2015-02-11 67 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