2012-04-25 6 views
1

には、次の手順を実行:実行時には即時アルターユーザーバインド変数

create or replace 
PROCEDURE ChangePassword 
(
    p_Name  VARCHAR2, 
    p_Password VARCHAR2 
) 
AS 
    EXECUTE IMMEDIATE 'ALTER USER :a IDENTIFIED BY :b' USING p_Name, p_Password; 
END; 

をsuccessfulyコンパイル、しかし:エラーで

exec ChangePassword('TestUser', 'newPassword'); 

結果:

01935. 00000 - "missing user or role name" 
*Cause: A user or role name was expected. 
*Action: Specify a user or role name. 

なぜ?

+1

AFAIKでは、DDL文にはバインドを使用できません。 –

答えて

5

識別子の代わりにバインド変数(このステートメントのユーザー名など)を使用することはできません。ステートメントが解析されるときに識別子の値を知る必要がありますが、実行前に解析後にバインド値が組み込まれます。

3

私は、次の

create or replace PROCEDURE ChangePassword(p_Name   IN VARCHAR2, 
              p_Old_password IN VARCHAR2, 
              p_New_password IN VARCHAR2) 
AS 
    EXECUTE IMMEDIATE 'ALTER USER ' || p_name || 
        ' IDENTIFIED BY ' || p_New_password || 
        ' REPLACE ' || p_Old_password; 
END; 

シェアを仕事と楽しんだと思います。

+3

それはうまくいく、私は試しました。問題は、非常にSQLインジェクションにオープンです。タスクを達成するための安全な方法はありますか? – Atif

+1

DBMS_ASSERTパッケージを使用すると、SQLインジェクションを回避できます。 [リンク](http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_assert.htm)を参照してください。たとえば、DBMS_ASSERT.ENQUOTE_NAMEを使用して、ユーザー名と古いパスワードと新しいパスワードが適切に名前として扱われ、DBMS_ASSERT.SCHEMA_NAMEがユーザー名が有効であることを確認することができます。 –