将具有不同 returns 的两个 select 语句合并到一个视图中
Combining two select statements with differing returns into a single view
我有一个 T-SQL 存储过程,我正试图将其转换为 PL-SQL。
目前,此存储过程执行一个很长的 select 查询,紧接着执行一个更短的 select 查询。看起来是这样的:
CREATE PROCEDURE proc_name
@userid int,
AS
select (about twenty fields)
from (about five tables)
where something = @userid
select (about five fields)
from (about three tables)
where something = @userid
当我看到它时,我的第一个想法是将其转换为视图,因为它只是在执行 select 语句。但是,考虑到两个 select 正在完成,这实际上可能吗?可以使用存储过程吗?我已经尝试过这个想法,但据我所知,我需要创建两个 sys_refcursors,这意味着调用代码需要以不同方式处理两个查询 returns,目前不必这样做。
所以问题是:如何将这种类型的程序从 T-SQL 转换为 PL-SQL?
您不能简单地在 PL/SQL
中进行 select
查询。它会抛出 PLS-00428: an INTO clause is expected in this SELECT statement
错误。
要return 多行,您可以使用CURSOR
。在你的情况下,有多个语句,你可以有两个 REFCURSOR
.
例如,
SQL> variable v_ref1 refcursor
SQL> variable v_ref2 refcursor
SQL>
SQL> DECLARE
2 v_ref1 sys_refcursor;
3 v_ref2 sys_refcursor;
4 BEGIN
5 OPEN :v_ref1 FOR SELECT empno, ename
6 FROM emp ORDER BY empno
7 FETCH FIRST 5 ROWS ONLY;
8 OPEN :v_ref2 FOR SELECT empno, ename
9 FROM emp ORDER BY empno DESC
10 FETCH FIRST 5 ROWS ONLY;
11 END;
12 /
PL/SQL procedure successfully completed.
SQL> print v_ref1
EMPNO ENAME
---------- ----------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
SQL> print v_ref2
EMPNO ENAME
---------- ----------
7934 MILLER
7902 FORD
7900 JAMES
7876 ADAMS
7844 TURNER
SQL>
如果您想合并多个 SELECT
语句的结果集,您可以使用 UNION
运算符并将其放在单个 REFCURSOR
中。假设列数据类型匹配并且顺序正确。这只是一个例子,
SQL> variable v_ref refcursor
SQL>
SQL> DECLARE
2 v_ref sys_refcursor;
3 BEGIN
4 OPEN :v_ref FOR
5 SELECT empno, DEPTNO FROM emp WHERE ROWNUM <=5
6 UNION ALL
7 SELECT empno, DEPTNO FROM EMP WHERE ROWNUM <=5;
8 END;
9 /
PL/SQL procedure successfully completed.
SQL> print v_ref
EMPNO DEPTNO
---------- ----------
7369 20
7499 30
7521 30
7566 20
7654 30
7369 20
7499 30
7521 30
7566 20
7654 30
10 rows selected.
SQL>
您可以通过将第一个 select 查询中不存在的字段设为 NULL,使第二个 select 查询也有 20 列。但这取决于你是否同意。
我有一个 T-SQL 存储过程,我正试图将其转换为 PL-SQL。
目前,此存储过程执行一个很长的 select 查询,紧接着执行一个更短的 select 查询。看起来是这样的:
CREATE PROCEDURE proc_name
@userid int,
AS
select (about twenty fields)
from (about five tables)
where something = @userid
select (about five fields)
from (about three tables)
where something = @userid
当我看到它时,我的第一个想法是将其转换为视图,因为它只是在执行 select 语句。但是,考虑到两个 select 正在完成,这实际上可能吗?可以使用存储过程吗?我已经尝试过这个想法,但据我所知,我需要创建两个 sys_refcursors,这意味着调用代码需要以不同方式处理两个查询 returns,目前不必这样做。
所以问题是:如何将这种类型的程序从 T-SQL 转换为 PL-SQL?
您不能简单地在 PL/SQL
中进行 select
查询。它会抛出 PLS-00428: an INTO clause is expected in this SELECT statement
错误。
要return 多行,您可以使用CURSOR
。在你的情况下,有多个语句,你可以有两个 REFCURSOR
.
例如,
SQL> variable v_ref1 refcursor
SQL> variable v_ref2 refcursor
SQL>
SQL> DECLARE
2 v_ref1 sys_refcursor;
3 v_ref2 sys_refcursor;
4 BEGIN
5 OPEN :v_ref1 FOR SELECT empno, ename
6 FROM emp ORDER BY empno
7 FETCH FIRST 5 ROWS ONLY;
8 OPEN :v_ref2 FOR SELECT empno, ename
9 FROM emp ORDER BY empno DESC
10 FETCH FIRST 5 ROWS ONLY;
11 END;
12 /
PL/SQL procedure successfully completed.
SQL> print v_ref1
EMPNO ENAME
---------- ----------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
SQL> print v_ref2
EMPNO ENAME
---------- ----------
7934 MILLER
7902 FORD
7900 JAMES
7876 ADAMS
7844 TURNER
SQL>
如果您想合并多个 SELECT
语句的结果集,您可以使用 UNION
运算符并将其放在单个 REFCURSOR
中。假设列数据类型匹配并且顺序正确。这只是一个例子,
SQL> variable v_ref refcursor
SQL>
SQL> DECLARE
2 v_ref sys_refcursor;
3 BEGIN
4 OPEN :v_ref FOR
5 SELECT empno, DEPTNO FROM emp WHERE ROWNUM <=5
6 UNION ALL
7 SELECT empno, DEPTNO FROM EMP WHERE ROWNUM <=5;
8 END;
9 /
PL/SQL procedure successfully completed.
SQL> print v_ref
EMPNO DEPTNO
---------- ----------
7369 20
7499 30
7521 30
7566 20
7654 30
7369 20
7499 30
7521 30
7566 20
7654 30
10 rows selected.
SQL>
您可以通过将第一个 select 查询中不存在的字段设为 NULL,使第二个 select 查询也有 20 列。但这取决于你是否同意。