2010-03-24 178 views
1

我有这样的功能:故障排除PG功能

CREATE OR REPLACE FUNCTION CREATE_AIRSPACE_AVAILABILITY_RECORD 
(cur_user VARCHAR, start_time VARCHAR, start_date VARCHAR, end_time VARCHAR, end_date VARCHAR, airspace_name VARCHAR) 

    RETURNS VOID AS ' 
    DECLARE 
c_user ALIAS for $1; 
BEGIN 
    IF start_time IS NULL OR 
     start_date IS NULL OR 
     end_time IS NULL OR 
     end_date IS NULL THEN 
     INSERT INTO c_user.AIRSPACE_AVAILABILITY 
      (ASP_AIRSPACE_NM, ASA_TIME_ID, ASA_START_DT, ASA_END_DT) 
     SELECT airspace_name, 
       1, 
       ABP.ABP_START_DT, 
       ABP.ABP_STOP_DT 
      FROM ABP 
      WHERE EXISTS 
      (SELECT ASP.ASP_AIRSPACE_NM 
       FROM AIRSPACE ASP 
       WHERE ASP.ASP_AIRSPACE_NM = airspace_name); 
    ELSIF start_time IS NOT NULL AND 
     start_date IS NOT NULL AND 
     end_time IS NOT NULL AND 
     end_date IS NOT NULL THEN 
     INSERT INTO c_user.AIRSPACE_AVAILABILITY 
      (ASP_AIRSPACE_NM, ASA_TIME_ID, ASA_START_DT, ASA_END_DT) 
     SELECT airspace_name, 
       1, 
       TO_DATE(start_date||start_time,''YYMMDDHH24MI''), 
       TO_DATE(end_date||end_time,''YYMMDDHH24MI'') 
      FROM DUAL 
      WHERE EXISTS 
      (SELECT ASP.ASP_AIRSPACE_NM 
       FROM c_user.AIRSPACE ASP 
       WHERE ASP.ASP_AIRSPACE_NM = airspace_name); 
    END IF; 

END ; 
    ' LANGUAGE plpgsql; 

我尝试调用它像这样:

select * from CREATE_AIRSPACE_AVAILABILITY_RECORD('user1','','','','',''); 

,我得到这个错误:

ERROR: schema "c_user" does not exist 
SQL state: 3F000 
Context: SQL statement "INSERT INTO c_user.AIRSPACE_AVAILABILITY (ASP_AIRSPACE_NM, ASA_TIME_ID, ASA_START_DT, ASA_END_DT) SELECT $1 , 1, TO_DATE($2 || $3 ,'YYMMDDHH24MI'), TO_DATE($4 || $5 ,'YYMMDDHH24MI') FROM DUAL WHERE EXISTS (SELECT ASP.ASP_AIRSPACE_NM FROM c_user.AIRSPACE ASP WHERE ASP.ASP_AIRSPACE_NM = $1)" 
PL/pgSQL function "create_airspace_availability_record" line 23 at SQL statement 

为什么不c_user被我的参数(user1)取代?

回答

2

当你写这样的事:

INSERT INTO c_user.AIRSPACE_AVAILABILITY 

数据库假定“c_user”是一个命名空间,而不是一个变量。如果要在此类查询中使用c_user变量的值,则应使用execute语句:

execute 'INSERT INTO ' || c_user || '.AIRSPACE_AVAILABILITY'; 
0

Why isn't c_user being replaced with my param (user1)?

因为对象名称(元数据)不能用变量(数据)替代。

选择的元数据动态通常不是最好的设计,但如果你需要忍受它,你应该做沿着

EXECUTE 'INSERT INTO ' || c_user || '.AIRSPACE_AVAILABILITY ' … 

,而不是线的东西。

请参阅here了解更多详情。

+0

如何获得此功能? – systemoutprintln 2010-03-24 17:53:51

+0

请不要忘记使用quote_ident()来避免函数中的SQL注入:quote_ident(c_user)。 EXECUTE很棒,但你必须确保它! – 2010-03-24 18:02:52