ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 谈谈“&”替换标志的一些特性

谈谈“&”替换标志的一些特性

原创 Linux操作系统 作者:realkid4 时间:2012-08-27 19:40:16 0 删除 编辑

 

在Oracle客户端,我们可以使用“&”来进行SQL语句指定内容的替换。当我们使用Sqlplus等基于Oracle客户端的工具时,“&”标号可以帮助我们实现一些功能。在本篇中,笔者准备探讨一下标号的基本特性和深层特点。

 

1、&标号基本使用

 

应该说,&标号的作用是在SQL语句执行过程中,如果Oracle发现中间使用了&标记,就终止执行,转而要求用户前段确认标记的变量取值,之后用输入的值进行数据替换。下面是在Sqlplus上的一个基本应用,我们在Oracle 10g下进行试验。

 

 

SQL> select * from v$version;

BANNER

----------------------------------------------------------------

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE    10.2.0.1.0      Production

TNS for 32-bit Windows: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 – Production

 

 

SQL> select empno, ename from emp where empno=&no;

输入 no 的值:  7902

原值    1: select empno, ename from emp where empno=&no

新值    1: select empno, ename from emp where empno=7902

 

     EMPNO ENAME

---------- ----------

      7902 FORD

 

 

当使用了&标号后,Oracle会提示用户输入这个取值,之后进行内容“全文替换”。注意,如果输入变量是一个字符串类型,要注意单引号’的使用特性如下:

 

 

SQL> select empno, ename from emp where job=&job;

输入 job 的值:  CLERK

原值    1: select empno, ename from emp where job=&job

新值    1: select empno, ename from emp where job=CLERK

select empno, ename from emp where job=CLERK

                                       *

第 1 行出现错误:

ORA-00904: "CLERK": 标识符无效

 

 

SQL> select empno, ename from emp where job='&job';

输入 job 的值:  CLERK

原值    1: select empno, ename from emp where job='&job'

新值    1: select empno, ename from emp where job='CLERK'

 

     EMPNO ENAME

---------- ----------

      7369 SMITH

      7876 ADAMS

 

SQL> select empno, ename from emp where job=&job;

输入 job 的值:  'CLERK'

原值    1: select empno, ename from emp where job=&job

新值    1: select empno, ename from emp where job='CLERK'

 

     EMPNO ENAME

---------- ----------

      7369 SMITH

      7876 ADAMS

 

 

在&与字符串的结合应用中,我们从上面的例子就可以看出端倪要点,如果SQL语句中的字符串列条件值没有使用单引号进行包括,那么输入的变量就一定要求带上’。如果字符串列条件值已经包括了单引号,就不需要输入了。

 

进一步想,我们可以认为,在&标号的情况下,就是一个简单的“内容替换”。

 

2、&标号的更进一步特性

 

其实,&标号绝不仅仅可以替换where后面的条件句。从语法本质看,这个标记可以替换SQL语句中更多的内容。

 

 

--1、替换where字句

SQL> select empno, ename from emp &state job='CLERK';

输入 state 的值:  where

原值    1: select empno, ename from emp &state job='CLERK'

新值    1: select empno, ename from emp where job='CLERK'

 

     EMPNO ENAME

---------- ----------

      7369 SMITH

      7876 ADAMS

 

--2、替换select字句

SQL> &state empno, ename from emp where job='CLERK';

SP2-0734: 未知的命令开头 "&state emp..." - 忽略了剩余的行。

SQL> select empno, ename &state emp where job='CLERK';

输入 state 的值:  from

原值    1: select empno, ename &state emp where job='CLERK'

新值    1: select empno, ename from emp where job='CLERK'

 

     EMPNO ENAME

---------- ----------

      7369 SMITH

      7876 ADAMS

 

--3、替换列名

SQL> select empno, &colum from emp where job='CLERK';

输入 colum 的值:  ename

原值    1: select empno, &colum from emp where job='CLERK'

新值    1: select empno, ename from emp where job='CLERK'

 

     EMPNO ENAME

---------- ----------

      7369 SMITH

      7876 ADAMS

 

--4、替换排序列

SQL> select empno from emp where job='CLERK' order by &m;

输入 m 的值:  empno

原值    1: select empno from emp where job='CLERK' order by &m

