2010-03-24 175 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