SQL查询中的游标

时间:2011-12-26 15:32:28

标签: sql oracle postgresql plsql cursor

在Oracle中,可以使用cursor关键字在SQL查询中返回cursor,如下所示:

select owner, table_name,
    cursor (select column_name 
        from all_tab_columns
        where owner = allt.owner 
        and table_name = allt.table_name) as columns
from all_tables allt

问题是:

  1. 有谁知道我在哪里可以找到这方面的文件?
  2. PortgreSQL(或任何其他开源DBMS)是否具有类似的功能?

2 个答案:

答案 0 :(得分:4)

它被称为CURSOR EXPRESSION,它显而易见地记录在Oracle SQL Reference中。 Find it here

至于你的第二个问题,PostgreSQL提供的与此功能最接近的是“标量子查询”。但是,正如@tbrugz指出的那样,这些只返回一行一列,因此它们与Cursor Expressions不太相似。 Read about them in the documentation here。 MySQL还有标量子查询,再次限制为一列和一行。 Docs here。同样是SQL Server和DB2(不是开源的,但为了完整性)。

这排除了所有明显的竞争者。因此,似乎不太可能任何其他DBMS提供我们从Oracle的游标表达式获得的锯齿状结果集。

答案 1 :(得分:4)

Postgres提供了游标表达式,但语法不如Oracle的方便。

首先,您需要为数组创建函数以进行refcursor转换:

create or replace function arr2crs(arr anyarray) returns refcursor as $$
declare crs refcursor;
begin
    open crs for select * from unnest(arr);
    return crs;
end;
$$ language plpgsql volatile;

现在让我们创建一些测试数据

create table dep as 
select 1 depid, 'Sales' depname
union all
select 2 depid, 'IT' depname;

create table emp as
select 1 empid, 1 depid, 'John' empname union all
select 2 empid, 1 depid, 'James' empname union all
select 3 empid, 2 depid, 'Rob';

您可以像这样查询

select 
    dep.*,
    arr2crs(array(
        select row(emp.*)::emp from emp 
        where emp.depid = dep.depid
    )) emps
from dep

在客户端处理这样的(Java)

public static List Rs2List(ResultSet rs) throws SQLException{
    List result = new ArrayList();
    ResultSetMetaData meta = rs.getMetaData();
    while(rs.next()){
        Map row = new HashMap();
        for (int i = 1; i <= meta.getColumnCount(); i++){
            Object o = rs.getObject(i);
            row.put(
                    meta.getColumnName(i),
                    (o instanceof ResultSet)?Rs2List((ResultSet)o):o);
        }
        result.add(row);
    }
    return result;
}

请注意,您必须显式地将行转换为特定类型。您可以使用CREATE TYPE创建必要的类型。