在 PL/SQL 中使用 oracle SET 值
Posted
技术标签:
【中文标题】在 PL/SQL 中使用 oracle SET 值【英文标题】:Use oracle SET values in PL/SQL 【发布时间】:2016-01-14 09:44:11 【问题描述】:我被要求为迁移文件设置一些环境参数。但是,像SQLBLANKLINES
这样的参数只在sqlplus中有效,其他工具(例如Flyway)会被它的使用破坏。 autocommit
也是如此。
有什么方法可以执行以下操作:
declare
v1 varchar2(60)
begin
v1 := SHOW SQLBLANKLINES
if (v1 is not empty) then
SET SQLBLANKLINES ON
end if;
end;
/
或者以某种方式查询环境以设置可用参数?
或者以某种方式确定正在使用的正是 sqlplus?
我知道SHOW
和SET
命令,但我不知道如何将它们的结果放入变量并在PL/SQL 中调用SET
。
Oracle 是 11g。
【问题讨论】:
如果您不知道将使用哪个客户端,则应在运行迁移文件之前在客户端环境中设置这些内容。这是安装说明在必要时指定的内容。但是不,您无法查看客户端设置或从 PL/SQL 块运行客户端命令。 【参考方案1】:您不能在 PL/SQL 中引用 SQL*Plus
命令,因为 PL/SQL 无法识别它们。此外,您不能直接在SQL*Plus
脚本中使用条件语句,因此您必须有点创意。但是,您可以有一个脚本来创建和运行另一个脚本,您可以使用它来注入条件语句。
例如,这是我用来让我的发布脚本继续或不继续的脚本(它退出 SQL*Plus
):
continue_or_exit.sql:
prompt Do you want to continue script execution?
accept yn prompt 'Y / N : ';
set termout off;
set verify off;
set heading off;
set pause off;
set echo off;
column aaaa newline;
spool continue_or_exit_output.sql
select decode(upper('&&yn'), 'Y', 'prompt Executing ...',
'prompt Stopped'
),
decode(upper('&&yn'), 'Y', '', 'accept return_key prompt ''Press <Return>''') aaaa,
decode(upper('&&yn'), 'Y', '', 'exit') aaaa
from dual;
spool off;
set termout on;
@continue_or_exit_output.sql
set termout on;
set verify on;
set heading on;
您应该能够根据您的情况对其进行修改,以决定是否打印出相关的 SQL*plus 命令。
【讨论】:
看起来不错,但这个脚本是交互式的,但我想通过 Flyway 手动和自动运行它 您不必以交互方式定义变量;您可以在调用它时将其作为脚本的一部分传递。例如。@your_release_scripts your_param_value
,然后通过&&1
引用它。这样,您可以在调用时定义它,希望您可以在 Flyway 中这样做?
其实flyway只是简单的获取带有特定前缀的文件列表,然后一个一个地执行。
那么也许您可以创建包装脚本,只需使用正确的参数调用相关脚本?【参考方案2】:
您不能从 PL/SQL 中调用 SQL*Plus 或任何客户端命令。它完全在服务器上执行。您可以告诉which client is being used,至少如果客户端表现良好,但这并不能真正帮助您,因为您仍然无法使用该信息来控制发出哪些客户端命令。
最简单的方法可能是使用迁移命令编写核心脚本,然后为特定客户端编写包装脚本;所以如果你有core_migration.sql
,你可以有另一个名为sqlplus_migration.sql
的脚本刚刚做了:
SET SQLBLANKLINES ON
-- any other SQL*Plus-specific set-up you want
SET PAGESIZE 0
SET LINESIZE 200
SET SERVEROUTPUT ON SIZE UNLIMITED
WHENEVER SQLERROR EXIT FAILURE
-- etc.
-- Run core migration script
@core_migration
exit 0;
SQL*Plus 需要能够找到核心脚本,因此最好/有必要使用 substitution variable 传递完整路径:
...
SET DEFINE ON
-- Run core migration script passed via command line
@&&1
exit 0;
...然后将其称为:
sqlplus -s -l usr/pwd @sqlplus_migration /path/to/core_migration.sql
(我不喜欢将凭据放在命令行上;您的脚本可以提示输入它们,但您建议您希望它是非交互式的)。
我不熟悉 Flyway - 它可能只是想调用核心脚本而不需要额外的步骤。
【讨论】:
您提供的客户链接很酷。我可以从 PL/SQL 执行 sql 文件吗? @ka2m - 不,您不能执行文件,PL/SQL 块在服务器上执行,无法看到客户端的文件或运行 SQL*Plus 命令(如 @ 或 start )。您可以使用 utl_file 读取文件,提取语句,运行它们 - 但前提是文件在服务器上,即使这样也不简单......以上是关于在 PL/SQL 中使用 oracle SET 值的主要内容,如果未能解决你的问题,请参考以下文章
使用带有布尔输入参数的 PL/SQL 在 oracle 中调用 java 存储过程
在 oracle 中使用正则表达式查找 POBOX - PL/SQL