在DML的过程中使用execute immediate并在参数中传递字符值

时间:2015-01-05 11:11:25

标签: oracle plsql oracle11g plsqldeveloper

我有一个删除程序,它使用表名和一些值来删除该表中的记录,因此我创建了一个带有execute immediate的程序,它通过参数和删除形成删除查询。

但是当我在参数中传递char值时,它会收到错误:

invalid identifier 

作为查询形成的字符值的单引号。请告诉我如何在过程中传递char值以正确形成字符串。

以下是程序:

CREATE OR replace PROCEDURE Prd_delete(p_tbl_name IN VARCHAR2,
                                       p_sys      VARCHAR2,
                                       p_b_id     VARCHAR2,
                                       p_c_date   NUMBER)
IS
  dlt_query VARCHAR2(200);
BEGIN
    dlt_query := 'delete from '
                 ||p_tbl_name
                 ||' where system='
                 ||p_sys
                 || ' And batch_id='
                 ||p_b_id
                 || ' And cobdate='
                 ||p_c_date;

    --dbms_output.put_line(dlt_query);
    EXECUTE IMMEDIATE dlt_query;
END;

/ 

以下是运行命令:

exec prd_delete ('TBL_HIST_DATA','M','N1',20141205);

以下是错误:

ORA-00904:"N1" invalid identifier.

如何正确传递此值?请建议。

3 个答案:

答案 0 :(得分:2)

  • 首先,为什么PL/SQL需要DELETE。你可以用普通SQL
  • 来做
  • 为什么P_C_DATENUMBER,什么数据类型为cobdate COLUMN。日期应始终为DATE。如果列数据类型为DATE,则会遇到更多错误。始终注意声明正确的数据类型。

使用dynamic SQL,在直接执行之前,最好使用DBMS_OUTPUT查看查询是否正确形成。我还建议使用quoting string literal technique使其更容易。

DBMS_OUTPUT.PUT_LINE(dlt_query);

查询的问题是您遗漏了single-quotation类型周围的VARCHAR2标记。

将查询修改为 -

dlt_query := 'delete from '||P_TBL_NAME||' where system='||P_SYS||
             ' And batch_id='||''''||P_B_ID|| '''' ||
             ' And cobdate='||P_C_DATE;

答案 1 :(得分:0)

在连接期间你正在丢失N1周围的引号

你可以通过在之前和之后添加引号来修复,例如。

dlt_query := 'delete from '||P_TBL_NAME||' where system='||P_SYS||
' And batch_id='||''''||P_B_ID|| '''' ||
' And cobdate='||P_C_DATE;

答案 2 :(得分:0)

如果必须使用EXECUTE IMMEDIATE语句,则应使用绑定变量:

    CREATE OR REPLACE PROCEDURE prd_delete (P_TBL_NAME IN VARCHAR2,
                                                P_SYS VARCHAR2,
                                                P_B_ID VARCHAR2,
                                                P_C_DATE NUMBER) IS
          dlt_query   VARCHAR2 (200);
    BEGIN
      dlt_query := 'delete from ' || P_TBL_NAME || ' where system=:1 and batch_id=:2 and cobdate=:3';
      BEGIN
        EXECUTE IMMEDIATE dlt_query USING P_SYS, P_B_ID, P_C_DATE;
      EXCEPTION
        WHEN OTHERS THEN
          -- catch exception !!
      END;
    END;
   /