新值    1: select empno from emp where job='CLERK' order by empno

 

     EMPNO

----------

      7369

      7876

 

 

上面的四个语句试验,告诉我们&替代符可以做更多的事情,包括替代SQL语句中的关键字和列名。注意,这里除了SQL的第一个关键字不能做之外。

 

 

说到这里,顺便提一下“&&”标记。&&标记的作用就是记住变量的取值,在下一次使用的时候,就不需要强制进行替换了。

 

 

 

SQL> select empno, ename from emp where job='&&job';

输入 job 的值:  CLERK

原值    1: select empno, ename from emp where job='&&job'

新值    1: select empno, ename from emp where job='CLERK'

 

     EMPNO ENAME

---------- ----------

      7369 SMITH

      7876 ADAMS

      7900 JAMES

      7934 MILLER

 

SQL> select empno, ename from emp where job='&&job';

原值    1: select empno, ename from emp where job='&&job'

新值    1: select empno, ename from emp where job='CLERK'

 

     EMPNO ENAME

---------- ----------

      7369 SMITH

      7876 ADAMS

 

 

3、关于&标号和绑定变量

 

&标号和我们在实际开发中使用的绑定变量有一些相似之处,但是具有更大的灵活性。绑定变量(bind variable)只能进行where条件单值的替换,而且不能进行SQL关键字的替换。那么,我们怎么看待这两个特性呢?

 

笔者认为,&标号的特性具有更加强的灵活性,多种的替换功能是建立在Oracle客户端功能的基础之上。也就是说,我们替换的全文内容,是Oracle客户端给我们进行替换的。Oracle客户端进行替换之后,将替换完的SQL语句发送给Oracle服务端,Oracle优化器optimizer接受和处理解析的语句,都是替换完成的SQL语句。下面我们通过实验去证明:

 

 

SQL> alter system flush shared_pool;

System altered

 

 

SQL> select /*+ demo */count(*) from emp where deptno=&no;

输入 no 的值:  10

原值    1: select /*+ demo */count(*) from emp where deptno=&no

新值    1: select /*+ demo */count(*) from emp where deptno=10

 

  COUNT(*)

----------

         3

 

SQL> select /*+ demo */count(*) from emp where deptno=&no;

输入 no 的值:  40

原值    1: select /*+ demo */count(*) from emp where deptno=&no

新值    1: select /*+ demo */count(*) from emp where deptno=40

 

  COUNT(*)

----------

         0

 

此时,我们检查Shared Pool中的游标,如下:

 

 

SQL> col sql_text for a52;

SQL> select sql_text, sql_id from v$sqlarea where sql_text like 'select /*+ demo */count(*)%';

 

SQL_TEXT                                             SQL_ID

---------------------------------------------------- -------------

select /*+ demo */count(*) from emp where deptno=40  0rtgwj49d4yu2

select /*+ demo */count(*) from emp where deptno=10  19a1vdf75kucg

 

 

可见,我们在shared pool中找到两条的父游标记录,说明在服务端接受的时候,就是已经替换完的取值。进一步说,&号在服务端是不能够起到bind variable的共享父子游标的作用。

 

而bind variable是可以起到这个作用的。

 

 

SQL> var x number;

SQL> exec :x := 10;

 

PL/SQL 过程已成功完成。

 

SQL> select /*+ demo */count(*) from emp where deptno=:x;

 

  COUNT(*)

----------

         3

 

SQL> exec :x := 20;

 

PL/SQL 过程已成功完成。

 

SQL> select /*+ demo */count(*) from emp where deptno=:x;

 

  COUNT(*)

----------

         5

 

SQL> select sql_text, sql_id from v$sqlarea where sql_text like 'select /*+ demo */count(*)%';

 

SQL_TEXT                                             SQL_ID

---------------------------------------------------- -------------

select /*+ demo */count(*) from emp where deptno=:x  888j35kfajnuj

 

 

 

4、结论

 

&是我们在Oracle客户端可以支持的一种工具类型。在我们进行调试程序的时候,可以提供一定程度的帮助。但是笔者认为,在实际开发工作中,意义不是很大。&标记符的出现,可能是作为某种历史时期的产品方向。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17203031/viewspace-742014/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
求道~

注册时间:2010-11-30

  • 博文量
    545
  • 访问量
    8041327