读书笔记:SQL 查询中的SQL*Plus 替换变量(DEFINE变量)和参数

Posted dingdingfish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读书笔记:SQL 查询中的SQL*Plus 替换变量(DEFINE变量)和参数相关的知识,希望对你有一定的参考价值。

本文为“SQL*Plus 替换变量 - 在 SQL 查询中定义变量和参数”的读书笔记。

此文主要是讲替换变量,也称为DEFINE变量,但也涉及了绑定变量和SQL Plus系统变量。

这篇文章展示了替换变量如何替换 Oracle SQL 和 SQL*Plus 语句中的硬编码文本。

向作者致敬,尽管是10多年前的文章,但写的非常好和全面,仍具重要参考价值。

1 介绍

本文档解释了 SQLPlus 替换变量如何工作以及它们可以在哪里使用。 它显示了 SQLPlus 中使用的三种类型的变量(替换、绑定和系统)之间的关系。

替换变量可以替换 SQLPlus 命令选项或其他硬编码文本。 它们可用于自定义 SQLPlus 脚本输出。 语句中的替换变量引用在 SQL*Plus 执行语句之前被预处理和替换。 变量值可以预定义、提示输入或设置为脚本参数。 变量还可以保存从查询返回的值。 有时替换变量称为用户变量或定义变量。

替换变量的例子为:

SQL> define
DEFINE _DATE           = "22-JUN-22" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "orclpdb1" (CHAR)
DEFINE _USER           = "SSB" (CHAR)
DEFINE _PRIVILEGE      = "" (CHAR)
DEFINE _SQLPLUS_RELEASE = "2103000000" (CHAR)
DEFINE _EDITOR         = "vi" (CHAR)
DEFINE _O_VERSION      = "Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0" (CHAR)
DEFINE _O_RELEASE      = "2103000000" (CHAR)

绑定变量存储在 RDBMS 中执行的 SQL 和 PL/SQL 语句的数据值。 它们可以保存单个值或完整的结果集。

系统变量包含直接控制 SQL*Plus 的值,例如报表的行大小和页面大小。 一些系统变量会影响替换变量的处理方式。 系统变量有时称为 SET 变量。

系统变量的例子为:

SQL> show all
appinfo is OFF and set to "SQL*Plus"
arraysize 15
autocommit OFF
autoprint OFF
autorecovery OFF
autotrace OFF
blockterminator "." (hex 2e)
btitle OFF and is the first few characters of the next SELECT statement
cmdsep OFF
colinvisible OFF
coljson OFF
colsep " "
compatibility version NATIVE
concat "." (hex 2e)
copycommit 0
COPYTYPECHECK is ON
define "&" (hex 26)
describe DEPTH 1 LINENUM OFF INDENT ON
echo OFF
editfile "afiedt.buf"
embedded OFF
errorlogging is OFF
escape OFF
escchar OFF
exitcommit ON
FEEDBACK ON for 6 or more rows SQL_ID OFF
flagger OFF
flush ON
fullcolname OFF
heading ON
headsep "|" (hex 7c)
history is OFF
instance "local"
jsonprint NORMAL
linesize 80
lno 14
loboffset 1
lobprefetch 0
logsource ""
long 80
longchunksize 80
markup html OFF HEAD "<style type='text/css'> body font:10pt Arial,Helvetica,sans-serif; color:black; background:White; p font:10pt Arial,Helvetica,sans-serif; color:black; background:White; table,tr,td font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px; th font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px; h1 font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;-
 h2 font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt; a font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;</style><title>SQL*Plus Report</title>" BODY "" TABLE "border='1' width='90%' align='center' summary='Script output'" SPOOL OFF ENTMAP ON PREFORMAT OFF
markup CSV OFF DELIMITER , QUOTE ON
newpage 1
null ""
numformat ""
numwidth 10
pagesize 14
PAUSE is OFF
pno 0
recsep WRAP
recsepchar " " (hex 20)
release 2103000000
repfooter OFF and is NULL
repheader OFF and is NULL
rowlimit OFF
rowprefetch 1
securedcol is OFF
serveroutput OFF
shiftinout INVISIBLE
showmode OFF
spool OFF
sqlblanklines OFF
sqlcase MIXED
sqlcode 0
sqlcontinue "> "
sqlnumber ON
sqlpluscompatibility 21.0.0
sqlprefix "#" (hex 23)
sqlprompt "SQL> "
sqlterminator ";" (hex 3b)
statementcache is 0
suffix "sql"
tab ON
termout ON
timing OFF
trimout ON
trimspool OFF
ttitle OFF and is the first few characters of the next SELECT statement
underline "-" (hex 2d)
USER is "SSB"
verify ON
wrap : lines will be wrapped
xmloptimizationcheck OFF

