2017-12-05 23 views
0

私は、存在しないテーブルにいくつかの挿入を実行するより適切な方法を探しています。 以前にテーブルを作成することは、選択した列のデータ型がわからないため、簡単にはできません。 「insert with create」はそうするでしょうが、私はそういうものはないと思います。テーブル作成で挿入するには?

これを選択して挿入するよりも良い方法はありますか?

この例では、問題に非常にストライプされた「悪い」方法を示します。

set nocount on 

declare 
    @name sysname = '', 
    @i int = 0, 
    @sql nvarchar(4000) = '' 

declare test cursor for 
    select top 10 a.name from sys.tables a inner join sys.columns b on a.object_id = b.object_id --and b.name = 'description' 
open test 
fetch next from test into @name 
while (@@FETCH_STATUS <> -1) 
begin 

    if @i = 0 begin 


     set @sql = 'select distinct top 10 description into #t1 from ' + @name + '' 
     select @sql 
     -- exec sp_executesql @sql 

    end 
    else begin 

     set @sql = 'insert #t1 select distinct top 10 description into #t1 from ' + @name + '' 
     select @sql 
     -- exec sp_executesql @sql 

    end 
    set @i = @i + 1 
    fetch next from test into @name 
end 
close test 
deallocate test 

if object_id ('tempdb..#t1') is not null select * from #t1 

このソリューションは、2つの位置でステートメントが必要なので「悪い」です。ここに示されたケースでは、これは簡単です。 しかし、ステートメントがより複雑になると、これが問題になることがあります。

+2

なぜ選択しないのですか? 。 。あなたは何をしたいのですか? –

+0

何かがここで少しです。あなたは、あなたはデータ型を知らないが、すべての単一のテーブルの名前の列を持っていると言う?なぜあなたは、すべてのテーブルにdescriptionという名前の列があることが分かっているのですか?テーブル間でデータ型を変更する理由は何ですか? –

+0

@Sean Lange:私はデータから読み返す必要がありますが、それは私の責任ではありません。アナウンスなしで変更がある可能性があります。 – Christian4145

答えて

0

あなたは、このいずれかにクエリを簡素化することができます:

set nocount on 

declare 
    @name sysname = '', 
    @i int = 0, 
    @sql nvarchar(4000) = N'' 

if object_id ('tempdb..#t1') is not null DROP TABLE #t1 

;WITH cte AS (
    select top 10 a.[name] 
    from sys.tables a 
    inner join sys.columns b 
     on a.object_id = b.object_id --and b.name = 'description' 
) 

SELECT @sql = @sql + N'UNION ALL 
select distinct top 10 description 
from ' + QUOTENAME([name]) + CHAR(13) 
FROM cte 

SELECT @sql = N';WITH cte AS (' + STUFF(@sql,1,10,') SELECT * INTO #t1 FROM cte') 

PRINT @sql 
--EXEC (@sql) 

select * from #t1 
  • ないカーソルまたはwhileループ。
  • クエリが実行される前にテンポラリテーブルが(存在する場合)削除されます。この表の列があるとして、それはこの表から何度でもsys.tablesSELECT TOP 10 Descriptionsから最初のテーブルを取る今のよう

あなたは、奇妙なクエリを得ました。

+0

このケースでCTEを使用することは良い考えですが、問題を解決しません。あなたのアイデア:1つのステートメントを作成し、 "select into"を使用します。 OKですが、ステートメントが大規模である場合やループが多い場合は、処理が難しくなります。あなたが知っている限り、1つのリテラルに対して4000の長さに制限されていますが、より複雑なSQLステートメントではそれほどではありません。 – Christian4145

+0

nvarchar(max)を使用できますが、制限は2GBです。 MSDNのsp_executesqlについて読んでください。あなたが連結で4kの文字問題を参照する場合、それは同じnvarchar(max)で解決されます。 – gofr1

+0

nvarchar(max)を使用しても、4000/8000文字に制限されている1つのリテラルには制限があります。 – Christian4145

0

SELECT INTOステートメントは、あるテーブルのデータを新しいテーブルにコピーします。これは役立ちます。

例: -

SELECT *上記はまた、サポート

条件が加わりoldtable FROM NEWTABLE INTO 。

関連する問題