2017-09-08 28 views
1

我需要與ORA-00905找出此問題的幫助:缺少關鍵字ORA-06512:在line 73COMMENT ON產生ORA-00905:缺少關鍵字通過EXECUTE IMMEDIATE

當它說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; 
+0

謝謝krokodilko糾正後。它看起來凌亂。 – JustinC

+0

嗨Krokodilko,謝謝你的跟進。是的,我有權訪問DBA_TAB_COLUMNS。這個想法讓我瘋狂。我現在可以完成一個複雜的Java程序,但我無法確定一個班輪問題。我還是PL/SQL的新手,但我必須做到這一點。我添加了一個自定義的錯誤信息,但它並沒有給我多大的幫助。我想,這個週末是評論主題,旁邊注意颶風或龍捲風。 – JustinC

+0

它通過SQLPLUS授予我自己的個人用戶名的權限後工作。當我創建用戶名時,我忘記提供訪問所有DML和表的所有權限。謝謝你Krokodilko。事實上,你提到它之後再看看它。課程學習是,它並不總是腳本,但也是許可。謝謝! – JustinC

回答

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' 
+0

非常感謝你的詳細描述,而不僅僅是指出線上的潛在缺陷。它會給我這個週末看點什麼。我現在就試試這個。 – JustinC

+0

在上面,我將光標所指的對象改爲 c_schema_name:= r.OWNER; c_table_name:= r.TABLE_NAME; c_column_name:= r.COLUMN_NAME; sql_stmt1:='COMMENT ON COLUMN「'|| c_schema_name ||'」。「|| || c_table_name ||'」。「|| c_column_name ||'IS」Comment here'''; 但是,我仍然得到相同的缺少關鍵錯誤信息。不過,謝謝你指出單引號和雙引號。 – JustinC

+0

這條線,SELECT'COMMENT ON COLUMN''|| OWNER ||'「。''|| TABLE_NAME ||'」。''|| COLUMN_NAME ||'''IS'''comment'從'dba_tab_columns'其中COLUMN_NAME ='SSAN'; 將列出具有'SSAN'的所有列如果我使用上面的結果集一次一個字面評論它將工作但它不起作用在pl/sql中,我仍然在調用 – JustinC