SQL> show release
release 2103000000

2 使用替换变量

2.1 创建、显示和删除替换变量

可以使用 DEFINE 命令显式创建替换变量。 定义变量意味着存储一个值以供将来使用。

SQL> define myv = 'King'

创建替换变量的另一种方法是使用 ACCEPT 命令。 这可用于提示输入值:

SQL> accept myv2 char prompt 'Enter a last name: '

查看所有或指定的替换变量:

SQL> define
...
DEFINE MYV             = "King" (CHAR)
DEFINE MYV2            = "amigo" (CHAR)

SQL> define myv
DEFINE MYV             = "King" (CHAR)

可以使用 UNDEFINE 命令删除替换变量:

SQL> undefine myv

SQL> define myv
SP2-0135: symbol myv is UNDEFINED

2.2 引用替换变量

可以通过在其名称前加上与号 (&) 来引用变量:

-- HR sample schema
define myv = 'King'
select employee_id from employees where last_name = '&myv';

old   1: select employee_id from employees where last_name = '&myv'
new   1: select employee_id from employees where last_name = 'King'

EMPLOYEE_ID
-----------
        156
        100

如果不想显示替换前后的值,可以用SET VERIFY OFF:

SQL> set verify off
SQL> select employee_id from employees where last_name = '&myv';

EMPLOYEE_ID
-----------
        156
        100

其实这里的verify即系统变量:

SQL> show verify
verify OFF

2.3 提示未定义的变量

如果使用“&”前缀引用变量,但尚未定义变量值,SQL*Plus 会提示您输入值:

SQL> define myname
SP2-0135: symbol myname is UNDEFINED
SQL> select employee_id from employees where last_name = '&myname';
Enter value for myname: King

EMPLOYEE_ID
-----------
        156
        100

Oracle 全球化语言设置(例如 NLS_LANG 环境变量的语言组件)确定用于“输入值”提示的确切语言。 提示文本不能以其他方式更改。

2.4 “&”和“&&”前缀的区别

先看一个示例:

SQL> prompt Querying table &mytable
Enter value for mytable: employees
Querying table employees
SQL> define mytable
SP2-0135: symbol mytable is UNDEFINED

SQL> prompt Querying table &&mytable
Enter value for mytable: employees
Querying table employees
SQL> define mytable
DEFINE MYTABLE         = "employees" (CHAR)

单与号 (&) 和双与号 (&&) 都可以在语句中作为替换变量名称的前缀。 SQL*Plus 预处理语句并替换变量的值。 然后执行该语句。 如果变量之前没有定义,那么 SQL Plus 会在进行替换之前提示您输入一个值。

如果单个 & 号前缀与未定义的变量一起使用,则不会存储您在提示符处输入的值。 在语句中替换值之后,该变量立即被丢弃并保持未定义。 如果变量被引用两次,即使是在同一个语句中,也会提示您两次。 每次提示可以输入不同的值。

如果双 & 号引用导致 SQLPlus 提示您输入值,则 SQLPlus 将变量定义为该值(即,该值将存储到您退出)。 使用“&”或“&&”对变量的任何后续引用(即使在同一命令中)都会替换新定义的值。 SQL*Plus 不会再次提示您。

再来看一个复杂点的例子:

SQL> undefine mytable
SQL> prompt Querying table &mytable &mytable
Enter value for mytable: a
Enter value for mytable: b
Querying table a b
SQL> prompt Querying table &&mytable &mytable
Enter value for mytable: a
Querying table a a
SQL> prompt Querying table &&mytable &mytable
Querying table a a

2.5 将查询列值存储在替换变量中

存储在数据库中的数据可以放入替换变量中。

SQL> column last_name new_value mynv
SQL> select last_name from employees where employee_id = 100;

LAST_NAME
-------------------------
King

SQL> define mynv
DEFINE MYNV            = "King" (CHAR)

COLUMN 命令中的 NEW_VALUE 选项隐式创建了一个名为“mynv”的替换变量。 在查询引用 LAST_NAME 列之前,不会实际创建该变量。 查询完成后,变量“mynv”保存从列“last_name”中最后检索到的值。

2.6 预定义的替换变量

