【发布时间】:2012-02-08 11:13:06
【问题描述】:
如何在 pl/sql 块中使用“START SCRIPT”?
我想用这样的东西
declare
begin
proc(para1,para2);
execute immediate 'start prompt1' ;
end;
/
我还想知道,我可以从 prompt1 获取一个值到调用脚本的 PL/SQL 块中吗?因为我需要使用该值来执行PL/SQL块中的一些操作。
【问题讨论】:
如何在 pl/sql 块中使用“START SCRIPT”?
我想用这样的东西
declare
begin
proc(para1,para2);
execute immediate 'start prompt1' ;
end;
/
我还想知道,我可以从 prompt1 获取一个值到调用脚本的 PL/SQL 块中吗?因为我需要使用该值来执行PL/SQL块中的一些操作。
【问题讨论】:
立即执行 'start prompt1' ;
立即执行是执行SQL语句,而不是任意命令。
我可以从 prompt1 获取一个值到我调用脚本的 PL/SQL 块中
您可以运行运行脚本 - 但我怀疑您是否可以从 SQL 脚本捕获输入,尤其是在 PL/SQL 块中
【讨论】:
如果您使用的是 sql*plus(或正在使用它的工具),那么您可以执行以下操作:
set serveroutput on
variable a number;
begin
:a := &promt;
dbms_output.put_line(:a);
end;
/
如果它是批量运行的,那么你可以这样做:
variable a number;
begin
:a := &1;
dbms_output.put_line(:a);
end;
并获取 :a 的值作为参数-
sqlplus sdad/fdsfd@fdggd @<your_script.sql> <val_for_a>
【讨论】:
现在是 2012 2017 年。脚本是上个千年的笨拙而脆弱的遗留物。 Oracle 有很多我们可以在 PL/SQL 中执行的功能,还有 Java 存储过程,还有启动作业的调度。除了运行 DDL 来创建或修改模式之外,在 Oracle 数据库环境中几乎不需要脚本;甚至 DDL 脚本也应该从外部客户端触发,可能是诸如 TeamCity 之类的构建工具。
我尤其认为尝试从 PL/SQL 程序运行 SQL 脚本是一种架构故障。你用存储过程不能做的脚本做什么?
至于将输入传递给存储过程,这就是参数的用途。 PL/SQL 不是交互式的,我们需要一个客户端来输入值。根据具体情况,这可以异步完成(文件或表中的值)或同步(从 SQL*Plus、SQL Developer 或定制前端调用存储过程)。
话虽如此,在现实世界中,我们使用的架构是杂乱无章的,数据库和外部操作系统之间存在相互依赖关系。那么我们能做些什么呢?
请注意,所有这些选项都需要提升访问权限(授予 DIRECTORY 对象、安全凭据等)。这些只能由特权用户(即 DBA)授予。除非我们的数据库有一个令人吃惊的松懈的安全配置,否则我们无法从 PL/SQL 运行任意的 shell 脚本。
最后,不清楚您期望在 PL/SQL 中运行 SQL 脚本有什么好处。请记住,PL/SQL 在数据库服务器上运行,因此它无法在客户端机器上看到脚本。鉴于接受用户输入的要求,这似乎是相关的。
也许最简单的解决方案是重新配置原始脚本。将必要的 PL/SQL 调用拆分成一个块,然后调用指定的脚本:
begin
proc(para1,para2);
end;
/
@prompt1.sql
【讨论】:
bootstram_schema_A.sql 或bootstrap_schema_B.sql. 根据条件,我们可能会运行一个或另一个(或一个接一个)。这是一种简化,我正在处理的实际情况要复杂一些,但这似乎有点矫枉过正当 PL/SQL 提供我们需要的所有控制结构来确定调用哪些脚本以及以什么顺序调用时,用另一种语言(比如 Java 或 Ant 脚本)编写驱动程序。
另一种做法是在一个*.bat 上执行带有参数的,例如:
示例 c:/oracle/bin/sqlplus.exe -w @c:/name
sql %1 %2 @c:/output.sql
【讨论】:
您可以在 SqlPlus 中编写一个 pl/sql 块来检查表中的参数,然后执行脚本。在要执行的脚本(下面的 MyScript.sql)中,语句终止符必须是“;”而不是“/”
declare
vMyParameter number := 0;
begin
select count(*) into vMyParameter
from MyTable
where MyCheckValue = 'Y';
if vMyParameter = 1 then
@MyFolder/MyScript.sql;
end if;
end;
/
【讨论】: