【问题标题】:oracle user rowtype variable to insert into table using execute immediate使用立即执行将 oracle 用户行类型变量插入表中
【发布时间】:2015-04-12 11:23:10
【问题描述】:

我正在使用 Oracle 11g。 我有一个函数,我想用它来将一行插入到表中。 其中一个参数是 table%rowtype。这已经填充了大多数正确的数据。 其中一个参数是表示目标表名称的 varchar2。 我想改变table%rowtype类型变量中三列的值,然后将其插入到varchar2类型的输入变量命名的表中。

  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;*/

我遇到了各种错误,但我怀疑我实际上必须枚举所有目标列及其各自的值。我真的不想这样做,而是在修复三个值后使用输入变量。 甚至有可能做到这一点吗? 无论如何谢谢 杰夫

【问题讨论】:

  • 如果你告诉 use 错误是什么会很有帮助,不是吗?

标签: oracle plsql rowtype


【解决方案1】:

如果您知道表MEASUREPOINT 的列名,您可以这样做。假设列是 (col1,col2),那么您的插入将是:

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

【讨论】:

  • 如果你打算使用这种方法,你真的应该使用dbms_assert.enquote_literal 为连接的值添加引号。
【解决方案2】:

要将rowtype变量传递给动态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 的回答)。一般来说,如果可以的话,最好绑定。

【讨论】:

  • 这不会引发“表达式必须是 SQL 类型”的错误吗?我有一个非常相似的问题,我明白了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多