Sql 我可以将一个查询的输出用作另一个select子句中的列吗

Sql 我可以将一个查询的输出用作另一个select子句中的列吗,sql,oracle,plsql,listagg,Sql,Oracle,Plsql,Listagg,我有一个查询,它将列名作为输出。例如 select Column_Name from Table1; -- Q1 此查询将column1、column2作为输出 现在我想在另一个查询中使用这个输出 Select Column1, column2 from Table2; --Q2 但在第二个查询中,我希望动态地从第一个查询中获取column1和column2 我需要下面这样的东西 Select (Select Column_name from Table 1) from Table2. 我

我有一个查询,它将列名作为输出。例如

select Column_Name from Table1; -- Q1
此查询将
column1、column2
作为输出

现在我想在另一个查询中使用这个输出

Select Column1, column2 from Table2; --Q2
但在第二个查询中,我希望动态地从第一个查询中获取column1和column2

我需要下面这样的东西

Select (Select Column_name from Table 1) from Table2.

我希望使用查询输出。(我不能使用PL/SQL函数)

据我所知,这是动态SQL,意思是PL/SQL,意思是你运气不好。

据我所知,这是动态SQL,意思是PL/SQL,意思是你运气不好。

不需要在另一个表中重复保存这些列
SYS\u REFCURSOR
可以与函数中的动态查询一起使用,如

CREATE OR REPLACE FUNCTION Get_Tab2_Results RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_tab       VARCHAR2(32) := 'TABLE2';  
BEGIN
     
  v_sql :='SELECT * FROM '||v_tab;
  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;
/
然后运行以下代码:

VAR rc REFCURSOR
EXEC :rc := Get_Tab2_Results;
PRINT rc
从SQL Developer的命令行,以查看预期的结果集

如果需要某些特定列,请在Select语句中列出它们的
column\u id
值,如下代码块所示

CREATE OR REPLACE FUNCTION Get_Tab2_Results RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols      VARCHAR2(32767);
  v_tab       VARCHAR2(32) := 'TABLE2';  
BEGIN
  SELECT DISTINCT LISTAGG(c.column_name,',') WITHIN GROUP (ORDER BY c.column_name)
    INTO v_cols
    FROM user_tab_cols c
   WHERE c.table_name = v_tab
     AND c.column_id IN (1,4);  
     
  v_sql :='SELECT '||v_cols||' FROM '||v_tab;
  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;
/
如果确实需要从另一个表(
table1
)中获取列的连接字符串,则使用

CREATE OR REPLACE FUNCTION Get_Tab2_Results RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols      VARCHAR2(32767);
  v_tab       VARCHAR2(32) := 'TABLE2';  
BEGIN
  SELECT column_name
    INTO v_cols
    FROM table1;  
     
  v_sql :='SELECT '||v_cols||' FROM '||v_tab;
  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;
/

其中,对
table1
的查询只返回一行,如前所述。

无需在另一个表中冗余保留这些列
SYS\u REFCURSOR
可以与函数中的动态查询一起使用,如

CREATE OR REPLACE FUNCTION Get_Tab2_Results RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_tab       VARCHAR2(32) := 'TABLE2';  
BEGIN
     
  v_sql :='SELECT * FROM '||v_tab;
  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;
/
然后运行以下代码:

VAR rc REFCURSOR
EXEC :rc := Get_Tab2_Results;
PRINT rc
从SQL Developer的命令行,以查看预期的结果集

如果需要某些特定列,请在Select语句中列出它们的
column\u id
值,如下代码块所示

CREATE OR REPLACE FUNCTION Get_Tab2_Results RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols      VARCHAR2(32767);
  v_tab       VARCHAR2(32) := 'TABLE2';  
BEGIN
  SELECT DISTINCT LISTAGG(c.column_name,',') WITHIN GROUP (ORDER BY c.column_name)
    INTO v_cols
    FROM user_tab_cols c
   WHERE c.table_name = v_tab
     AND c.column_id IN (1,4);  
     
  v_sql :='SELECT '||v_cols||' FROM '||v_tab;
  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;
/
如果确实需要从另一个表(
table1
)中获取列的连接字符串,则使用

CREATE OR REPLACE FUNCTION Get_Tab2_Results RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols      VARCHAR2(32767);
  v_tab       VARCHAR2(32) := 'TABLE2';  
BEGIN
  SELECT column_name
    INTO v_cols
    FROM table1;  
     
  v_sql :='SELECT '||v_cols||' FROM '||v_tab;
  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;
