0

約 4,000 万台以上の車両のスナップショット データを含む多数のテーブル (約 40) があります。各スナップショット テーブルは特定の時点 (四半期の終わり) にあり、構造は同じです。

ほとんどの分析は単一のスナップショットに対して行われますが、すべてのスナップショットに対して一度に分析を実行する必要がある場合があります。たとえば、すべてのスナップショットからすべての Ford Focus 車を含む新しいテーブルを作成する必要がある場合があります。

これを実現するには、現在 2 つのオプションがあります
。a) FROM 句を変更するだけで、同じコードを何度も繰り返す長い、長い、長いバッチ ファイルを作成する
[欠点 - 書き込みに長い時間がかかり、ブロックの 1 つのコードは、他のすべてのブロックで手間のかかる変更を必要とします]
b) ビューを使用してすべてのテーブルを結合し、代わりにクエリを実行します
[欠点 - テーブルは別々のデータベース インスタンスに格納され、インデックスを作成できず、結果のビューは長さ 6 億レコード、幅 125 列のようなものなので、信じられないほど遅い]

したがって、私が知りたいのは、動的SQLを使用するか、SQLをループに入れてすべてのテーブルをスプールできるかどうかです。これは次のようになります。

for each *table* in TableList
INSERT INTO output_table
SELECT *table* as OriginTableName, Make, Model
FROM *table*
next *table* in TableList

これは可能ですか?これは、クライアントが必要なものを変更したときに元の SQL を更新することが非常に簡単になり、元のテーブルに既にあるすべてのインデックスを利用できることを意味します。

ポインタ、提案、またはヘルプをいただければ幸いです。

4

2 に答える 2

3

テーブル(名前付けパターンなど)を識別できる場合は、次のように簡単に言うことができます。

DECLARE @sql NVARCHAR(MAX);

SELECT @sql = N'';

SELECT @sql = @sql + 'INSERT output_table SELECT ''' + name + ''', Make, Model
    FROM dbo.' + QUOTENAME(name) + ';'
FROM sys.tables 
WHERE name LIKE 'pattern%';
-- or WHERE name IN ('t1', 't2', ... , 't40');

EXEC sp_executesql @sql;

dboこれは、それらがすべてスキーマ内にあることを前提としています。そうでない場合は、調整は簡単です...ただ交換dboしてください' + QUOTENAME(SCHEMA_NAME([schema_id])) + '...

于 2012-04-16T15:06:03.133 に答える
0

結局、私は2つの方法を使用
しました。別のフォーラムの誰かがsp_msforeachtableとすべてのテーブル名を含むテーブルを使用することを提案しました。彼らの提案は次のとおりです。

create table dbo.OutputTable (OriginTableName nvarchar(500), RecordCount INT)
create table dbo.TableList (Name nvarchar (500))

insert dbo.TableList 
        select '[dbo].[swap]'
union   select '[dbo].[products]'
union   select '[dbo].[structures]'
union   select '[dbo].[stagingdata]'

exec sp_msforeachtable @command1 = 'INSERT INTO dbo.OutputTable SELECT ''?'',    COUNT(*)     from ?'
,@whereand = 'and syso.object_id in (select object_id(Name) from dbo.TableList)'             

select * from dbo.OutputTable

これは一部のクエリでは完全に機能しますが、クエリ内でGROUP BY句を使用できないという事実に悩まされているようです(または、少なくとも、これを行う方法が見つかりませんでした)。

私が使用した最後の解決策は、テーブル名を含むルックアップテーブルで動的SQLを使用することでした。非常に単純な形式では、これは次のようになります。

DECLARE @TableName varchar(500)
DECLARE @curTable CURSOR
DECLARE @sql NVARCHAR(1000)

SET @curTable = CURSOR FOR 
SELECT [Name] FROM Vehicles_LookupTables.dbo.AllStockTableList

OPEN @curTable
FETCH NEXT
FROM @curTable INTO @TableName

WHILE @@FETCH_STATUS = 0
BEGIN

SET @sql = 'SELECT ''' +@TableName + ''', Make, sum(1) as Total FROM ' + @TableName + ' GROUP BY Make'
EXEC sp_executesql @sql

FETCH NEXT
FROM @curTable INTO @TableName

END
CLOSE @curTable
DEALLOCATE @curTable
于 2012-04-18T07:35:46.760 に答える