上次介绍了动态SQL(字符串的SQL)的基本语法:
<动态SQL的执行基本语法>
EXECUTE IMMEDIATE 动态SQL;
但是有个问题,如果动态SQL是查询的时候,无论结果是一行还是多行,查询的结果怎么放到变量里边呢。
之前介绍的时候后,查询结果只有一行的时候,可以使用使用SELECT INTO语句,如果结果是多行的时候,则需要使用光标。
这一章,针对动态SQL只返回一行的结果进行说明。
首先,复习一下不要动态SQL的例子和语法:也就是SELECT INTO文。
以下的例子是在SQL*Plus等画面上显示指定员工的名字的处理。
SQL>SET SERVEROUT ON --SQLPLUS、SQLDeveloper的画面输出有效
SQL> DECLARE
2 V_ENAME EMP.ENAME%TYPE;–用于存储查询结果的变量
3 BEGIN
4 SELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO = 7934;
5 DBMS_OUTPUT.PUT_LINE(‘取得的员工名称=’|V_ENAME);
6 END;
7 /
取得的员工名称=MILLER
PL/SQL过程成功完成。
简单地解释如下:
●第2行……预先声明保存查询结果的变量
●第4行……用SELECT INTO语句将结果赋给该变量
●第5行……画面上显示变量的值
让我们猜想一下,如果动态查询SQL的结果和上边第4行一样,SELECT INTO文单引号引起来,做成字符串作为动态SQL,用EXECUTE IMMEDIATE来实行的话会怎么样呢?
SQL> DECLARE
2 V_ENAME EMP.ENAME%TYPE;
3 BEGIN
4 EXECUTE IMMEDIATE
5 ‘SELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO = 7934’;
6 DBMS_OUTPUT.PUT_LINE(‘取得的员工名称=’|V ENAME);
7 END;
8 /
DECLARE
*
行1发生错误。:
ORA-00905:没有关键词。
ORA-06612:行4
发生语法错误。
所以,把SELECT INTO文直接变成动态SQL的文字串是不行的。
出问题出在INTO语句,INTO句必须在动态SQL(字符串SQL)之后。
如下所示的话,就OK了:
SQL> DECLARE
2 V_ENAME EMP.ENAME%TYPE;
3 BEGIN
4 EXECUTE IMMEDIATE
5 ‘SELECT ENAME FROM EMP WHERE EMPNO = 7934’ INTO V_ENAME;
6 DBMS_OUTPUT.PUT_LINE(‘取得的员工名称=’|V_ENAME);
7 END;
8 /
取得的员工名称=MILLER
PL/SQL过程成功完成。
结果正常。
如上所述,查询用的动态SQL返回1行结果时的语法如下所示:
<查询用的动态SQL返回1行的基本语法>
EXECUTE IMMEDIATE 'SELECT 列1,列2,… ’ II INTO 变量1,变量2;
要点是INTO语句不包括在动态SQL(字符串SQL)的记述中,要和变量一起写在动态SQL字符串之外。
同理,要返回一行的多列时,可以使用变量也可以使用记录变量。
INTO 变量1,变量2
或
INTO 记录变量
和嵌入的SELECT INTO文一样呢。只是INTO句的地方不同。
假如检索结果是0行,或者多行的时候,会发生错误(分别为NO DATA FOUND例外、TOO MANY ROWS例外),发生错误时需要进行例外处理。
本次到此为止。