/

如前所述,
表1的查询只返回一行。

是,可以根据另一个查询的结果运行查询。尽管下面的查询是一个纯SQL语句,它返回任何SQL客户机都能理解的常规行和列,但您必须创建自定义PL/SQL对象才能实现该功能

查询:

select * from table(method4.dynamic_query(
    q'[
        select 'select ' || listagg(column_name, ',') || ' from table2' sql from table1
    ]'
));
结果:

COLUMN1  COLUMN2
-------  -------
      1        2
示例架构:

create table table1 as
select 'COLUMN1' column_name from dual union all
select 'COLUMN2' column_name from dual;

create table table2 as select 1 column1, 2 column2, 3 column3 from dual;
上面的代码使用我的开源程序。虽然程序使用了大量的PL/SQL,但应用程序并不知道这一点,并且会将您的查询视为无聊的SQL语句


除了创建自定义PL/SQL程序外,在SQL中获取动态SQL的唯一方法是使用包
DBMS\u XMLGEN.GETXML
,如中所示[https://stackoverflow.com/q/57174679/409172](这是答案)。但是,该技术只支持静态列数,因此您需要设置最大列数或将多个列转换为多行。

是的,可以根据另一个查询的结果运行查询。尽管下面的查询是一个纯SQL语句,它返回任何SQL客户机都能理解的常规行和列,但您必须创建自定义PL/SQL对象才能实现该功能

查询:

select * from table(method4.dynamic_query(
    q'[
        select 'select ' || listagg(column_name, ',') || ' from table2' sql from table1
    ]'
));
结果:

COLUMN1  COLUMN2
-------  -------
      1        2
示例架构:

create table table1 as
select 'COLUMN1' column_name from dual union all
select 'COLUMN2' column_name from dual;

create table table2 as select 1 column1, 2 column2, 3 column3 from dual;
上面的代码使用我的开源程序。虽然程序使用了大量的PL/SQL,但应用程序并不知道这一点,并且会将您的查询视为无聊的SQL语句


除了创建自定义PL/SQL程序外,在SQL中获取动态SQL的唯一方法是使用包
DBMS\u XMLGEN.GETXML
,如中所示[https://stackoverflow.com/q/57174679/409172](这是答案)。但是,该技术只支持静态列数,因此您需要设置最大列数或将多列转换为多行。

使用ListAgg函数,我可以获得逗号分隔的值,但输出在括号中。因此,它不会将其理解为列。正如我所说的:您需要动态SQL,它可以在PL/SQL过程中使用。由于您不能使用PL/SQL,因此对此您无能为力。使用ListAgg函数,我可以获得逗号分隔的值,但输出是用括号括起来的。因此,它不会将其理解为列。正如我所说的:您需要动态SQL,它可以在PL/SQL过程中使用。由于您不能使用PL/SQL,因此对此您无能为力。谢谢您的回复。这里的问题是我不能使用PL/SQL块。我只能使用普通查询。我需要在另一个不理解pl/sql的应用程序中使用此查询。好的,我已经添加了这个案例,欢迎@ManishGoyal。谢谢您的回复。这里的问题是我不能使用PL/SQL块。我只能使用普通查询。我需要在另一个不懂pl/sql的应用程序中使用此查询。好吧,我已经添加了一个案例,欢迎@ManishGoyal。您真的不允许使用任何pl/sql对象,还是只受只懂sql的应用程序的限制?您使用的数据库版本是什么?如果允许您创建PL/SQL函数,有几种方法可以创建PL/SQL对象,这些对象看起来像一个常规表,可以在SQL上下文中使用。Hi Jon,是的,我们受到一个只理解SQL的应用程序的限制。Hi@ManishGoyal,这个应用程序如何执行查询?它是从应用程序传递来执行的某种准备好的语句吗?如果是这样,您可以尝试“模拟”执行立即/稍微昂贵的一个/第一个查询数据库,并在组(按1排序)中选择“select”| | listagg(列名称),”)|从表1的“表2”中选择“select”。然后将结果作为secont请求传递给数据库。您真的不允许使用任何PL/SQL对象,还是只受只懂SQL的应用程序的限制?您使用的数据库版本是什么?如果允许您创建PL/SQL函数,有几种方法可以创建PL/SQL对象,这些对象看起来像一个常规表,可以在SQL上下文中使用。Hi Jon,是的,我们受到只理解SQL的应用程序的限制。Hi@ManishGoyal,