2015-09-01 105 views
1

我想在Netteza SQL的For循環中修改表格。我知道Netteza在存儲過程中不允許alter table。正如所引用的:存儲過程替代Netteza SQL ALTER TABLE?

「這些SQL命令在Netezza存儲過程的主體中也是被禁止的。」

有沒有其他方法可以做到這一點?我是Netteza的初學者。我也不知道我的循環格式是否正確?

CREATE OR REPLACE PROCEDURE "SP_Automate_Table"() 
RETURNS INTEGER 
LANGUAGE NZPLSQL AS 
BEGIN_PROC 
DECLARE 

vSQL1 varchar(30000) ; 

BEGIN 

FOR i in 2011..2014 
LOOP 
For j in 1..12 
Loop  
    call "SP_Count"(i, j); 
    vSQL1:='alter table X add columnX INT'; 
    .... 
     ... 
     .. 
    EXECUTE immediate vSQL1; 

    END LOOP; 
END LOOP; 

END; 
END_PROC; 

回答

1

從v7.1開始,您可以在存儲過程中聲明AUTOCOMMIT ON塊,並且在此塊中可以調用否則在存儲過程中禁止的語句。

CREATE OR REPLACE PROCEDURE ADMIN.SP_ALTER_LOOP(INTEGER, INTEGER) 
RETURNS INTEGER 
LANGUAGE NZPLSQL AS 
BEGIN_PROC 
DECLARE 
    pStartVal ALIAS FOR $1; 
    pCount ALIAS FOR $2;  
    vSQL varchar(30000); 

BEGIN 

BEGIN AUTOCOMMIT ON 
for i in 1 .. pCount LOOP 
    vSQL := 'ALTER TABLE CLAIM_' || pStartVal + i-1 || ' ADD COLUMN (COL2 BIGINT);'; 
    EXECUTE IMMEDIATE vSQL; 
END LOOP; 

END; 
END; 
END_PROC; 

在v7.1之前,我不知道用存儲過程改變表結構的方法。

請注意,在ALTER TABLE的一般情況下(不管是像這樣的腳本還是手動腳本),確保在ALTER操作之後執行每個修改表的修飾。

GROOM TABLE tablename VERSIONS; 
+0

太棒了,我有v7.2。 –

+1

哦,很好。這給了我一個很好的理由擺脫7.0.4。 –

0

你的循環語句是syntactically correct,但沒有辦法從發佈之內nzplsql ALTER語句。

我會建議做一個bash腳本作爲替代,反覆調用nzsql

for i in $(seq 2011 2014); do 
    for j in $(seq 1 12); do 
    nzsql -c "call \"SP_Count\"($i, $j);" 
    nzsql -c "alter table X add columnX INT;" 
    done 
done 

我真的不能想象一個用情況下,你會希望通過從不能也這樣做在數據庫之外覆蓋數據庫中調用存儲過程動態添加列。

+0

謝謝,它有幫助。儘管其他答案更方便。 –

+0

這是我們的用例。我們有一個數據庫升級腳本,可以從我們的軟件的一個版本轉到另一個版本,它恰好已經被編寫爲單個SQL文件。其中一個限制是我們有一個可以多次執行而不會產生任何錯誤的文件。爲此,我們必須創建名爲CREATE_TABLE_IF_NOT_EXISTS(),ADD_COLUMN_IF_NOT_EXISTS()和RENAME_COLUMN_IF_EXISTS()的存儲過程。它比我們預期的要複雜一點,我們可能會更好地寫一個批處理文件(Windows應用程序)或一些混合文件,但我們確實有一個用例。 – Carl

+0

對,我明白了,但正如我所提到的,我無法想象一種情況,您需要在*數據庫中執行此操作,否則您無法在其中執行此操作。大多數這些任務不是某些用戶需要訪問它的事情。我的觀點是腳本環境是功能的超集。另外這聽起來很可怕。檢查存在並通知/拋出錯誤比靜默地修復事情要好得多,特別是在執行升級時。 –