【问题标题】:I want to pass a variable argument to external SQL file (PL/SQL with SQL*Plus)我想将变量参数传递给外部 SQL 文件(带有 SQL*Plus 的 PL/SQL)
【发布时间】:2014-02-02 06:45:11
【问题描述】:

我已经在这个论坛和谷歌上搜索了我的问题的答案,但我找不到我的挑战的具体答案。这就是为什么我在这里问它希望得到你们中的一个人的答复。

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

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

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)
)

插入以下其中一项(条目较多,但一项足以向您展示工作方式):

    insert into control (S,N,B,Acheck,Adcheck,Blu,ADB)
       values('Test','B','J','J','N','N', '');

我的控制文件如下:

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 文件?

我还发现了以下帖子: 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) 这看起来像是我的挑战,但我不是从批处理文件调用,而是从 sql 文件调用。

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

【问题讨论】:

  • 为什么要将代码存储在外部文件中,而不是存储在数据库中?
  • 使其不依赖于数据库。我在不同的数据库上使用我的 sql 文件。我有一个文件正在创建我的数据库结构,所以每次我需要它时都是一样的。此外,数据库由其他方管理,并且可以随时执行角色回退。
  • 我也试过了,效果一样。我有一个控制文件,它正在检查需要运行哪些文件。我有 6 个外部文件。它们都使用相同的变量,但它们检查不同的选项。
  • @JeroenMulder - 你所展示的根本不应该运行;您是否真的在控制脚本的调用中将值括在引号中,例如'%v_s%' 和(在尼古拉斯的版本中)'v_s'?您也不能从 PL/SQL 调用外部文件; uitvoer.sql 的内容被解析为块的一部分,因此 v_s 将被视为包含代码中的变量 - 您根本不需要将其视为替换变量?
  • @AlexPoole 不,这只是问题所在,它根本没有运行。我没有将值括在引号中。因为如果我这样做,它确实是作为文本发送的。它应该在变量中发送值。我认为它没有正确解析变量。

标签: oracle plsql sqlplus


【解决方案1】:

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

例如,如果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
  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;

【讨论】:

    猜你喜欢
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 2016-02-14
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    相关资源
    最近更新 更多