2011-12-26 92 views
4

在Oracle中,它可能返回cursor一个SQL查询中,使用cursor关键字,像这样:游标SQL查询

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)是否具有类似的功能?

回答

4

它被称为CURSOR EXPRESSION,它在明显的地方记录在Oracle SQL Reference中。 Find it here

至于你的第二个问题,PostgreSQL为匹配这个功能提供的最接近的东西是“标量子查询”。不过,正如@tbrugz所指出的,这些只返回一行和一列,所以它们不像光标表达式。 Read about them in the documentation here。 MySQL也有标量子查询,同样限于一列和一行。 Docs here。同样SQL Server和DB2(不是开源的,但为了完整性)。

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

+1

很好的参考,谢谢。但PostgreSQL的“标量子查询”与“游标表达式”不同:游标表达式可以返回多个行和列,而标量子查询只能返回一行(或无)和一列 – tbrugz 2011-12-27 12:49:26

2

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来创建必要的类型。