【问题标题】:How to use dynamic sql in pl/sql?如何在pl/sql中使用动态sql?
【发布时间】:2021-06-25 06:54:29
【问题描述】:

我有以下 pl/sql 过程作为示例(我的过程要大得多,但我的问题是关于动态 sql)。我的问题是如何在 SQL_STMT 中使用变量 V_DATE:

CREATE OR REPLACE PROCEDURE TEST (DATE_A IN DATE) IS    
   V_DATE DATE;    
   SQL_STMT VARCHAR2(4000);    
BEGIN     
   V_DATE = DATE_A;
   SQL_STMT = 'CREATE TABLE TABLE_1 AS 
               SELECT * 
                 FROM TABLE_2 A 
                WHERE A.DATE_FROM = V_DATE';
    
   EXECUTE IMMEDIATE SQL_STMT;
   COMMIT;        
END TEST;
/

【问题讨论】:

    标签: sql oracle plsql dynamic-sql


    【解决方案1】:

    您需要连接该值。 (通常绑定变量是个好主意,但它们不能与 DDL 一起使用。)

    create or replace procedure test
        ( date_a in date )
    as
        sql_stmt varchar2(4000);
    begin
        sql_stmt :=
            'create table table_1 as select * from table_2 a '||
            'where a.date_from = date '''||to_char(date_a,'YYYY-MM-DD')||'''';
    
        dbms_output.put_line(sql_stmt);
        execute immediate sql_stmt;
    end test;
    

    生成的语句将类似于:

    create table table_1 as select * from table_2 a where a.date_from = date '2021-03-27'
    

    请注意,这只会工作一次,因为之后表已经存在,所以create table 语句将失败,但这只是一个演示语法的示例。

    【讨论】:

      【解决方案2】:

      虽然连接是一种选择,但由于 SQL 注入(尽管可能不会在此处与 DATE 一起使用)和您将要体验的硬解析,我可能会改为探索以下选项。在这种情况下,您将生成更多撤消操作,但您正在执行的操作可能是可以接受的。您还可以添加APPENDNOLOGGING 提示,看看是否有帮助。这些提示有一些很好的比较here

      DROP TABLE dba_objects_date;
      
      CREATE OR REPLACE PROCEDURE date_test(date_a IN DATE) AS
        sql_stmt VARCHAR2(4000);
      BEGIN
        sql_stmt := 'create table dba_objects_date as select * from dba_objects a ' ||
                    'where 0 = 1';
        EXECUTE IMMEDIATE sql_stmt;
      
        sql_stmt := 'insert into dba_objects_date select * from dba_objects a ' ||
                    'where a.created >= :date_from';
      
        EXECUTE IMMEDIATE sql_stmt
          USING date_a;
      END date_test;
      /
      
      BEGIN
        date_test(SYSDATE - 14);
      END;
      /
      
      SELECT COUNT(*)
        FROM dba_objects_date;
      -- 821
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-31
        • 1970-01-01
        • 2018-09-18
        • 1970-01-01
        • 1970-01-01
        • 2016-07-29
        • 2012-04-03
        • 1970-01-01
        相关资源
        最近更新 更多