假設這種情況
create table mytable (a number, b number, c number)
insert into mytable values (10, 20, 30)
insert into mytable values (1, 2, 3)
,只有存在具有該名稱(否則就應該在從all_tab_columns
查詢所有者)一個表,查詢可以簡化這種方式:
SELECT 'select ' || LISTAGG(column_name, ', ') WITHIN GROUP (ORDER BY column_name) || ' from ' || table_name
FROM all_tab_columns
WHERE TABLE_NAME = 'MYTABLE'
AND DATA_TYPE <> 'VARCHAR2'
AND DATA_LENGTH < 2000
GROUP BY table_name
這會給:select A, B, C from MYTABLE
。
這裏的問題是,你不能簡單地運行一個返回可變數量列的語句;使用這一方法,可以構建一個xml:
SELECT xmltype(
DBMS_XMLGEN.getxml(
( SELECT 'select ' || LISTAGG(column_name, ', ') WITHIN GROUP (ORDER BY column_name) || ' from ' || table_name
FROM all_tab_columns
WHERE TABLE_NAME = 'MYTABLE'
AND DATA_TYPE <> 'VARCHAR2'
AND DATA_LENGTH < 2000
GROUP BY table_name)
)
)
FROM DUAL
<?xml version="1.0"?>
<ROWSET>
<ROW>
<A>10</A>
<B>20</B>
<C>30</C>
</ROW>
<ROW>
<A>1</A>
<B>2</B>
<C>3</C>
</ROW>
</ROWSET>
另一種方法可以使用一些PLSQL和動態SQL,與尤爾查詢稍加修改來連接領域,打造一個唯一的字符串的結果:
declare
type tTabResults is table of varchar2(1000);
vSQL varchar2(1000);
vTabResults tTabResults;
begin
SELECT 'select ' || LISTAGG(column_name, '|| '', '' ||') WITHIN GROUP (ORDER BY column_name) || ' from ' || table_name
into vSQL
FROM all_tab_columns
WHERE TABLE_NAME = 'MYTABLE'
AND DATA_TYPE <> 'VARCHAR2'
AND DATA_LENGTH < 2000
GROUP BY table_name;
--
execute immediate vSQL bulk collect into vTabResults;
--
for i in vTabResults.first .. vTabResults.last loop
dbms_output.put_line(vTabResults(i));
end loop;
end;
10, 20, 30
1, 2, 3
請注意,我過於簡單的問題,處理數字字符串和不使用任何轉換,通過簡單地打印您的表中的值,不管它們的類型;在真正的解決方案中,您應該處理可能的列類型並修改初始查詢以添加一些類型轉換。
感謝Aleksej--這絕對不像我希望的那麼簡單,而且由於我的動態代碼全都在R(我更容易理解),所以我最終做了2個查詢 - 第一個識別所有varchar2字段,然後用R來處理它們,並建立一個適當的最終查詢。我非常感謝你的時間 - 謝謝! – gruvn