Oracle 我想将变量参数传递给外部SQL文件(PL/SQL和SQL*Plus)

Oracle 我想将变量参数传递给外部SQL文件(PL/SQL和SQL*Plus),oracle,plsql,sqlplus,Oracle,Plsql,Sqlplus,我已经搜索了这个论坛,并通过谷歌为我的问题找到了答案,但我找不到我的挑战的具体答案。这就是为什么我在这里问它,希望能从你们当中的一位那里得到答案 我希望使用多个SQL文件,而一个SQL文件是控制文件,它使用参数执行其他SQL文件。 该文件名为:startup.sql 我有一个包含所有值的表(不介意列的名称,我为我的帖子更改了它们) 插入以下内容之一(有更多条目,但一条足以向您展示工作方式): 我的控制文件如下所示: set escape on set serveroutput on SET DE

我已经搜索了这个论坛,并通过谷歌为我的问题找到了答案,但我找不到我的挑战的具体答案。这就是为什么我在这里问它,希望能从你们当中的一位那里得到答案

我希望使用多个SQL文件,而一个SQL文件是控制文件,它使用参数执行其他SQL文件。 该文件名为:startup.sql

我有一个包含所有值的表(不介意列的名称,我为我的帖子更改了它们)

插入以下内容之一(有更多条目,但一条足以向您展示工作方式):

我的控制文件如下所示:

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;
/
在我的uitvoer.sql中,我有一个如下的变量:

    variable_s := '&&1';
    variable_blu := '&&2';
现在发生了以下事情。 我启动SQLPlus(使用所有凭据)并启动我的控制文件(control.sql)。 SQLPlus的输出中说明了以下内容:

old 89:        s = '&&1';
new 89:        s = '%v_s%';
old 128:       b_lu := '&&2';
new 128:       b_lu := '%v_blu%';
我期待的是:

old 89:        s = '&&1';
new 89:        s = 'Test';
old 128:       b_lu := '&&2';
new 128:       b_lu := 'J';
为什么控制文件中的变量没有正确解析为新的SQL文件

我还发现了以下帖子: / 这看起来像是我的挑战,但我不是从批处理文件调用,而是从sql文件调用

我希望有人能帮助我。如果有什么不清楚的地方,我可以试着解释一下。

@
是a,它在PL/SQL中没有任何意义。您的脚本在解析时包含在PL/SQL块中,如果您在缓冲区中保存代码,您可以看到这一点。控制块中声明的变量可直接用于“包含”代码,无需替换

例如,如果
uitvoer.sql
只包含:

dbms_output.put_line(v_s);
然后,此控制脚本:

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

list
产生:

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;
缓冲区中的PL/SQL块包含代码,而不是对
uitvoer.SQL
的引用。但是包含的代码起作用了,因为它引用了控制脚本中的变量,该变量仍在作用域中


如果您希望允许控制变量具有不同的名称,允许更灵活地调用
uitvoer.sql
,那么您仍然可以使用替换变量,但仍然替换变量名称,而不是其值。例如,使用此
uitvoer.sql
(请注意,替换变量assginment的周围没有引号):

以及传递变量名的控制脚本:

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

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;

为什么要将代码存储在外部文件中,而不是数据库中?以使其不依赖于数据库。我在不同的数据库上使用我的sql文件。我有一个文件正在创建我的数据库结构,所以每次我需要它时它都是一样的。另外,数据库是由其他方管理的,并且可以在他们需要的时候返回角色。我也尝试过,这也有同样的效果。我有一个控制文件,它正在检查哪些文件是运行所必需的。我有6个外部文件。所有这些都使用相同的变量,但它们检查不同的选项。@JeroenMolder-您显示的内容根本不应该运行;在控制脚本的调用中,是否真的将值括在引号中,例如
'%v_s%'
和(在Nicholas版本中)
'v_s'
?您也不能从PL/SQL调用外部文件;
uitvoer.sql
的内容被解析为块的一部分,因此
v_s
将被视为包含代码中的一个变量-您根本不需要将其视为替换变量?@AlexPoole不,这只是问题,它根本没有运行。我没有将这些值括在引号中。因为如果我这样做,它确实是以文本形式发送的。它应该发送变量中的值。我认为它没有正确解析变量。
declare
  variable_s varchar2(10);
begin
  variable_s := &&1;
  dbms_output.put_line(variable_s);
end;
declare
  v_s varchar2(10) := 'Test';
begin
  @uitvoer.sql v_s
end;
/
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;