COMMENT ON通过EXECUTE IMMEDIATE生成ORA-00905:缺少关键字

时间:2017-09-08 17:07:59

标签: sql oracle plsql

我需要帮助找出ORA-00905的问题:缺少关键字ORA-06512:第73行

当它表示第73行时,它实际上引用了第56行的sql语句本身。但是,我使用的是同一个脚本,它使用了一个完美的工作表。  通过更改架构,表和列名称,我不断收到此错误。我正在尝试几个版本,并使用fetch进入游标。  它一直说sql语句缺少关键字,但它正在使用同一行的另一个脚本。我希望有人能在这里帮助我。这是我第一次在这个论坛发帖,我希望有一天我能为这个伟大的社区做出贡献。提前谢谢!

DECLARE
--CREATE OR REPLACE PROCEDURE setcomment
--IS

         CURSOR cur IS 
           SELECT COLUMN_NAME, TABLE_NAME, OWNER 
           FROM DBA_TAB_COLUMNS 
           WHERE COLUMN_NAME = 'SSAN' 
           ORDER BY OWNER ASC, TABLE_NAME ASC, COLUMN_NAME ASC;

         c_schema_name           DBA_TAB_COLUMNS.OWNER%type; 
         c_table_name                DBA_TAB_COLUMNS.TABLE_NAME%type;
         c_column_name            DBA_TAB_COLUMNS.COLUMN_NAME%type;


        --This is a variable name to concatenate column names from <c_schema_name>.<c_table_name>.<c_column_name>
        col_name VARCHAR(250) ;                    
        --This is a variable to hold SQL statement and the message to be commented 
        sql_stmt1 VARCHAR(2000) ;
        msg VARCHAR(250)    := ' '' Comment going here '' '; 

 BEGIN

     --Looping r cursor through cur cursor. Retrieving a row of record at a time
     FOR  r in cur LOOP


         c_schema_name := r.owner;
         c_table_name := r.table_name;
         c_column_name := r.column_name;                    

         --Concatenate all the column names into a single column name. 
          col_name := c_schema_name||'.'||c_table_name||'.'||c_column_name;

         sql_stmt1  :=   'COMMENT ON COLUMN '|| col_name ||' IS ''Comment going here '' ' ;

         -- sql_stmt1  :=   'COMMENT ON COLUMN '|| col_name ||' IS '||msg;

           EXECUTE IMMEDIATE sql_stmt1;
          --EXECUTE IMMEDIATE 'COMMENT ON COLUMN '|| c_schema_name||'.'||c_table_name||'.'||c_column_name || ' IS '' Comment going here '' ' ;

           DBMS_OUTPUT.PUT_LINE ('COMMENT ON ' || col_name   || ' procedure completed....');


    END LOOP;


 END;
  / 

如果仍然找不到错误来源,则创建一个日志表,运行以下代码,并显示(选择)表中的所有错误条目
然后尝试手动运行命令 您是否具有相应的权限来评论其他模式中的表?它可以从DBA_TAB_COLS中获得SELECT的权限,但这并不意味着它可以修改其他模式/表。

CREATE TABLE log_errors( error_msg varchar2(4000));

DECLARE
         CURSOR cur IS 
           SELECT COLUMN_NAME, TABLE_NAME, OWNER 
           FROM DBA_TAB_COLUMNS 
           WHERE COLUMN_NAME = 'SSAN' 
           ORDER BY OWNER ASC, TABLE_NAME ASC, COLUMN_NAME ASC;

        col_name VARCHAR(250) ;                    
        sql_stmt1 VARCHAR(2000) ;
        msg VARCHAR(250)    := 'Comment going here'; 

 BEGIN
     FOR  r in cur LOOP
          col_name := '"'|| r.OWNER ||'"."'||r.TABLE_NAME||'"."'||r.COLUMN_NAME||'"';
          sql_stmt1 := 'COMMENT ON COLUMN ' || col_name || ' IS ''' || msg || '''';
          BEGIN
            EXECUTE IMMEDIATE sql_stmt1;
          EXCEPTION 
            WHEN OTHERS THEN
                INSERT INTO log_errors( error_msg ) VALUES ( sql_stmt1 );
          END;
    END LOOP;
 END;
  / 

  SELECT * FROM log_errors;

1 个答案:

答案 0 :(得分:2)

除了Mathguy的回答 - 如果使用quoted identifiers

创建了任何表,您的脚本将会失败
  

数据库对象命名规则

     

每个数据库对象都有一个名称。在SQL语句中,您表示   带引号标识符或非引用标识符的对象的名称   标识符

     
      
  • 带引号的标识符以双引号(“)开头和结尾。   如果使用带引号的标识符命名模式对象,则必须使用   每次引用该对象时都使用双引号。

  •   
  • 未加引号的标识符不会被任何标点符号包围。

  •   
     

您可以使用带引号或非带引号的标识符来命名   数据库对象。但是,数据库名称,全局数据库名称和   数据库链接名称始终不区分大小写,并存储为   大写。如果你指定这样的名称作为带引号的标识符,那么   引号被默默地忽略了。

简单实用的例子 - 第一个表的名称是非引用标识符,第二个表的名称是引用标识符:

CREATE TABLE table_one (
  SSAN int
);

CREATE TABLE "TaBle @#% TWO" (
  SSAN int
);

SELECT 'COMMENT ON COLUMN ' || OWNER || '.' || TABLE_NAME || '.' || COLUMN_NAME || ' IS ''My superb comment''' 
       As my_comment_command
FROM ALL_TAB_COLUMNS 
WHERE COLUMN_NAME = 'SSAN' ;

MY_COMMENT_COMMAND                                                                                                                                                                                                                                                                                                                                                                                                                         
----------------------------------------------------------------
COMMENT ON COLUMN SCOTT.TABLE_ONE.SSAN IS 'My superb comment'
COMMENT ON COLUMN SCOTT.TaBle @#% TWO.SSAN IS 'My superb comment'

很明显,第二个命令会失败。

但是如果你在脚本中使用引号,那么一切都会正常工作:

SELECT 'COMMENT ON COLUMN "' || OWNER || '"."' || TABLE_NAME || '"."' || COLUMN_NAME || '" IS ''My superb comment''' 
       As my_comment_command
FROM ALL_TAB_COLUMNS 
WHERE COLUMN_NAME = 'SSAN' ;

MY_COMMENT_COMMAND                                                                                                                                                                                                                                                                                                                                                                                                                               
----------------------------------------------------------------------
COMMENT ON COLUMN "SCOTT"."TABLE_ONE"."SSAN" IS 'My superb comment'
COMMENT ON COLUMN "SCOTT"."TaBle @#% TWO"."SSAN" IS 'My superb comment'