在 .sql 脚本中定义和使用变量

Posted

技术标签:

【中文标题】在 .sql 脚本中定义和使用变量【英文标题】:Defining and Using Variables in .sql scripts 【发布时间】:2013-03-28 20:31:17 【问题描述】:

我正在尝试在 .sql 文件中定义变量,以便可以在我的 sql 语句中使用它们。但是我对如何定义这些变量感到非常困惑,我什至找不到一个很好的在线资源可以清楚地解释所有这些。我遵循不同来源的建议,并且在“Oracle SQL Developer”中不断出现编译错误。这是我的两个问题:

问题1:看来你可以通过以下2种方式定义变量。这两种方式有什么区别,我可以同时使用吗?

define first_name = Joe;
select * from customer where name = '&firstname';

variable first_name CHAR;
exec :first_name:= 'Joe';
select * from customer where name = :firstname;

问题2:在第一种方法(即使用define命令)中,我可以定义一个number类型的变量吗?如果可以,我该怎么做?

【问题讨论】:

您似乎忘记用分号结束第一个代码块中的第一行。此外,如果您发布您遇到的编译错误,它可能会有所帮助。 对问题 2 的简短回答:否。另请参阅***.com/a/7783530。 @user1888243 - 我已经扩展了我的答案来描述“问题 1”和“问题 2”之间的区别。卢克是正确的,对“问题 2”的简短回答是否定的;希望我的扩展答案能解释原因。 谢谢埃德。并感谢运气。我只是看了你在那个问题上的回答;那正是我想要的。绑定变量和替代变量的区别。 【参考方案1】:

你可以定义NUMBER变量没问题:

SQL> VARIABLE myNum NUMBER;
SQL> EXEC :myNum := 123.456;

PL/SQL procedure successfully completed.

SQL> print myNum;

     MYNUM                                        
----------                                        
   123.456                                        

还支持许多其他类型。这是来自 VARIABLE 命令的USAGE 帮助文本:

Usage: VAR[IABLE] [ <variable> [ NUMBER | CHAR | CHAR (n [CHAR|BYTE]) |
                VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
                NVARCHAR2 (n) | CLOB | NCLOB | BLOB | BFILE
                REFCURSOR | BINARY_FLOAT | BINARY_DOUBLE ] ]

如果您输入VARIABLE(或只是VAR)而不输入任何其他内容,SQL*Plus 将列出所有变量及其值。

附录:对比原题中的两种变量赋值方式。

当你这样做时......

define first_name = Joe
select * from customer where name = '&first_name';

...它更像是 C/C++ 中的#define。你不能把它当作一个变量来对待;它只是每次 SQL*Plus 看到 &amp;first_name 时粘贴的文本。

当你这样做时......

variable first_name CHAR;
exec :first_name:= 'Joe';
select * from customer where name = :first_name;

您正在创建一个可以操作的真实变量。

请注意,如果您在定义中使用CHAR(没有大小),则第一个分配将确定其大小,之后您不能再延长它。如果将其定义为CHAR(50),它将始终为 50 个字符长并用空格填充。这可能会让人感到困惑,所以在大多数情况下,我建议将 VARCHAR2 用于字符串。

【讨论】:

这就是我真正追求的;两种方法的区别。令人惊讶的是,对于诸如成熟的软件和行业,没有在线资源可以合乎逻辑地解释这些。我不明白,Oracle 在这些领域的文档很烂。【参考方案2】:

- 问题 1 的答案: 第一种类型的变量称为替换变量,它仅适用于 SQL*Plus 和 SQL Developer。因此,当您在任何 SQL 语句中提供替代变量时,SQL*Plus 将变量替换为它的值。它与 Oracle 服务器或性能无关。 您提供的示例将在发送到 Oracle 数据库服务器之前转换为以下内容:

select * from customer where name = 'Joe';

第二部分称为绑定变量,它不是 SQL*Plus 或 SQL Developer 独有的,因为您可以在连接到 Oracle 的 Java 应用程序(或其他语言)中使用它。 当您多次运行相同的语句时,绑定变量会提供更好的性能,因为您总是按原样提交语句(无需重写)。然后在数据库级别对变量进行评估。例如,假设您已将“first_name”的值更改为“Mark”:

exec :first_name:= 'Mark';

与绑定变量相同的语句被提交到 Oracle 数据库服务器。数据库使用缓存区域来查找以前运行过的相同语句并再次使用它。然后数据库使用变量值。这意味着数据库不需要为同一条语句重新解析和重新计算最佳执行计划。 但是第一种类型(替换变量)不是这种情况。

- 问题 2 的答案: 不,你不能,因为正如我上面所说,SQL*Plus 或 SQL Developer 所做的只是重写语句,用它的值替换变量名。它对它的类型一无所知。这里只进行文本替换。

您可以在此处找到更多详细信息: http://www.oracle-base.com/articles/misc/literals-substitution-variables-and-bind-variables.php

【讨论】:

【参考方案3】:

在Oracle中,你可以如下定义变量:

CREATE OR REPLACE FUNCTION MyFunction()
AS

    my_number     NUMBER (20, 0);
    first_name    VARCHAR2(256);

BEGIN
    first_name := 'Joe';
    select * from customer where name = first_name;

END

这就是你要找的吗?

【讨论】:

感谢您的回复。事实上,这是我可以使用的第三种语法。为什么定义变量的方式各不相同,它们有什么区别?所有这些语法都是由 Oracle 创建的吗? @User....我不知道哪一个更适合您的情况。我正在使用 Oracle 10,这是我们在 Oracle 10 中的首选方法 另外,我使用了您在上面提供的语法,我得到“绑定变量“my_number”未声明”。所以,语法不起作用。 我知道它是如何在 PL/SQL 块中完成的;我正在寻找的是它是如何在简单的 sql 脚本中完成的。

以上是关于在 .sql 脚本中定义和使用变量的主要内容,如果未能解决你的问题,请参考以下文章

使用 R 中定义的变量从 R 运行 SQL 脚本

DB2的SQL脚本如何定义变量,并赋值使用?执行成功有重赏哦,谢谢

MYSQL在脚本中使用变量-执行脚本时传参

如何在shell脚本中使用变量

shell脚本中sql语句得到一个值,赋值给变量出错

如何在 SQL 脚本中使用 Perl 变量(使用反引号)