在 DML 过程中使用立即执行并在参数中传递字符值
Use execute immediate in procedure for DML and passing character value in parameter
我有一个删除过程,它使用 table 名称和一些值来从 table 中删除记录,因此我创建了一个立即执行的过程,它通过采用参数并删除。
但是,每当我在参数中传递 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.
如何正确传递这个值?请建议。
您在连接过程中丢失了 N1 周围的引号
您可以通过在 前后添加引号来修复,例如。
dlt_query := 'delete from '||P_TBL_NAME||' where system='||P_SYS||
' And batch_id='||''''||P_B_ID|| '''' ||
' And cobdate='||P_C_DATE;
- 首先,为什么
DELETE
需要PL/SQL
。你可以用简单的 SQL
.
- 为什么
P_C_DATE
是NUMBER
,cobdate
COLUMN是什么数据类型。日期应始终为 DATE
。如果列数据类型是DATE
,那么你会运行陷入更多的错误。始终注意声明正确的数据类型。
对于dynamic SQL
,在直接执行之前,最好使用DBMS_OUTPUT
查看查询是否正确形成。我还建议使用 quoting string literal technique
使它更容易。
DBMS_OUTPUT.PUT_LINE(dlt_query);
查询的问题是您缺少 VARCHAR2
类型周围的 single-quotation
标记。
修改查询为-
dlt_query := 'delete from '||P_TBL_NAME||' where system='||P_SYS||
' And batch_id='||''''||P_B_ID|| '''' ||
' And cobdate='||P_C_DATE;
如果必须使用 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;
/
我有一个删除过程,它使用 table 名称和一些值来从 table 中删除记录,因此我创建了一个立即执行的过程,它通过采用参数并删除。
但是,每当我在参数中传递 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.
如何正确传递这个值?请建议。
您在连接过程中丢失了 N1 周围的引号
您可以通过在 前后添加引号来修复,例如。
dlt_query := 'delete from '||P_TBL_NAME||' where system='||P_SYS||
' And batch_id='||''''||P_B_ID|| '''' ||
' And cobdate='||P_C_DATE;
- 首先,为什么
DELETE
需要PL/SQL
。你可以用简单的SQL
. - 为什么
P_C_DATE
是NUMBER
,cobdate
COLUMN是什么数据类型。日期应始终为DATE
。如果列数据类型是DATE
,那么你会运行陷入更多的错误。始终注意声明正确的数据类型。
对于dynamic SQL
,在直接执行之前,最好使用DBMS_OUTPUT
查看查询是否正确形成。我还建议使用 quoting string literal technique
使它更容易。
DBMS_OUTPUT.PUT_LINE(dlt_query);
查询的问题是您缺少 VARCHAR2
类型周围的 single-quotation
标记。
修改查询为-
dlt_query := 'delete from '||P_TBL_NAME||' where system='||P_SYS||
' And batch_id='||''''||P_B_ID|| '''' ||
' And cobdate='||P_C_DATE;
如果必须使用 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;
/