0

だからここに私のコードがあります:

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;
/

私はこれについて他の答えを探しました、そして私が知る限りこれはうまくいくはずです。ただし、次のエラーが発生します:'Error(3,25):PLS-00302:コンポーネント'COLUMN_NAME'を宣言する必要があります'

ありがとう。

4

1 に答える 1

2

column_nameエラーメッセージは、パラメータの宣言で指す行3、文字25を指定し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;
/

ただし、SQLインジェクションを回避するには、列名をサニタイズする必要があります。たとえば、リンクした質問に対するAPCの回答は、DBMS_ASSERTパッケージの使用について言及しています。

于 2012-12-12T11:21:30.303 に答える