如何在 EXECUTE IMMEDIATE 中使用动态 where 子句

Posted

技术标签:

【中文标题】如何在 EXECUTE IMMEDIATE 中使用动态 where 子句【英文标题】:How to use dynamic where clause in EXECUTE IMMEDIATE 【发布时间】:2018-08-16 06:07:41 【问题描述】:

我有一个包含插入、选择、where 子句、动态 where 子句、group by 子句列的表。

使用过程我需要执行 insert into 语句并使用动态 where 子句。

我尝试了以下一个,但是它给了我一个错误的缺失表达式。

create or replace PROCEDURE dynamicWhereClause(Datee IN DATE,processId IN NUMBER)
IS 

 processName VARCHAR2(100);
 tablePrefix CONFIG_DETAILS.SOURCE_TABLE%Type;
 sourceTableType CONFIG_DETAILS.SOURCE_TABLE_TYPE%Type;
 insertClause CONFIG_DETAILS.INSERT_CLAUSE%Type;
 selectClause CONFIG_DETAILS.SELECT_CLAUSE%Type;
 whereClause CONFIG_DETAILS.WHERE_CLAUSE%Type;
 onUpdateClause CONFIG_DETAILS.ON_UPDATE_CLAUSE%Type;
 groupByClause CONFIG_DETAILS.GROUP_BY_CLAUSE%Type;
 orderByClause CONFIG_DETAILS.ORDER_BY_CLAUSE%Type;
 isDynamicWhereClause CONFIG_DETAILS.IS_DYNAMIC_WHERE_CLAUSE%Type;
 tableName VARCHAR2(50);
 Process_Date DATE;
 processQuery VARCHAR2(6000 BYTE);


 CURSOR Process_Report IS 
    select NAME,SOURCE_TABLE,SOURCE_TABLE_TYPE,INSERT_CLAUSE,SELECT_CLAUSE,WHERE_CLAUSE,ON_UPDATE_CLAUSE,GROUP_BY_CLAUSE,ORDER_BY_CLAUSE,IS_DYNAMIC_WHERE_CLAUSE FROM 
    CONFIG_DETAILS where ID=processId;

BEGIN

    OPEN Process_Report;
    LOOP

        FETCH Process_Report INTO processName,tablePrefix,sourceTableType,insertClause,selectClause,whereClause,onUpdateClause,groupByClause,orderByClause,isDynamicWhereClause;
            EXIT when Process_Report%NOTFOUND;

        tableName := getSourceTableName(tablePrefix,sourceTableType,processDate);
        Process_Date := processDate;

        processQuery := insertClause || selectClause ||' from ' || tableName ||' ' ||
        nvl(whereClause,'') ||''||nvl(groupByClause,'') ||''||nvl(orderByClause,'') ||''||nvl(onUpdateClause,'');

        dbms_output.put_line(processQuery);

        IF isDynamicWhereClause = 'Y' 
        THEN
            dbms_output.put_line(processQuery);
            EXECUTE IMMEDIATE processQuery USING Process_Date;  

        ELSE

            EXECUTE IMMEDIATE  processQuery;

        END IF;

    END LOOP;
    CLOSE Process_Report;

END;

在执行过程时,它给了我以下错误。

Error report -
ORA-00936: missing expression
ORA-06512: at "Mytest.dynamicWhereClause", line 44
ORA-06512: at line 1
00936. 00000 -  "missing expression"

请进一步帮助我

谢谢

【问题讨论】:

你检查过dbms_output.put_line(processQuery); 产生了什么吗?不要EXECUTE IMMEDIATE 任何东西,除非你确定processQuery 没问题。 NVL(variable, '') 没意义,直接用variable吧。 ORDER BY 子句对于 INSERT 语句也是无用的。 我不确定我(或其他任何人)可以检查什么。显然,缺少日期值,但我不知道为什么。你没有连接它。为什么?您选择的 WHERE 子句中可能缺少它;我怎么知道? 字符串必须像insert into DETAIL(ID,DATEE,NAME) select ID,DATEE,NAME from CC_08 where DATEE= :dateValue 【参考方案1】:

您的问题不是 100% 清楚。你说在DATEE 为空之后,你是在 date 之后分配一个变量吗?下面是如何将执行立即数与变量一起使用的示例。注意绑定变量:i 在打印中是如何显示的。

set serveroutput on size 1000 
/
declare t number(4) :=10;
txt varchar2(100);
begin
txt :='INSERT INTO TAB (ID) values (:i)';
dbms_output.put_line(t || ' ' || txt);
execute immediate txt using T;
end;
/

PL/SQL procedure successfully completed

10 INSERT INTO TAB (ID) values (:i)

【讨论】:

以上是关于如何在 EXECUTE IMMEDIATE 中使用动态 where 子句的主要内容,如果未能解决你的问题,请参考以下文章

如何只使用一次 EXECUTE IMMEDIATE 创建 2 个表?

oracle中EXECUTE IMMEDIATE是啥意思?如何使用,请用自己理解的语言,通俗的解释出来,谢谢了各位!

通过 EXECUTE IMMEDIATE 从 select 语句中返回一个值

在 PL\SQL 块中使用 EXECUTE IMMEDIATE

在存储过程中对 DML 语句使用 EXECUTE IMMEDIATE

在 Oracle 中使用 Execute Immediate 将数据插入表中