启动 SQL*Plus 时创建的预定义替换变量可以通过输入不带参数的 DEFINE 来查看。 每个预定义变量都带有下划线前缀。 预定义变量可以像用户定义的替换变量一样未定义或重新定义。

-- 我的笔记本
SQL> define
DEFINE _DATE           = "23-JUN-22" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "orclpdb1" (CHAR)
DEFINE _USER           = "HR" (CHAR)
DEFINE _PRIVILEGE      = "" (CHAR)
DEFINE _SQLPLUS_RELEASE = "2103000000" (CHAR)
DEFINE _EDITOR         = "vi" (CHAR)
DEFINE _O_VERSION      = "Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0" (CHAR)
DEFINE _O_RELEASE      = "2103000000" (CHAR)

-- 云端实例
SQL> define
DEFINE _DATE           = "23-JUN-22" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "orclpdb1" (CHAR)
DEFINE _USER           = "SSB" (CHAR)
DEFINE _PRIVILEGE      = "" (CHAR)
DEFINE _SQLPLUS_RELEASE = "2106000000" (CHAR)
DEFINE _EDITOR         = "vi" (CHAR)
DEFINE _O_VERSION      = "Oracle Database 21c EE Extreme Perf Release 21.0.0.0.0 - Production
Version 21.6.0.0.0" (CHAR)
DEFINE _O_RELEASE      = "2106000000" (CHAR)

SQL Plus 10.1 中引入了变量_DATE、_PRIVILEGE 和_USER。 SQL Plus 9.2 中引入了变量_CONNECT_IDENTIFIER。 SQL Plus 18 中引入了变量 _SQL_ID。

  • _CONNECT_IDENTIFIER:变量_CONNECT_IDENTIFIER 包含用于启动SQL Plus 的连接标识符。 例如,如果 SQL Plus 连接字符串是“hr/my_password@MYSID”,则该变量包含 MYSID。 如果您使用完整的 Oracle Net 连接字符串,例如“hr/my_password@(DESCRIPTION=(ADDRESS_LIST=…(SERVICE_NAME=MYSID.MYDOMAIN)))”,则 _CONNECT_IDENTIFIER 将设置为 MYSID。 如果未明确指定连接标识符,则 _CONNECT_IDENTIFIER 包含 Oracle 用于连接的默认连接标识符。 例如,在 UNIX 上,它将包含环境变量 TWO_TASK 或 ORACLE_SID 中的值。 如果未连接 SQL Plus,则该变量被定义为空字符串。
  • _DATE:变量_DATE 可以是动态的,显示当前日期,也可以设置为固定字符串。 日期使用 NLS_DATE_FORMAT 的值进行格式化,并可能显示时间信息。 默认情况下,使用 &_DATE 的 DEFINE 或取消引用将给出使用时的日期。 _DATE 可以是 UNDEFINED,或使用显式 DEFINE 命令设置为固定字符串。 通过将 _DATE 定义为空字符串来重新启用动态日期行为。
  • _EDITOR:变量 _EDITOR 包含外部文本编辑器可执行文件名。
  • _O_RELEASE:变量_O_RELEASE 包含Oracle 数据库版本号的字符串表示。 如果您的 Oracle 数据库版本是 9.2.0.3.0,则该变量包含“902000300”。 如果您使用 Oracle Net 连接到远程数据库,Oracle 版本可能与 SQL*Plus 版本不同。
  • _O_VERSION:变量 _O_VERSION 包含一个显示数据库版本和可用选项的文本字符串。
  • _SQLPLUS_RELEASE:变量_SQLPLUS_RELEASE 包含格式与_O_RELEASE 类似的SQL*Plus 版本号。
  • _USER:变量 _USER 包含 SHOW USER 给出的当前用户名。 如果未连接 SQL*Plus,则该变量定义为空字符串。
  • _SQL_ID:SQL ID 是标识用于数据库监控的 SQL 语句的唯一值。 SQL ID 将分配给预定义的 SQL*Plus 变量 _SQL_ID。

2.7 脚本参数

假设我们有如下的脚本:

$ cat test.sql
SET VERIFY OFF
select '&1' from dual;
exit

我们可以以以下方式调用:

-- 在操作系统调用
$ sqlplus -S / as sysdba @test King

'KIN
----
King

-- 在SQL Plus中调用
SQL> @test King

'KIN
----
King

脚本参数成为定义的替换变量。 第一个参数的变量名是“1”,第二个是“2”,以此类推。效果与在SQL Plus中输入以下相同:

