Oracle动态PL / SQL。我不能让它工作

时间:2012-12-12 11:04:32

标签: oracle dynamic plsql

所以这是我的代码:

CREATE OR REPLACE PROCEDURE UPDATE_USER
(
  updateColumn IN USERS.column_name%type,
  changeStr IN VARCHAR2,
  unID IN VARCHAR2
)
IS
BEGIN
  EXECUTE IMMEDIATE
    'UPDATE
      users
    SET :1 = :2
    WHERE
      uniqueID = :3'
  USING updateColumn, changeStr, unID; 
END;
/

我已经在此搜索了其他答案,据我所知,这应该有效。但是我得到错误:     '错误(3,25):PLS-00302:组件' COLUMN_NAME'必须声明'

感谢。

1 个答案:

答案 0 :(得分:2)

错误消息指定第3行,字符25,它指向column_name参数声明中的updateColumn。您似乎尝试将列名称作为参数传递给更新,但这意味着在编译时该列未知,因此无法知道其类型。这也没有意义 - 如果它是number列,那么您将尝试将列名称传递给数字参数,这无论如何都无法工作。如果您不想将其声明为简单varchar2,则可以使用user_tab_columns.column_name%type

但是您无法使用绑定变量在update语句中动态设置列名。它会编译,但会从以冒号开头的表观名称获得ORA-01747。你需要连接它,比如:

CREATE OR REPLACE PROCEDURE UPDATE_USER
(
  updateColumn IN user_tab_columns.column_name%type,
  changeStr IN VARCHAR2,
  unID IN VARCHAR2
)
IS
BEGIN
  EXECUTE IMMEDIATE
    'UPDATE
      users
    SET ' || updateColumn || ' = :1
    WHERE
      uniqueID = :2'
  USING changeStr, unID; 
END;
/

但您需要将列名清理为avoid SQL injection。例如,APC answer to the question you linked to提及使用DBMS_ASSERT包。