2

Oracle 9 データベースに一連の履歴テーブルがあります。History_table_00 には前月のデータが含まれ、History_table_01 には前の月が含まれ、History_table_02 にはその前の月が含まれます。来月、History_table_02 の名前が history_table_03 に自動的に変更され、history_table_01 の名前が history_table_02 に変更され、history_table_00 の名前が history_table_01 に変更され、新しい history_table_00 が作成されて最新の履歴が収集されます (意味があるといいのですが)。

とにかく、すべての履歴テーブルを動的に選択する select ステートメントを作成する必要があります。これらはすべて同じ名前を共有し、連番を追加するだけでテーブル名を見つけることができるため、これがあまり複雑にならないことを願っています。

select table_name from all_tables where table_name like 'HISTORY_TABLE_%';

各テーブルの標準クエリは次のようになります。

select id, name, data_column_1, data_column_2 from history_table_%;

毎月行って新しいテーブルを追加しなくても、常にすべての履歴テーブルから選択する SQL ステートメントを作成するという目標を達成するには、どうすればよいでしょうか? 皆さんが提供できるものに感謝します。

4

4 に答える 4

2

refカーソルを使用できますが、お勧めしません。こんなふうになります

create table tab_01 as select 1 a , 10 b from dual;
create table tab_02 as select 2 a , 20 b from dual;
create table tab_03 as select 3 a , 30 b from dual;

create or replace function get_all_history
return sys_refcursor
as
   r sys_refcursor;
   stmt varchar2(32000);
   cursor c_tables is
           select  table_name
           from    user_tables
           where   table_name like 'TAB_%';
begin
   for x in c_tables loop
           stmt := stmt || ' select * from ' || x.table_name ||' union all';
   end loop;
   stmt := substr(stmt , 1 , length(stmt) - length('union all'));
   open r for stmt;
   return r;
end;
/

SQL> select get_all_history() from dual;

GET_ALL_HISTORY()
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

         A          B
---------- ----------
         1         10
         2         20
         3         30
于 2013-07-02T15:12:22.210 に答える
2

を使用してすべての履歴テーブルから選択するビューを定義しunion all 、テーブルの名前が変更されるたびにビューも変更することをお勧めします。

create OR replace view history_data as 
SELECT id, name, data_column_1, data_column_2  FROM history_table_01
union all 
SELECT id, name, data_column_1, data_column_2  FROM history_table_02
union all 
SELECT id, name, data_column_1, data_column_2  FROM history_table_03
;

次に、SELECT * FROM history_data; を単純化できます。

次のステートメントを使用して、ビューを動的に構築できます。

SELECT 'SELECT id, name, data_column_1, data_column_2  FROM ' || table_name || ' union all ' 
FROM  user_tables 
WHERE table_name like 'HISTORY_TABLE_%'     
于 2013-07-02T15:24:01.633 に答える
0

考えられる解決策:

    CREATE OR REPLACE PROCEDURE GET_HIST_DETAILS IS

DECLARE

QUERY_STATEMENT VARCHAR2(4000) := NULL;
CNT             NUMBER;

BEGIN 

select COUNT(table_name) INTO CNT from all_tables where table_name like 'HISTORY_TABLE_%';

FOR loop_counter IN 1..CNT

LOOP

 IF LOOP_COUNTER <> CNT THEN
 {  
 QUERY_STATEMENT := QUERY_STATEMENT || 'select id, name, data_column_1, data_column_2 from history_table_0' || loop_counter || ' UNION';
 }
 ELSE
 {
   QUERY_STATEMENT := QUERY_STATEMENT || 'select id, name, data_column_1, data_column_2 from history_table_0' || loop_counter ;
 } 

EXECUTE_IMMEDIATE QUERY_STATEMENT;

END LOOP;


END GET_DETAILS;

PS:私は Oracle をインストールしていないので、構文エラーについてテストしていません。

于 2013-07-02T19:03:39.490 に答える
0

データベースに存在するテーブルごとに大きなクエリを作成する動的 SQL ステートメントを実行することをお勧めします。次の SQL クエリを試してください。(書式設定をお許しください。ここで改行を行う方法がわかりません)

DECLARE @table VARCHAR(255)
      , @objectID INT
      , @selectQuery VARCHAR(MAX)

SELECT @objectID = MIN(object_id)
  FROM sys.tables
 WHERE name LIKE 'history_table_%'

WHILE @objectID IS NOT NULL
BEGIN
  SELECT @table = name
    FROM sys.tables
   WHERE object_id = @objectID
   ORDER BY object_id

  SELECT @selectQuery = ISNULL(@selectQuery + ' UNION ALL ', '') + 'select id, name, data_column_1, data_column_2 FROM ' + @table

  SELECT @objectID = MIN(object_id)
    FROM sys.tables
   WHERE name LIKE 'tblt%'
     AND object_id > @objectID
END 

SELECT @selectQuery
--EXEC (@selectQuery)
于 2013-07-02T15:09:56.493 に答える