SQL> define 1 = King
SQL> @test

'KIN
----
King

脚本参数变量的类型为 CHAR,类似于使用 DEFINE 显式创建的变量。

允许使用单引号或双引号引用参数。 这允许在参数中使用空格。 调用 SQLPlus 的操作系统和脚本语言以不同的方式处理引号。 它们可能会也可能不会将引号传递给 SQLPlus 可执行文件。 例如,在 UNIX 上的标准 Bourne shell 中,参数周围的引号在参数传递给 SQLPlus 之前被去除,而 SQLPlus 永远不会看到引号。

建议使用您的 SQL*Plus 补丁级别检查引用参数在您的操作系统上是如何处理的。 为了 UNIX 和 Windows 环境之间的可移植性,在包含空格的参数周围使用双引号

例如:

$ sqlplus -S / as sysdba @test "King Queue"

'KINGQUEUE
----------
King Queue

$ sqlplus -S / as sysdba @test ""

'
-

简而言之,目前还没有方法将引号作为参数传递。

2.8 更多关于替代变量

替换变量引用在命令被解析和执行之前被预处理和替换。 伪代码如下:

1. Loop for each "&" and "&&" variable reference:
    If the variable already has a value defined (i.e. stored)
        Replace the variable reference with the value
    else
        Prompt for a value
        Replace the variable reference with the value
        If the variable is prefixed with "&&" then
            define (i.e. store) the variable for future use

2. Execute the statement

第 1 步发生在 SQL Plus 客户端工具中。 SQL Plus 然后将最后的语句发送到执行步骤 2 的数据库引擎。

不能在 PL/SQL 循环中重复提示。 此示例提示一次,输入的值将替换为脚本文本。 然后将生成的脚本发送到数据库引擎执行。 相同的输入值在表中存储五次:

SQL> create table mytable (a int);

Table created.

begin
  for i in 1 .. 5 loop
    insert into mytable values (&myv);
  3    4    end loop;
  5  end;
  6  /
Enter value for myv: 1
old   3:     insert into mytable values (&myv);
new   3:     insert into mytable values (1);

PL/SQL procedure successfully completed.

SQL> select count(*) from mytable;

  COUNT(*)
----------
         5

替代变量不会递归展开。 如果引用变量的值包含一个 & 符号,则该 & 符号按字面意思使用,不被视为第二个变量前缀:

set escape \\
define myv = \\&mytext
prompt &myv
-- 输出为:
&mytext

您不能将替换变量用作命令的第一个标记。 每个命令名称必须是硬编码文本,否则会显示错误。

SQL> &myv * from dual;
SP2-0734: unknown command beginning "&myv * fro..." - rest of line ignored.

替代变量不能用于 APPEND、CHANGE、DEL 和 INPUT 等缓冲区编辑命令。 这些命令中的与号 (&) 按字面意思处理。

如果您希望在替换变量名之后立即使用字母数字字符,请将 SET CONCAT 的值(默认为句点 (.))将变量名与以下字符分开。例如:

SQL> spool &mycity.Australia.log
-- 等效于
SQL> spool MelbourneAustralia.log

SQL> spool &myfile..log
-- 等效于
SQL> spool reports.log

ANSI“/* */”或“–”注释中看起来像替换变量的文本可能被视为一个,例如:

SQL> set feedback only
SQL> select department_id, location_id /* get dept & loc */ from departments;
Enter value for loc: test
old   1: select department_id, location_id /* get dept & loc */ from departments
new   1: select department_id, location_id /* get dept test */ from departments

27 rows selected.

&和loc之间居然可以有空格,不过还是建议写为&loc。

3 使用绑定变量

绑定变量在 SQL 和 PL/SQL 语句中用于保存数据或结果集。 它们通常用于 SQL 语句中以优化语句性能。 带有绑定变量的语句可以多次重新执行,而无需重新解析。 它们的值可以在 PL/SQL 块中设置和引用。 它们可以在 SQL 语句中引用,例如 选择。 除 VARIABLE 和 PRINT 命令外,绑定变量引用应以冒号为前缀。

绑定变量是使用 VARIABLE 命令创建的。 以下 PL/SQL 块设置绑定变量:

variable bv number
begin
  :bv := 8;
end;
/

-- 或者
variable bv number
execute :bv := 8

-- 或者
variable bv number = 8

显示变量定义和值:

SQL> variable
variable   bv
datatype   NUMBER
SQL> print bv

        BV
----------
         8

