I want to pass a variable argument to external SQL file (PL/SQL with SQL*Plus)

oracle, plsql, sqlplus

Solution

`@` is a SQL*Plus command, it has no meaning in PL/SQL. Your script is being included within the PL/SQL block at parse time, which you can see if you `list` the code in the buffer. The variables declared in your control block are available to the 'included' code directly, without needing substitution.

As an example, if `uitvoer.sql` just contains:

dbms_output.put_line(v_s);

Then this control script:

set serveroutput on
declare
  v_s varchar2(10) := 'Test';
begin
  @uitvoer.sql
end;
/

list

Produces:

Test

PL/SQL procedure successfully completed.

  1  declare
  2    v_s varchar2(10) := 'Test';
  3  begin
  4  dbms_output.put_line(v_s);
  5* end;

The PL/SQL block in the buffer has the included code, not a reference to `uitvoer.sql`. But the included code worked because it referred to a variable from the control script which was still in-scope.

If you want to allow for the control variables having different names, allowing `uitvoer.sql` to be called more flexibly perhaps, then you can still use substitution variables, but you're still substituting the variable name, not its value. For example, with this `uitvoer.sql` (note that the substitution variable assginment does not have quotes around it):

declare
  variable_s varchar2(10);
begin
  variable_s := &&1;
  dbms_output.put_line(variable_s);
end;

And your control script passing the variable name:

declare
  v_s varchar2(10) := 'Test';
begin
  @uitvoer.sql v_s
end;
/

You see:

old   7:   variable_s := &&1;
new   7:   variable_s := v_s;
Test

PL/SQL procedure successfully completed.

  1  declare
  2    v_s varchar2(10) := 'Test';
  3  begin
  4  declare
  5    variable_s varchar2(10);
  6  begin
  7    variable_s := &&1;
  8    dbms_output.put_line(variable_s);
  9  end;
 10* end;

Problem

I have search this forum and via google for an answer for my question, but I can't find a specific answer for my challenge. That is why I am asking it here to hope to receive an answer from one of you guys. I want to work with multiple SQL files, whereas one SQL file is the control file that executes the other SQL files with parameters. That file is called: startup.sql I have a table with all my values (don't mind the names of the columns, I changed them for my post). ``` create table control ( S varchar2(15) not null, N varchar2(25 char) not null, B varchar2(25 char) not null, Acheck varchar2(25 char) not null, Adcheck varchar2(25) not null, Blu varchar2(25) not null, ADB varchar2(25) ) ``` Where one of the following is inserted (there are more entries, but one is enough to show you the way of working): ``` insert into control (S,N,B,Acheck,Adcheck,Blu,ADB) values('Test','B','J','J','N','N', ''); ``` My control file looks like: ``` set escape on set serveroutput on SET DEFINE ON declare cursor c_lees_control is select S, N, B, Acheck, Adcheck, Blu, ADB from control v_s varchar2(30); v_b varchar2(30); v_blu varchar2(30); begin for r_lees_control in c_lees_control loop v_s := r_lees_control.S; v_b := r_lees_control.B; v_blu := r_lees_control.Blu; if v_b = 'J' then --Also tried this. --@C:/Temp/uitvoer.sql $v_s $v_blu @C:/Temp/uitvoer.sql %v_s% %v_blu% end if; end loop; end; / ``` In my uitvoer.sql I have a variable like this: ``` variable_s := '&&1'; variable_blu := '&&2'; ``` Now the following is happening. I start SQLPlus (with all my credentials) and I start my control file (control.sql). In the output of SQLPlus the following is stated: ``` old 89: s = '&&1'; new 89: s = '%v_s%'; old 128: b_lu := '&&2'; new 128: b_lu := '%v_blu%'; ``` I was expecting the following: ``` old 89: s = '&&1'; new 89: s = 'Test'; old 128: b_lu := '&&2'; new 128: b_lu := 'J'; ``` Why are my variables in the control file not parsed correctly to the new SQL file? I also found the following posts: How do you pass an argument to a PL/SQL block within a sql file called using START in sqlplus? / Launch PL/SQL script from batch file (with arguments) It looks like my challenge, but I am not calling from an batchfile but from an sql file. I hope someone can help me. If something is unclear, I can try to explain it a bit more.

Original source