PLS-00103:遇到符号“,”

Posted

技术标签:

【中文标题】PLS-00103:遇到符号“,”【英文标题】:PLS-00103: Encountered the symbol "," 【发布时间】:2013-03-21 10:36:56 【问题描述】:

此过程出现以下错误。

CREATE OR REPLACE PROCEDURE SAMPLE
IS
BEGIN
EXECUTE IMMEDIATE
    'CREATE TABLE COLUMN_NAMES AS (
     SELECT LISTAGG(COLUMN_NAME, ',') WITHIN GROUP (ORDER BY COLUMN_NAME) AS STUDENTS
     FROM   
         (SELECT DISTINCT COLUMN_NAME
          FROM BW_COLUMN_ROW_CELL_JOIN)
     )';
END;
/

给予:

PLS-00103: Encountered the symbol "," when expecting one of the following:     
* & = - + ; < / > at in is mod remainder not rem return    
returning <an exponent (**)> <> or != or ~= >= <= <> and or   
like like2 like4 likec between into using || multiset bulk    member submultiset 

谁能说说这有什么问题?

谢谢。

【问题讨论】:

@Dazzal。感谢您的回复...实际上,当我们要执行它们在运行时运行的 DDL 命令时,我认为应该在存储过程中使用 Execute Immediate。 【参考方案1】:

另一种方法(在 Oracle 10g 及更高版本中)是使用替代字符串文字表示法 - 这意味着您无需担心正确转义字符串中的所有单引号,例如q'my string's got embedded quotes':

CREATE OR REPLACE PROCEDURE SAMPLE
IS
BEGIN
EXECUTE IMMEDIATE q'[
     CREATE TABLE COLUMN_NAMES AS (
     SELECT LISTAGG(COLUMN_NAME, ',') WITHIN GROUP (ORDER BY COLUMN_NAME) AS STUDENTS
     FROM   
         (SELECT DISTINCT COLUMN_NAME
          FROM BW_COLUMN_ROW_CELL_JOIN)
     )]';
END;
/

【讨论】:

【参考方案2】:

我认为问题是单引号中有单引号。我目前无法对此进行测试,但我建议您尝试以下方法(注意内引号是双引号 '',它会转义它们:

CREATE OR REPLACE PROCEDURE SAMPLE 
IS
BEGIN 
    EXECUTE IMMEDIATE 'CREATE TABLE COLUMN_NAMES AS ( SELECT LISTAGG(COLUMN_NAME, '','') WITHIN GROUP (ORDER BY COLUMN_NAME) AS STUDENTS FROM (SELECT DISTINCT COLUMN_NAME FROM BW_COLUMN_ROW_CELL_JOIN) )'; 
END; 
/

我还会先尝试独立代码的create table 部分,以确保它在将其包装到 proc 之前有效。

【讨论】:

哇,它现在可以工作了...我刚刚在逗号处添加了双引号...完成了...非常感谢【参考方案3】:

不能在select statementExecute Immediate 中直接使用single quotes,需要使用CHR(39) 编码

CREATE OR REPLACE PROCEDURE SAMPLE
IS
BEGIN
   EXECUTE IMMEDIATE
     'CREATE TABLE COLUMN_NAMES AS (
             SELECT LISTAGG(COLUMN_NAME,'||chr(39)||','||chr(39)||') WITHIN GROUP (ORDER BY COLUMN_NAME) AS STUDENTS
             FROM   
            (SELECT DISTINCT COLUMN_NAME FROM BW_COLUMN_ROW_CELL_JOIN))';
END;

【讨论】:

execute immediate 将执行任何有效的字符串格式的 sql 语句,在这种情况下,如果您指定 execute immediate 'select 'error' from dual'; 之类的内容,它将给出运行时错误,即 PLS-00103: Encountered the symbol "ERROR" when expecting one of the following: * &amp; = - + ; &lt; / &gt; at in is mod remainder not rem return 所以要在execute immediate的SQL语句中使用单个代码,我们将使用chr(39)!如果我错了,请告诉我这个的替代方案 您可以使用双引号将一个“真正的”单引号放入结果字符串中。换句话说,EXECUTE IMMEDIATE 'SELECT ' || CHR(39) || 'quoted literal' || CHR(39) || ' FROM DUAL'EXECUTE IMMEDIATE 'SELECT ''quoted literal'' FROM DUAL' 是等价的,而 IMO 后者更容易阅读(和输入!)。 当我尝试像DECLARE V_STR VARCHAR(40); BEGIN EXECUTE IMMEDIATE 'SELECT LISTAGG(ename,",") within group (order by deptno) from emp' into v_str; dbms_output.put_line(v_str); END; 一样的事情但它给了我像ORA-00904: ",": invalid identifier 这样的错误消息,我正在使用ORACLE11g

以上是关于PLS-00103:遇到符号“,”的主要内容,如果未能解决你的问题,请参考以下文章

PLS-00103:遇到符号“COLUMNS”

PLS-00103:遇到符号“,”

错误(30,11):PLS-00103:遇到符号更新错误

获取 PLS-00103:在创建包时遇到符号“/”错误

PLS-00103:遇到符号

ORA-06550:第 13 行,第 4 列:PLS-00103:遇到“UPDATE” ORA-06550:第 15 行,第 3 列:PLS-00103:遇到符号“END”