2010-08-09 57 views
0

大廈Tony's answerthis question如何使用動態SQL來聲明從表名派生的列名?

如果我想要做這樣的事情,

CREATE PROCEDURE A(tab IN VARCHAR2) IS 
tab.col_name <column> --static declaration (column name always remains the same) 
BEGIN 
    EXECUTE IMMEDIATE 'INSERT INTO ' || tab(col_name) || 'VALUES(123)'; 
END A; 

如何使用動態SQL在上述情況下?

+0

爲什麼negvote? – Moeb 2010-08-09 13:43:56

+1

這是一個很好的問題...... – 2010-08-09 13:46:37

回答

4

這個例子通過在表名和列名:

CREATE PROCEDURE A 
    (tab IN VARCHAR2 
    , col_name IN VARCHAR2 
) IS 
BEGIN 
    EXECUTE IMMEDIATE 'INSERT INTO ' || tab || '(' || col_name || ') VALUES(123)'; 
END A; 

你需要認識到這一切後EXECUTE IMMEDIATE必須是包含一些有效的SQL字符串。驗證這一點的一個好方法是將其設置在一個變量,並輸出到屏幕上:

CREATE PROCEDURE A 
    (tab IN VARCHAR2 
    , col_name IN VARCHAR2 
) IS 
    v_sql VARCHAR2(2000); 
BEGIN 
    v_sql := 'INSERT INTO ' || tab || '(' || col_name || ') VALUES(123)'; 
    DBMS_OUTPUT.PUT_LINE('SQL='||v_sql); 
    EXECUTE IMMEDIATE v_sql; 
END A; 

這應該然後顯示類似下面的SQL加:

SQL = INSERT INTO mytable(mycolumn) VALUES(123)

(提供的服務器輸出已打開)。

編輯:既然你想要的列名是始終具有相同值的局部變量,可以這樣做的:

CREATE PROCEDURE A (tab IN VARCHAR2) 
IS 
    col_name VARCHAR2(30) := 'MYCOLUMN'; 
    v_sql VARCHAR2(2000); 
BEGIN 
    v_sql := 'INSERT INTO ' || tab || '(' || col_name || ') VALUES(123)'; 
    DBMS_OUTPUT.PUT_LINE('SQL='||v_sql); 
    EXECUTE IMMEDIATE v_sql; 
END A; 
+0

如果我不想傳遞一個列名作爲參數,而是想要在過程中聲明**,該怎麼辦?那可能嗎? – Moeb 2010-08-09 13:49:46

+0

列名是否總是相同?如果不是,你的程序應該以某種方式發現?請進一步解釋你需要什麼。 – 2010-08-09 13:58:23

+0

是的,列名始終應該是相同的。 – Moeb 2010-08-09 14:01:09