还可以作为参数传递给SQL Plus命令,仅支持EXIT:

SQL> EXIT :bv
Disconnected from Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
[oracle@oracle-21c-vagrant ~]$ echo $?
8

无法取消定义或删除 SQLPlus 会话中的绑定变量。 但是,退出 SQLPlus 时不会记住绑定变量。

有关自动显示值和对整个结果集使用 REFCURSOR 绑定变量的信息,请参阅 SQL*Plus 用户指南和参考手册中的关于使用绑定变量和 VARIABLE。

3.1 将替换变量分配给绑定变量

您可以将替换变量分配给绑定变量:

define mysubv = 123
variable mybndv number
execute :mybndv := &mysubv;
SQL> print mybndv

    MYBNDV
----------
       123

SQL*Plus 在替换“mysubv”的值后执行 PL/SQL 赋值语句。 如果尚未定义“mysubv”,系统会提示您输入值。

绑定变量可用于后续 SQL 或 PL/SQL 命令。

3.2 将绑定变量分配给替换变量

有时,使绑定变量的值可用于 SQL*Plus 命令(如 TTITLE 或 SPOOL)很有用。 例如,您可能想要调用一个返回字符串的 PL/SQL 函数并将该值用作 SQL Plus 假脱机文件名。 SPOOL 命令不理解绑定变量语法,因此需要先将绑定变量值分配给替换变量。

示例:

variable mybv varchar2(14)
begin
  /* ... */
  :mybv := 'report.log';
end;
/

column mybvcol new_value nv noprint
-- 使用查询将绑定变量的值传递给新的替换变量“nv”:
-- 以下命令不会产生输出
select :mybv mybvcol from dual;

SQL> define nv
DEFINE NV              = "report.log" (CHAR)

spool &nv
spool off

4 使用系统变量

大多数系统变量是用于控制 SQLPlus 系统行为的 SET 命令选项。 例如,要从 SQLPlus 设置输出行大小:

set linesize 60

每个系统变量的当前状态可以用 SHOW 命令显示。

SQL> show linesize
linesize 80

系统变量有时称为 SET 变量。

某些系统变量包含无法设置的值。 例如,RELEASE(SQL*Plus 版本的字符串表示)只能显示。

4.1 影响替代变量的系统变量

几个系统变量影响替代变量。

4.1.1 SET CONCAT

使用 SET CONCAT 定义将替换变量的名称与紧跟在变量名称后面的字母数字字符分开的字符。 默认情况下,它是单个句点 (.)。

例如,如果“mycity”被定义为“Melbourne”,那么以下命令是等价的:

SQL> spool &mycity.Australia.log
SQL> spool MelbourneAustralia.log

4.1.2 SET DEFINE

使用 SET DEFINE OFF 停止 SQLPlus 执行任何变量替换。 这使得 SQLPlus 将所有与号 (&) 视为文字字符,并防止 SQL*Plus 提示您输入值:

SQL> set define off
SQL> select 'B&W' MyHeading from dual;

MYH
---
B&W

默认的替换变量前缀是一个 & 符号。 SET DEFINE 命令可用于更改变量名前缀字符。 SET DEFINE ON 重新打开变量替换并将前缀字符重置为“&”

4.1.3 SET ESCAPE

使用 SET ESCAPE 防止孤立出现的“&”被视为替换变量前缀:

SQL> show escape
escape OFF
SQL> select 'B\\&W' MyHeading from dual;
Enter value for w: w
old   1: select 'B\\&W' MyHeading from dual
new   1: select 'B\\w' MyHeading from dual

MYH
---
B\\w

SQL> set escape \\
SQL> select 'B\\&W' MyHeading from dual;

MYH
---
B&W

任何没有转义字符的“&”都被视为变量前缀。

4.1.4 SET NULL

SET NULL 设置打印 NULL 数据值时 SQL*Plus 显示的文本。

如果 COLUMN NEW_VALUE(或 COLUMN OLD_VALUE)命令将变量与选定列相关联并且当前行包含 NULL 值,则替换变量可以采用 SET NULL 文本的值。 替换变量的类型在包含 NULL 时临时更改为 CHAR。

SQL> show null
null ""
SQL> select null from dual;

N
-


SQL> set null A
SQL> select null from dual;

N
-
A

4.1.5 SET NUMFORMAT

SET NUMFORMAT 和 SET NUMWIDTH 交互。 使用 SET NUMFORMAT 更改数值变量的默认显示格式。 使用 SET NUMFORMAT “” 删除格式。 当没有格式时,默认数字格式使用 SET NUMWIDTH 选项:

