1

The following procedure:

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;

compiles successfuly, but when executed:

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

results in error:

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

Why?

1
  • 1
    AFAIK, you can't use bind for DDL statements, can you? Commented Apr 25, 2012 at 13:32

2 Answers 2

5

You can't use bind variables in place of identifiers, such as the user name in this statement. The value of the identifier needs to be known when the statement is parsed, whereas a bind value is incorporated after parsing, before execution.

Sign up to request clarification or add additional context in comments.

Comments

4

I think that the following would work

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;

Share and enjoy.

2 Comments

That do work, I tried. The problem is, its VERY open to sql injection. Is there some secure way to accomplish the task?
You might use the DBMS_ASSERT package to avoid SQL injection. See link. For example, you might use DBMS_ASSERT.ENQUOTE_NAME to make sure the user name and old and new password are properly treated as names, and DBMS_ASSERT.SCHEMA_NAME to assert that the user name is a valid one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.