问题描述
大家好,
要求: 我们需要将表名作为参数传递到过程中,并且还需要将该值与字符串连接起来,以使正确的表名在数据库中可用。
对于例如: 根据我的代码,如果我给出的参数为
执行过程 (10,'DE','CON','INC');
因此,通过这个,我试图在下面给出的过程中制作一个表格:
CON_SAP_TEMP_DE_CON_INC (在光标中选择表)
CON_SAP_UNLOAD_DE_CON_IN (插入时插入表)
现在请看我的代码:
如果您专注于插入,我已经注释掉了一行 “-插入到con_sap_unload_de_con_inc值V_CON_SAP_RESP(I);”
,如果我通过这一行,过程正在编译,并没有面临任何问题,因为我们在这个语句中传递了一个硬编码表,但我的要求是有表,我正在解决从V_TABLE开始。
您能在Insert语句中帮助我吗?
写插入的正确方法是什么。
要求: 我们需要将表名作为参数传递到过程中,并且还需要将该值与字符串连接起来,以使正确的表名在数据库中可用。
对于例如: 根据我的代码,如果我给出的参数为
执行过程 (10,'DE','CON','INC');
因此,通过这个,我试图在下面给出的过程中制作一个表格:
CON_SAP_TEMP_DE_CON_INC (在光标中选择表)
CON_SAP_UNLOAD_DE_CON_IN (插入时插入表)
现在请看我的代码:
create or replace PROCEDURE UNLOAD_CON_SAP_RESP_LOG
(PROC_ARRAY_SIZE IN PLS_INTEGER DEFAULT 10000,OPCO_UPCASE IN VARCHAR2,V_SEGMENT IN VARCHAR2,V_EVENT_NAME IN VARCHAR2)
AS
V_TABLE_NAME varchar2(100) := OPCO_UPCASE||'_'||V_SEGMENT||'_'||V_EVENT_NAME;
V_TABLE_NAME_TEST varchar2(100) := 'CON_SAP_UNLOAD'||'_'||V_TABLE_NAME;
V_TABLE_NAME_TEST_TEMP varchar2(100) := 'CON_SAP_TEMP'||'_'||V_TABLE_NAME;
sql_stmt_t_select VARCHAR2(32767);
sql_stmt_t_insert VARCHAR2(32767);
type rc is ref cursor;
CON_SAP_CUR rc;
TYPE CON_SAP_RESP IS TABLE OF CONTRACT_SAP_RESPONSE_LOG%ROWTYPE;
V_CON_SAP_RESP CON_SAP_RESP;
BEGIN
sql_stmt_t_select := 'SELECT * FROM CON_SAP_TEMP WHERE CONTRACT_ID IN
(SELECT CONTRACT_ID FROM '||V_TABLE_NAME_TEST_TEMP||')';
sql_stmt_t_insert := 'INSERT INTO '||V_TABLE_NAME_TEST||' VALUES V_CON_SAP_RESP(I)';
DBMS_OUTPUT.PUT_LINE(sql_stmt_t_select);
DBMS_OUTPUT.PUT_LINE(sql_stmt_t_insert);
DBMS_OUTPUT.PUT_LINE('PROCEDURE STARTS' || ' ' || TO_CHAR(SYSDATE,'DD-MON-YY HH24:MI:SS'));
OPEN CON_SAP_CUR for sql_stmt_t_select;
LOOP
FETCH CON_SAP_CUR BULK COLLECT INTO V_CON_SAP_RESP LIMIT PROC_ARRAY_SIZE;
FORALL I IN 1..V_CON_SAP_RESP.COUNT
sql_stmt_t_insert;
--INSERT INTO con_sap_unload_de_con_inc VALUES V_CON_SAP_RESP(I);
EXIT WHEN CON_SAP_CUR%NOTFOUND;
END LOOP;
CLOSE CON_SAP_CUR;
DBMS_OUTPUT.PUT_LINE('PROCEDURE ENDS' || ' ' || TO_CHAR(SYSDATE,'DD-MON-YY HH24:MI:SS'));
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN OTHERS THEN
--Consider logging the error and then re-raise
RAISE;
END UNLOAD_CON_SAP_RESP_LOG;
------------------------------------------ 如果您专注于插入,我已经注释掉了一行 “-插入到con_sap_unload_de_con_inc值V_CON_SAP_RESP(I);”
,如果我通过这一行,过程正在编译,并没有面临任何问题,因为我们在这个语句中传递了一个硬编码表,但我的要求是有表,我正在解决从V_TABLE开始。
您能在Insert语句中帮助我吗?
写插入的正确方法是什么。
专家解答
您没有指定要插入的值是什么!你需要绑定到我
但是你应该做的是放弃循环。从选择中使其成为直线插入:
另外: 你真的需要动态SQL吗?静态SQL要安全得多。
如果你真的必须使用动态SQL,那么确保你用dbms_assert净化用户输入:
https://oracle-base.com/articles/10g/dbms_assert_10gR2
否则你会让自己暴露在SQL注入攻击中!
但是你应该做的是放弃循环。从选择中使其成为直线插入:
sql_stmt_t_select := 'INSERT INTO '||V_TABLE_NAME_TEST||' (cols)
SELECT cols FROM CON_SAP_TEMP WHERE CONTRACT_ID IN
(SELECT CONTRACT_ID FROM '||V_TABLE_NAME_TEST_TEMP||')'; 另外: 你真的需要动态SQL吗?静态SQL要安全得多。
如果你真的必须使用动态SQL,那么确保你用dbms_assert净化用户输入:
https://oracle-base.com/articles/10g/dbms_assert_10gR2
否则你会让自己暴露在SQL注入攻击中!
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