SQL> variable bv number = 123.45
SQL> show numformat
numformat ""
SQL> print bv

        BV
----------
    123.45

SQL> set numformat 0999.9
SQL> print bv

     BV
-------
 0123.5

SQL> set numformat 9.9EEEE
SQL> print bv

       BV
---------
  1.2E+02

SQL> set numformat ""
SQL> print bv

        BV
----------
    123.45

4.1.6 SET NUMWIDTH

只有当 SET NUMFORMAT 没有值时,SQL*Plus 才使用 SET NUMWIDTH 的值。 使用 SET NUMWIDTH 改变数值变量的显示宽度:

SQL> show numformat
numformat ""
SQL> show numwidth
numwidth 10
SQL> variable bv number = 123.45
SQL> print bv

        BV
----------
    123.45

SQL> set numwidth 20
SQL> print bv

                  BV
--------------------
              123.45
SQL> set numwidth 4
SQL> print bv

  BV
----
 123

SQL> set numwidth 2
SQL> print bv

BV
--
##

请注意,该值在字段宽度内是右对齐的,并且每个示例中前导空格的数量都会发生变化。

如果数字替换变量的格式或字段宽度对于值来说太小,SQL*Plus 会显示井号 (#)。

4.1.7 SET SQLPROMPT

在 SQL*Plus 10g 中,每次打印提示时都会动态替换提示中的替换变量。 与 TTITLE 中使用的变量一样,它们不应以 ‘&’ 为前缀,否则它们仅在执行 SET SQLPROMPT 命令时被替换一次。

在提示中使用预定义的替换变量 _USER 和 _CONNECT_IDENTIFIER 来提供当前用户名和数据库:

$ sqlplus hr/Welcome1@orclpdb1
SQL> set sqlprompt "_user'@'_connect_identifier:SQL> "
HR@orclpdb1:SQL> connect oe/Welcome1@orclpdb1
Connected.
OE@orclpdb1:SQL> connect / as sysdba
Connected.
SYS@ORCLCDB:SQL> define
DEFINE _DATE           = "23-JUN-22" (CHAR)
DEFINE _CONNECT_IDENTIFIER = "ORCLCDB" (CHAR)
DEFINE _USER           = "SYS" (CHAR)
DEFINE _PRIVILEGE      = "AS SYSDBA" (CHAR)
DEFINE _SQLPLUS_RELEASE = "2103000000" (CHAR)
DEFINE _EDITOR         = "vi" (CHAR)
DEFINE _O_VERSION      = "Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0" (CHAR)
DEFINE _O_RELEASE      = "2103000000" (CHAR)

每次打印提示时,SQL*Plus 都会检查每个单词以查看它是否是已定义的替换变量。 如果是,它将打印其值。 否则会逐字显示。 嵌套引号中的文本永远不会被替换。 出于性能原因,默认提示“SQL>”中的 SQL 一词永远不会被视为替换变量。

只有当 SET SQLPLUSCOMPATIBILITY 为 10.1 或更高版本时,提示中的变量才会被动态替换。 否则,对于 SQL*Plus 版本 9.2 和更早版本,在执行 SET SQLPROMPT 命令时,可以替换一次以“&”为前缀的变量。

4.1.8 SET VERIFY

使用 SET VERIFY 来控制 SQL*Plus 在替换变量值时是否回显新旧语句文本。 SET VERIFY 仅对 SQL 和 PL/SQL 语句中使用的替换变量有影响:

SQL> show verify
verify ON
SQL> select '&v' from dual;
Enter value for v: aaa
old   1: select '&v' from dual
new   1: select 'aaa' from dual

'AA
---
aaa

SQL> set verify off
SQL> select '&v' from dual;
Enter value for v: aaa

'AA
---
aaa

SQL*Plus 命令(如 SET , PROMPT, TTITLE)中使用的变量不会验证

以上是关于读书笔记:SQL 查询中的SQL*Plus 替换变量(DEFINE变量)和参数的主要内容,如果未能解决你的问题,请参考以下文章

1. SQL读书笔记——SQL中的连接

sql注入攻击与防御第二版读书笔记二——SQL注入测试

SQL条件逻辑——SQL读书笔记

《T-SQL查询》读书笔记Part 1.逻辑查询处理知多少

sql注入攻击与防御第二版读书笔记二——SQL盲注利用

SQL基础教程读书笔记-1