【问题标题】:PLSQL Missing ExpressionPLSQL 缺少表达式
【发布时间】:2018-08-26 09:53:58
【问题描述】:

谁能告诉我为什么我在运行这个脚本时会收到以下错误:

DECLARE
    some_string VARCHAR2(30)    := 'Some String';
    V_CNT   NUMBER := null; 
    v_msg varchar2(4000) := ''; 
BEGIN
    v_msg := 'SELECT COUNT(*) INTO ' || V_CNT || ' FROM table_name WHERE column_name = ' || upper(some_string);
    execute immediate v_msg; 

    DBMS_OUTPUT.PUT_LINE(V_CNT);
END;
/

我得到的错误是:

ORA-00936: missing expression

【问题讨论】:

标签: sql oracle plsql dynamic-sql


【解决方案1】:

看看这个例子(基于实际的 Scott 的表和值,而不是 generic 的)。基本上,EXECUTE IMMEDIATE 应该看起来不同 - 同时使用 USINGINTO。此外,无需声明变量null(或空字符串)。

SQL> set serveroutput on;
SQL> declare
  2      some_string varchar2(30) := 'MANAGER';
  3      v_cnt       number;
  4      v_msg       varchar2(4000);
  5  begin
  6    v_msg := 'SELECT COUNT(*) FROM emp WHERE job = :a';
  7
  8    execute immediate v_msg into v_cnt using some_string;
  9
 10    dbms_output.put_line(v_cnt);
 11  end;
 12  /
3

PL/SQL procedure successfully completed.

SQL>

【讨论】:

  • 这很好用。但是,如果我想将整个 SELECT 语句显示为调试消息怎么办?含义,包括第 6 行和第 8 行作为字符串。
  • 作为第 7 行,包括 dbms_output.put_Line(replace(v_msg, ':a', some_string));
【解决方案2】:

这个问题很少:

  1. V_CNTnull 并且您没有为其分配任何值,因此 qwith 它的部分变为:

    SELECT COUNT(*) INTO FROM
    

我认为这会导致错误。

  1. where 子句中没有撇号,这也可能导致更多错误。你应该使用:

    'SELECT COUNT(*) INTO ' || V_CNT || ' FROM table_name WHERE column_name = ''' || upper(some_string) || '''';
    

【讨论】:

    【解决方案3】:

    如下使用

    DECLARE
     some_string VARCHAR2(30)    := 'Some String';
     V_CNT   NUMBER := null; 
     v_msg varchar2(4000) := ''; 
    BEGIN
    
         v_msg := 'SELECT COUNT(*)  
                     FROM table_name 
                    WHERE column_name = ''' || upper(some_string)||''''; 
                 -- more quotes needed, I'm printing result of the decent v_msg also.
    
         execute immediate v_msg into v_cnt; -- you should shift "into v_cnt" here.
    
         DBMS_OUTPUT.PUT_LINE(v_msg);
         ---> SELECT COUNT(*) FROM table_name WHERE column_name = 'Some String'
         DBMS_OUTPUT.PUT_LINE(v_cnt);    
    END;
    

    附注您可以获得上述结果,但我也建议您使用绑定变量(出于安全和性能原因),就像在 @Littlefoot 的情况下一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多