SELECT INTO
SELECT INTO 语句是 SQL SELECT 命令的 SPL 变体,区别是:
- 该 SELECT INTO 旨在将结果赋给变量或记录,然后它们可以在 SPL 程序语句中使用。
- SELECT INTO 的可访问结果集最多是一行。
除了上述的以外,SELECT 命令的所有子句(如 WHERE、ORDER BY、GROUP BY、HAVING 等)都对 SELECT INTO 有效。以下是 SELECT INTO 的两个变体。
SELECT select_expressions INTO target FROM ...;
target 是简单变量的逗号分隔列表。select_expressions 和语句的其余部分与 SELECT 命令相同。所选值必须在数据类型、数量和顺序方面与目标的结构完全匹配,否则会发生运行时错误。
SELECT * INTO record FROM table ...;
record 是以前声明的记录变量。
如果查询返回零行,会将 null 值赋给目标。如果查询返回多行,会将第一行赋给目标并丢弃其余部分。(请注意,“第一行”定义不明确,除非您使用 ORDER BY。)
有一个使用 BULK COLLECT 子句的 SELECT INTO 变体,它允许包含返回到集合中的多行的结果集。
您可以在 EXCEPTION 块中使用 WHEN NO_DATA_FOUND 子句来确定赋值是否成功(也就是说,查询至少返回了一行)。
此版本的 emp_sal_query 存储过程使用将结果集返回到记录中的 SELECT INTO 变体。还请注意,添加了包含 WHEN NO_DATA_FOUND 条件表达式的 EXCEPTION 块。
CREATE OR REPLACE PROCEDURE emp_sal_query (
p_empno IN emp.empno%TYPE
)
IS
r_emp emp%ROWTYPE;
v_avgsal emp.sal%TYPE;
BEGIN
SELECT * INTO r_emp
FROM emp WHERE empno = p_empno;
DBMS_OUTPUT.PUT_LINE('Employee # : ' || p_empno);
DBMS_OUTPUT.PUT_LINE('Name : ' || r_emp.ename);
DBMS_OUTPUT.PUT_LINE('Job : ' || r_emp.job);
DBMS_OUTPUT.PUT_LINE('Hire Date : ' || r_emp.hiredate);
DBMS_OUTPUT.PUT_LINE('Salary : ' || r_emp.sal);
DBMS_OUTPUT.PUT_LINE('Dept # : ' || r_emp.deptno);
SELECT AVG(sal) INTO v_avgsal
FROM emp WHERE deptno = r_emp.deptno;
IF r_emp.sal > v_avgsal THEN
DBMS_OUTPUT.PUT_LINE('Employee''s salary is more than the '
|| 'department average of ' || v_avgsal);
ELSE
DBMS_OUTPUT.PUT_LINE('Employee''s salary does not exceed the '
|| 'department average of ' || v_avgsal);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Employee # ' || p_empno || ' not found');
END;
如果使用不存在的员工编号执行查询,结果显示如下。
EXEC emp_sal_query(0);
Employee # 0 not found
具有 SELECT INTO 的 EXCEPTION 部分中使用的另一个条件子句是 TOO_MANY_ROWS 异常。如果 SELECT INTO 语句选择了多行,则 SPL 会引发异常。
在执行以下块时,会引发 TOO_MANY_ROWS 异常,因为指定的部门中有许多员工。
DECLARE
v_ename emp.ename%TYPE;
BEGIN
SELECT ename INTO v_ename FROM emp WHERE deptno = 20 ORDER BY ename;
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('More than one employee found');
DBMS_OUTPUT.PUT_LINE('First employee returned is ' || v_ename);
END;
More than one employee found
First employee returned is ADAMS
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。
评论