2015-02-11 75 views
0

我正在使用Oracle 11g。 我有一個函數,我想用來插入到一個表中的行。 其中一個參數是表格%rowtype。這已經填充了大部分正確的數據。 其中一個參數是表示目標表名稱的varchar2。 我想更改類型表%rowtype變量的三列中的值,然後將其插入到由varchar2類型的輸入變量指定的表中。oracle用戶rowtype變量插入表使用立即執行

FUNCTION AddMP(vMP   IN MEASUREPOINT%ROWTYPE, 
        vNewPointNum IN MEASUREPOINT.POINTNUM%TYPE, 
       v_CalMtrName IN MEASUREPOINT.METERNAME%TYPE) RETURN VARCHAR2 IS 
     v_RetVal  VARCHAR2(50) := K_OKAY; 
     v_Status  VARCHAR2(50) := NULL; 
     v_AssetNum  MEASUREPOINT.ASSETNUM%TYPE; 
     v_SiteId  MEASUREPOINT.SITEID%TYPE; 
     v_OrgId  ASSETMETER.ORGID%TYPE; 
     v_ChangeDate ASSETMETER.CHANGEDATE%TYPE; 
     v_err_num  NUMBER; 
     v_err_msg  VARCHAR2(255); 
     v_err_string VARCHAR2(1000) := NULL; 
     v_insert_str VARCHAR2(2000) := NULL; 
     v_RowsAffected VARCHAR2(10) := NULL; 
     v_NewMP  MEASUREPOINT%ROWTYPE; 
    BEGIN 
     v_AssetNum := vMP.Assetnum; 
     v_SiteId  := vMP.Siteid; 
     v_ChangeDate := SYSDATE; 
     v_OrgId  := vMP.Orgid; 
     --Put new data into vMP 

     tempMP    := vMP; 
     tempMP.Pointnum  := vNewPointNum; 
     tempMP.Metername  := v_CalMtrName; 
     tempMP.Measurepointid := measurepointseq.nextval; 
     tempMP.Pointnum  := vNewPointNum; 

     /*  v_insert_str := ' insert \*+ ignore_row_on_dupkey_index(tab, tab_pk) *\into ' || 
          TABLE_MEASUREPOINT || ' values :insertRecord '; 
     */ 
      v_insert_str := ' insert /*+ ignore_row_on_dupkey_index(tab, tab_pk)  */into ' || 
          TABLE_MEASUREPOINT || ' values tempMP '; 

      EXECUTE IMMEDIATE v_insert_str; 
      /*INSERT INTO MEASUREPOINT_TEMP VALUES tempMP;*/ 

我收到各種錯誤,但我懷疑我實際上必須枚舉所有的目標列和它們的個別值。我真的不想這樣做,但在修復三個值之後使用輸入變量。 它甚至可以做到這一點? 謝謝在任何情況下 傑夫

+0

如果你告訴使用錯誤是什麼,不會有幫助嗎? – OldProgrammer 2015-02-11 22:16:52

回答

0

如果你知道表MEASUREPOINT的列名,你可以這樣做。假設列(COL1,COL2),那麼你的插入會:

v_insert_str := ' insert /*+ ignore_row_on_dupkey_index(tab, tab_pk)  */into ' || 
      TABLE_MEASUREPOINT || ' values ('||tempMP.col1||','||tempMP.col2||')'; 
+0

如果你打算使用這種方法,你應該真的使用'dbms_assert.enquote_literal'來爲連接的值添加引號。 – Allan 2015-02-11 22:53:43

0

要通過行類型變量到動態SQL,你應該使用綁定變量和using

v_insert_str := ' insert /*+ ignore_row_on_dupkey_index(tab, tab_pk)  */into ' || 
          TABLE_MEASUREPOINT || ' values :1 '; 

EXECUTE IMMEDIATE v_insert_str using tempMP; 

原因您的原始方法不起作用,即通過execute immediate運行的動態SQL運行在它自己的作用域中,而不在過程或塊的範圍內。爲了使用execute immediate中的局部變量,您必須使用綁定變量(如我的答案中)傳遞它們,或者連接它們(如在@Aramillo的答案中)。一般來說,如果可以的話,最好綁定一下。

+0

這不會引發「表達式必須是SQL類型」錯誤嗎?我有一個非常類似的問題,我明白了。 – godzsa 2016-07-26 10:17:07