2010-08-09 28 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