2

I have the following function in PLSQL which connects remotely to different Database Links to change passwords:

FUNCTION fun_change_password(DB_LINK_VARIABLE varchar2)
    RETURN binary_integer IS

    jobid binary_integer;

  BEGIN
      dbms_job.submit@DB_LINK_VARIABLE (jobid,'begin execute immediate ''alter user MYUSER identified by mypassw''; end;');
      COMMIT;
      RETURN jobid;
  END;

My goal is to specify which DB Link to use sending its name in a varchar2 variable called *DB_LINK_VARIABLE*. But when I compile this into a package, the parser sends me an error:

PLS-00352: Unable to access another database 'DB_LINK_VARIABLE'

Obviously, I pre-configured and tested all my datalinks and works perfectly.

How can I use variable 'DB_LINK_VARIABLE' into this code?

3
  • 1
    I would be surprised if you could to this. Commented Jan 13, 2014 at 15:21
  • @OldProgrammer Actually, there is a way to do this using 'dynamic SQL' and SYS_REFCURSOR data-type, but I found a problem with quotation. Check this example: CREATE OR REPLACE FUNCTION pro_test (pv_dblink VARCHAR2) IS emp_refcur SYS_REFCURSOR; empno VARCHAR2(20); ename VARCHAR2(20); BEGIN OPEN emp_refcur FOR 'SELECT empno, ename FROM emp@'||pv_dblink; LOOP FETCH emp_refcur into empno,ename; EXIT WHEN emp_refcur%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Employee no: '||empno||'/ Employee name: '||ename); END LOOP; END; Commented Jan 13, 2014 at 19:15
  • 1
    I just found this.. Justin's answer for this question here Commented Jan 16, 2014 at 7:16

2 Answers 2

2

You can do this with dynamic SQL by executing an anonymous PL/SQL block.

Below is a simple example where I execute dbms_utility.get_time function over a database link.

$ cat so35.sql
declare
  function remote_time(p_dblink in varchar2) return number is
    v_time number; 
  begin  
    execute immediate
      'begin :time := dbms_utility.get_time@' || p_dblink || '; end;'
    using out v_time;
    return v_time;
  end;
begin
  dbms_output.put_line('time = ' || remote_time('foo'));
end;
/


SQL> select dbms_utility.get_time as local, dbms_utility.get_time@foo as remote from dual;

     LOCAL     REMOTE
---------- ----------
  77936814 1546395927

SQL> @so35.sql
time = 1546396850

PL/SQL procedure successfully completed.

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

1 Comment

I see.. You are right, so, the user can just make a minor change in his code to make it work! Thanks for letting me know my mistake!
1
PLS-00352: Unable to access another database 'DB_LINK_VARIABLE'

Error message shows, oracle is looking for a db link called DB_LINK_VARIABLE instead of the value associated to it.

You may need to do a check on variable, and make the hardcoding of the db link , instead of using a bind variable for it.!

Functions are compiled code in DB, so I guess oracle would do a semantic check on this during compilation itself, rather than doing it in runtime.

If it was just a SQL call to remote db, EXECUTE IMMEDIATE would have been used. Since it is PL/SQL there is no way for it, but for having multiple IF conditions, to validate the variable name, and making the full name in your PL/SQL block.

1 Comment

The explanation of PLS-00352 is correct, but the conclusion that this can't be done with dynamic SQL is incorrect !

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.