2017-09-04 83 views
0

我有一个要求来旋转从用户指定的特定表的列。 问题是从每个表中透视的列数是动态的。 所以下面的代码获取表中列的名称。在SQL中使用嵌套select时无法正常工作

SELECT DISTINCT 
       LISTAGG('''' || column_name || '''', ',') 
        WITHIN GROUP (ORDER BY column_name) AS temp_in_statement 
       FROM (SELECT DISTINCT column_name FROM all_tab_columns WHERE table_name = 'DIM_XYZ') 

上面的代码返回以下列格式中的列:

col1, col2 

我必须使用枢轴这一要求并且为了枢转列在下面的代码插上面的代码。

SELECT * FROM 
(
    SELECT table_name, column_name 
    FROM ALL_TAB_COLUMNS 
    WHERE 
     table_name = 'DIM_XYZ' 

) 
PIVOT 
(
    MIN(column_name) 
    FOR column_name IN ( 

-- values added manually 

'col1','col2' 

-- values added manually 


    ) 
) 
ORDER BY table_name; 

的代码工作正常,在这种情况下,但更换时 'COL1', 'COL2' 由SELECT语句检索的列名的系统引发以下错误:

ORA-00936: missing expression 
00936. 00000 - "missing expression" 
*Cause:  
*Action: 
Error at Line: 39 Column: 40 

CODE:

SELECT * FROM 
(
    SELECT table_name, column_name 
    FROM ALL_TAB_COLUMNS 
    WHERE 
     table_name = 'DIM_XYZ' 

) 
PIVOT 
(
    MIN(column_name) 
    FOR column_name IN ( 

--code below does not work when plugged in the statement above 
       SELECT DISTINCT 
       LISTAGG('''' || column_name || '''', ',') 
        WITHIN GROUP (ORDER BY column_name) AS temp_in_statement 
       FROM (SELECT DISTINCT column_name FROM all_tab_columns WHERE table_name = 'DIM_XYZ') 
--code above does not work 
    ) 
) 
ORDER BY table_name; 
---------------- 

你们有什么想法如何解决这个问题吗?

+2

listagg返回的STRING(单数)可能看起来像你在IN()中使用的东西,但事实是它不能以这种方式工作。您需要创建“动态sql”以将单个字符串“'col1','col2'”解释为一对字符串'col1','col2'。 –

回答

0

您不能直接将动态表达式作为输入添加到数据透视表, 您可以尝试这样的方式,即通过PL/SQL块检索变量中表的所有列,然后以某种方式将其传递给Oracle数据透视表功能期望的。

SET serveroutput ON; 


    DECLARE 
    sqlquery VARCHAR(32767); 
    cols VARCHAR2(32767); 
    BEGIN 

     SELECT listagg('''' || column_name || '''', ',') within 
     GROUP(
     ORDER BY column_name) 
     INTO cols 
     FROM 
     (SELECT DISTINCT column_name 
     FROM all_tab_columns 
     WHERE TABLE_NAME = 'TABLE_NAME') 
     ; 

     sqlquery := '  
    SELECT * FROM 
    (
     SELECT table_name, column_name 
     FROM ALL_TAB_COLUMNS 
     WHERE 
      table_name = ''TABLE_NAME'' 
    ) 
    PIVOT 
    (
     MIN(column_name) 
     FOR column_name IN ( 
      ''||cols||'' 
     ) 
    ) 
     ORDER BY table_name'; 

     DBMS_OUTPUT.PUT_LINE(sqlquery); 

     EXECUTE IMMEDIATE sqlquery; 

    END; 
    /