2016-10-11 115 views
0

我正在考慮這一點。我對動態SQL相當陌生,所以我可能不會問Google正確的問題,但這是我正在嘗試做的事情......我使用動態SQL進行查詢。當我運行該查詢時,它會產生多行。所有這些行(大約30)組成一個單一的聯合查詢。我可以複製所有這些行並粘貼到一個新的查詢並運行 - 工作正常,但我需要做的是在單個查詢中運行這一切。我查了一下使用execute immediate和fetch的例子,但我似乎無法讓他們真正吐出數據......他們最終只是說「執行成功」,但實際上並沒有產生任何結果行。下面的SQL的結果列名是「qry_txt」 - 而不是以面值生成它,我想將它作爲查詢來執行。再一次,我可能沒有說清楚,但我基本上試圖將2個查詢(涉及手動複製/粘貼步驟)轉換爲單個查詢。希望這是有道理...爲動態原生SQL查詢的結果執行結果行

這裏是我的SQL:

Select CASE when 
lead(ROWNUM) over(order by ROWNUM) is null then 
'SELECT '||''''||T.TABLE_NAME||''''||' as TABLE_NAME,'||''''||T.COLUMN_NAME||''''||' as COLUMN_NAME, cast('|| T.COLUMN_NAME ||' as 
varchar2(100)) as SAMPLE_DATA || 
from rpt.'||T.TABLE_NAME ||' where '||T.COLUMN_NAME||' is not null and ROWNUM=1;' 
else 
'SELECT '||''''||T.TABLE_NAME||''''||' as TABLE_NAME,'||''''||T.COLUMN_NAME||''''||' as COLUMN_NAME, cast('|| T.COLUMN_NAME ||' as 
varchar2(100)) as SAMPLE_DATA from rpt.'||T.TABLE_NAME ||' where '||T.COLUMN_NAME||' is not null and ROWNUM=1 union ' end as qry_txt 
from all_tab_columns t where T.OWNER='rpt' and T.DATA_TYPE != 'BLOB' and T.DATA_TYPE != 'LONG' and T.TABLE_NAME = 'NME_DMN' 
ORDER BY ROWNUM asc; 
+1

你的目標是打開一個返回給調用者的遊標,然後提取行(這很容易,可以通過'execute immediate'完成)。或者你是否需要一個可以讀取所有行的PL/SQL塊(這更難,幾乎可以肯定涉及使用'dbms_sql'包的更復雜的路徑)? –

+0

從我一直在閱讀的內容來看,打開光標聽起來像是正確的軌道。是的,我需要獲取所有的行,就像我正在運行一個直接選擇查詢一樣。只要我結束了行,我對任何一種方法都是開放的,但是最簡單的方法是能夠重複這種技術; ...) – user3108489

+1

如果你想打開一個返回的遊標對於調用者來說,調用者不能是一個獲取數據的PL/SQL塊(如果你使用12.1,而且你願意變得更加複雜,它可能會發生)。你可以返回一個遊標到'SQL * Plus'或一個C#應用程序,然後可以獲取數據。如果你想擁有一個可以獲取所有行的PL/SQL塊,你將需要更復雜的'dbms_sql'路徑。我不確定其中哪些實際適用於您。 –

回答

1

你不能寫在SQL動態查詢。你需要使用PLSQL塊來實現這一點。請看你如何做到這一點。 PS:代碼未經測試。

declare 
    var1 <decalration same of column in select list> ; 
    var2 <decalration same of column in select list> ; 
    var3 <decalration same of column in select list> ; 
    .... 
    varn ; 

begin 
    for i in (SELECT LEAD (ROWNUM) OVER (ORDER BY ROWNUM) COl1 
       FROM all_tab_columns t 
       WHERE  T.OWNER = 'rpt' 
        AND T.DATA_TYPE != 'BLOB' 
        AND T.DATA_TYPE != 'LONG' 
        AND T.TABLE_NAME = 'NME_DMN' 
      ORDER BY ROWNUM ASC) 

    Loop 

    If i.col1 IS NULL Then 

    execute immediate 'SELECT ' 
          || '''' 
          || T.TABLE_NAME 
          || '''' 
          || ' as TABLE_NAME,' 
          || '''' 
          || T.COLUMN_NAME 
          || '''' 
          || ' as COLUMN_NAME, cast(' 
          || T.COLUMN_NAME 
          || ' as 
           varchar2(100)) as SAMPLE_DATA || 
          from rpt.' 
          || T.TABLE_NAME 
          || ' where ' 
          || T.COLUMN_NAME 
          || ' is not null and ROWNUM=1' into var1 , var2 ,var3 ....varn; 

    Else 

     execute immediate 'SELECT ' 
          || '''' 
          || T.TABLE_NAME 
          || '''' 
          || ' as TABLE_NAME,' 
          || '''' 
          || T.COLUMN_NAME 
          || '''' 
          || ' as COLUMN_NAME, cast(' 
          || T.COLUMN_NAME 
          || ' as 
      varchar2(100)) as SAMPLE_DATA from rpt.' 
          || T.TABLE_NAME 
          || ' where ' 
          || T.COLUMN_NAME 
          || ' is not null and ROWNUM=1' into var1 , var2 ,var3 ....varn; 

    end if; 

    End Loop;    

    exception 
    when others then 
    dbms_output.put_lin(sqlcode ||'--'||sqlerrm); 

End; 
+0

我跑這個,並收到此錯誤:查找錯誤 ORA-06550:第2行,第8列:PLS-00103:當期待以下之一時遇到符號「<」:常量異常表long double ref char time timestamp interval date二進制國家字符nchar – user3108489

+1

我只是幫你身體。它不是一個實際的工作代碼。我只是以你可以工作的方式幫助你。我的評論也是內聯的。只需按照語法和相應地修改您的代碼 – XING

+0

恐怕我不知道您的技術或我目前正在接受的錯誤,以使其適用於我。仍在嘗試... – user3108489