ORACLE資料庫建立動態表
阿新 • • 發佈:2018-12-12
最近公司一個專案程式碼裡的定時任務無法執行,查驗程式碼良久,奈何程式碼過於老舊,開發人員換了一茬又一茬,現在都無法理清,故無奈只好到資料庫裡重新寫存過,配置定時任務。
在寫存過時,由於檢測及安全效能要求,需要備份資料,設計是每次呼叫存過時就建立一張新表記錄歷史資料,開始時是準備直接一條語句搞定:
BEGIN execute immediate 'create table tmp_a_'||to_char(sysdate, 'yyyymmdd')||' as select * from a'; END;
但是執行時報錯,找了良久未發現問題所在,自己懷疑是拼接表名時字串的問題,所以我調整了一下上面的語句:
is tableName varchar2(30); BEGIN tableName :='tmp_a_'||to_char(sysdate,'yyyymmdd' ); execute immediate 'create table ' || tableName ||' as select * from a'; END;
這樣就可以了,能夠執行成功,問題也完美解決!
PS:在存過裡執行create語句時,有時會報“許可權不足!”,這是因為Oracle8i及其後的版本,Oracle引入呼叫者(invoker)許可權,使得物件可以以呼叫者身份和許可權執行。遇到儲存過程中帶有Create Table的這種情況,通常解決方法是進行顯式的系統許可權: grant create table to username;但是,此方法太笨,因為有可能執行一個儲存過程,需要很多不同許可權(oracle對許可權劃分粒度越來越細)。最好的方法是,利用 oracle 提供的方法,在建立儲存過程時,加入 Authid Current_User 條件進行許可權分配。
create or replace procedure p_test Authid Current_User is begin execute immediate 'create table tmp(id number(1))'; end p_test;
分享一下,希望能幫到和我一樣遇到此類問題的道友們!