暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle PL/SQL过程问题 (在动态表上批量收集和插入)

askTom 2018-02-02
266

问题描述

大家好,

要求: 我们需要将表名作为参数传递到过程中,并且还需要将该值与字符串连接起来,以使正确的表名在数据库中可用。

对于例如: 根据我的代码,如果我给出的参数为

执行过程 (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_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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论