選択結果の挿入スクリプトへの変換-SQL Server [終了]


105

SQL Server 2008SQL Server Management Studio を持っています。

Table1database1 からデータを選択する必要があります。次に、結果とinsert values into Table1データベース2のいくつかの値を編集する必要があります。

または別の言い方をさせてください。

1つのテーブルのデータをに変換するにはどうすればよいですかinsert script


データベースは同じサーバー上にありますか?その場合は、一方から他方に挿入できます。database2.dbo.myTableに挿入し、database1.dbo.anOtherTableからデータを選択
u07ch

はい、両方のデータベースが同じサーバー上にあります。しかし、私はスクリプトが必要です。このスクリプトをデータベース担当者に渡します。
キャプテンコミック

質問を明確にするのに役立ちます。どのようなアプローチでも機能しますか、それともdbaに渡すことができる挿入スクリプトが必要ですか?
2013年

回答:


31

SSMS Toolpack(ビールのように無料)には、テーブルからのINSERTステートメントの生成など、さまざまな優れた機能があります。

更新: SQL Server Management Studio 2012(およびそれ以降)では、SSMS Toolpackは無料ではなくなりましたが、適度なライセンス料が必要です。


+1 @marc_s T-SQLジェネレータースクリプトを使用せずに、そのような挿入スクリプトを生成するのに多くの作業を行いましたが、今、ツールがあることを教えてくれます。
bernd_k 2010

テーブルがお金のデータを格納するときは注意してください。これらのデータ型は、通常表示されるよりも、またはSSMS Toolpackによって生成されたスクリプトに小数点以下の桁数を格納できます
bernd_k

13
これはもはや無料ではありません。ssmstoolspack.com/Licensing
グレッグ

@Greg:指摘してくれてありがとう。注:ライセンスはSQL Server Management Studio 2012以降にのみ適用されます-以前のバージョンでは、ツールパックは無料です。
marc_s 2013年

4
SSMS Toolpackの代替?
Kiquenet 2017年

153

これは別の方法で、状況によってはプラグインや外部ツールをインストールするよりも簡単な場合があります。

  • を行います。select [whatever you need]INTO temp.table_namefrom [... etc ...]
  • オブジェクトエクスプローラーでデータベースを右クリック=>タスク=>スクリプトの生成
  • [ temp.table_nameオブジェクトの選択]画面で選択し、[次へ]をクリックします。
  • 「スクリプトの保存方法の指定」画面で、次のようにします。
    • [詳細]をクリックし、[スクリプトへのデータの種類]プロパティを見つけ、[データのみ]を選択して、詳細プロパティを閉じます。
    • [新しいクエリウィンドウに保存]を選択します(何千ものレコードがない場合)。
  • [次へ]をクリックして、ジョブが完了するのを待ち、結果のINSERTステートメントが新しいクエリウィンドウに表示されることを確認します。
  • 検索と置換を使用して、すべて[temp.table_name]をに変更し[your_table_name]ます。
  • drop table [temp.table_name]

INTO temp.table1を使用すると、次のエラーが生成されます。指定されたスキーマ名 "temp"が存在しないか、それを使用する権限がありません。私は、SQL 2012年使用しています
マーク

3
tempここでは、アクセスできるスキーマを指します。あなたはどちらか(1を作成することができますcreate schema temp。単にあなたが現在作業しているものは何でもスキーマを使用(良い))、その後、作業が完了したときにそれを削除、または
KT。

1
これをありがとう、私は方法があるに違いないことを知っていました!ちなみに、スクリプトを作成するテーブルのデータ全体だけが必要な場合は、一時テーブルの作成をスキップできます。
FAB、

Azureデータベースにデータをインポートするには、これを使用する必要がありました。それを非Azureデータベースにインポートし、SQL挿入として抽出します。
m12lrpv 2018年

2
SSMSが結果セットにこの機能「出力を挿入スクリプトとして表示する」を追加していないことにまだ驚かされます。 )のように。これは、非常に大きな結果セットで実行するのに永遠にかかる可能性があります
Traderhut Games

60

SSMSの場合:

  • データベースを右クリック>タスク>スクリプトを生成

  • [特定のデータベースオブジェクトを選択する]を選択し、スクリプトを作成するテーブルをオンにします。

  • Advanced >オプションのリストをクリックし、一番下までスクロールして、「スクリプトを作成するデータのタイプ」を探し、それを「データのみ」に変更します> OK

  • [新しいクエリウィンドウに保存]> [次へ]> [次へ]> [完了]を選択します

180行すべてが180の挿入ステートメントとして記述されています!


12
数行に便利です。役に立たない:テーブルに20000行があり、20行に対して20挿入しか必要ない場合。
Kiquenet 2017年

2
@Kiquenet-最初に目的の20行を選択するビューを作成し、次の手順に従ってビューに基づいて挿入スクリプトを作成できます。次に、一括検索と置換を行って、ビュー名を挿入する必要のあるテーブル名に変更します。
12

@tember言うようにビューでは機能しませんが、Visual Studioでは機能します。最初に必要な選択を含むビューをSQLスタジオで作成し、次にVisual Studioを開いてSQLサーバーに接続し、作成したビューでスクリプトを生成します。
Sergii

その情報をありがとう。テーブル全体をダンプするのはやり過ぎですが、私の問題は解決しました。
ポールズ

ライフセーバー。私は一生スクリプトを書いています。
ジェイ

38

ネイティブメソッド

たとえば、テーブルがある場合

Users(Id, name)

あなたはこれを行うことができます:

select 'insert into Table values(Id=' + Id + ', name=' + name + ')' from Users

この方法で行うことができますが、テーブルがいくつかある場合は、少しタイプする必要があります。これを行うgoogleで書かれた、見つけられるspsがあります。または、VS2012を持っている場合は、VSにそれを行わせることができます。以下の私の答えを参照してください。
2014

1
フィールドが少ないテーブルに役立ちます。テーブルに50、60、100列がある場合は役に立ちません。より良い世代のSQLコード
Kiquenet 2017年

23

1-スクリプトの説明

A)テーブルにデータを挿入するための構文は次のとおりです

Insert into table(col1,col2,col3,col4,col5)    

             -- To achieve this part i    
             --have used below variable
                ------@CSV_COLUMN-------

values(Col1 data in quote, Col2..quote,..Col5..quote)

-- To achieve this part 
-- i.e column data in 
--quote i have used 
--below variable
----@QUOTED_DATA---

C)既存のテーブルから上記のデータを取得するには、出力が上記のスクリプトの形式になるように選択クエリを記述する必要があります

D)そして最後に、実行時に挿入スクリプトを生成する最終的なスクリプトを作成するために、上記の変数を連結しました

E)

@TEXT='SELECT ''INSERT INTO
 '+@TABLE_NAME+'('+@CSV_COLUMN+')VALUES('''+'+'+SUBSTRING(@QUOTED_DATA,1,LEN(@QUOTED_DATA)-5)+'+'+''')'''+' Insert_Scripts FROM '+@TABLE_NAME + @FILTER_CONDITION

F)そして最後に上記のクエリを実行しました EXECUTE(TEXT)

G)QUOTENAME()関数を使用して、列データを引用符で囲む

H)ISNULLが使用されているのは、任意の行NULL に任意の列のデータがある場合、クエリが失敗し、それが返さNULLれるためです。ISNULL

I)そしてsp_generate_insertscripts 同じのためにsp を作成しました

1-必要なテーブル名を入力するだけ insert script

2-特定の結果が必要な場合はフィルター条件

----------Final Procedure To generate Script------

CREATE PROCEDURE sp_generate_insertscripts
(
    @TABLE_NAME VARCHAR(MAX),
    @FILTER_CONDITION VARCHAR(MAX)=''
)
AS
BEGIN

SET NOCOUNT ON

DECLARE @CSV_COLUMN VARCHAR(MAX),
        @QUOTED_DATA VARCHAR(MAX),
        @TEXT VARCHAR(MAX)

SELECT @CSV_COLUMN=STUFF
(
    (
     SELECT ',['+ NAME +']' FROM sys.all_columns 
     WHERE OBJECT_ID=OBJECT_ID(@TABLE_NAME) AND 
     is_identity!=1 FOR XML PATH('')
    ),1,1,''
)

SELECT @QUOTED_DATA=STUFF
(
    (
     SELECT ' ISNULL(QUOTENAME('+NAME+','+QUOTENAME('''','''''')+'),'+'''NULL'''+')+'','''+'+' FROM sys.all_columns 
     WHERE OBJECT_ID=OBJECT_ID(@TABLE_NAME) AND 
     is_identity!=1 FOR XML PATH('')
    ),1,1,''
)

SELECT @TEXT='SELECT ''INSERT INTO '+@TABLE_NAME+'('+@CSV_COLUMN+')VALUES('''+'+'+SUBSTRING(@QUOTED_DATA,1,LEN(@QUOTED_DATA)-5)+'+'+''')'''+' Insert_Scripts FROM '+@TABLE_NAME + @FILTER_CONDITION

--SELECT @CSV_COLUMN AS CSV_COLUMN,@QUOTED_DATA AS QUOTED_DATA,@TEXT TEXT

EXECUTE (@TEXT)

SET NOCOUNT OFF

END

あなたは素晴らしい仕事をしました...
DineshDB 2018年

14

Visual Studio SQL Serverオブジェクトエクスプローラーを使用して実行できます。

必要なテーブルのコンテキストメニューから[データの表示]をクリックして、結果をフィルター処理し、結果をスクリプトとして保存できます。


1
あなたの投稿は、Visual StudioのSQL Serverデータツールを使用した正しい最も簡単な方法です。ここここ、最初の1000行の挿入ステートメントの生成がどのように役立つかを説明する投稿です。
shaijut 2016年

8

Visual Studioを使用して、次の操作を行います

タイプSQL Serverのプロジェクトを作成-> SQL Serverデータベースプロジェクト

SQLサーバーエクスプローラーCTL-\、CTL-Sを開きます。

SQL SERVERアイコンを右クリックしてSQL Serverを追加します。新しいサーバーを追加

興味のあるテーブルに移動します

右クリック->データの表示

左上のセルをクリックしてすべてを強調表示します(ctl-Aは機能していないようです)

右クリック->スクリプト

これは素晴らしいです。私は何年にもわたって上記のすべてを試しました。これを行うためのツールが世の中にあることは知っていますが、その名前は思いつきません。しかし、それは非常に高価です。

幸運を。私はこれを理解しました。テキストフィールドなどを使用して広範囲にテストしていませんが、長い道のりを進むように見えます。

グレッグ


1
これは選択結果を変換するのではなく、単にテーブルからスクリプトを作成するだけです。
エリックK

@QuantumDynamix-元の質問は、「1つのテーブルのデータをスクリプトに変換するにはどうすればよいですか」によって下部に明確化されています。以下は私のアプローチのサンプルです。それはまさにユーザーが尋ねたものです。実際、ユーザーの要求に応じて、挿入のスクリプトを実際に生成するのは私が見る唯一のソリューションです。なぜ反対票か。「選択結果を変換しない」とはどういう意味ですか?SET IDENTITY_INSERT [PMDB]。[BUAttr] ON INSERT INTO [PMDB]。[BUAttr]([id]、[BU]、[Name]、[Value])VALUES(1、N'ALASKA '、N'GeoCenter Lat' 、N'67.07213' )
グレッグ・

これは一時テーブルの作成と一緒に、私のためにそれを行いました
hr-tis '22 / 11/17

4

intoステートメントを使用して別のテーブルを作成しますたとえば、

[dbo]。[Employee]からTest_123に*を選択します。ここで、「%Test%」のような名前です。

データベースに移動しますデータベースを右クリックしますスクリプトの生成をクリックしますテーブルを選択しますアドバンスオプションを選択し、属性を選択します "データのみ"ファイルを選択します "新しいクエリで開く"

SQLがスクリプトを生成します


3

SSMSで「ファイルに結果」オプションを選択し、選択した結果をファイルにエクスポートして結果ファイルに変更を加え、最後にBCPを使用して、データベース2のテーブル1に挿入できる一括コピーを使用できます。

一括挿入の場合、.rptファイルを.csvファイルに変換する必要があると思います

お役に立てば幸いです。


2

同様の問題がありましたが、クエリからINSERTステートメントを作成できる必要がありました(フィルターなどを使用)。

だから私は次の手順を作成しました:

CREATE PROCEDURE dbo.ConvertQueryToInsert (@input NVARCHAR(max), @target NVARCHAR(max)) AS BEGIN

    DECLARE @fields NVARCHAR(max);
    DECLARE @select NVARCHAR(max);

    -- Get the defintion from sys.columns and assemble a string with the fields/transformations for the dynamic query
    SELECT
        @fields = COALESCE(@fields + ', ', '') + '[' + name +']', 
        @select = COALESCE(@select + ', ', '') + ''''''' + ISNULL(CAST([' + name + '] AS NVARCHAR(max)), ''NULL'')+'''''''
    FROM tempdb.sys.columns 
    WHERE [object_id] = OBJECT_ID(N'tempdb..'+@input);

    -- Run the a dynamic query with the fields from @select into a new temp table
    CREATE TABLE #ConvertQueryToInsertTemp (strings nvarchar(max))
    DECLARE @stmt NVARCHAR(max) = 'INSERT INTO #ConvertQueryToInsertTemp SELECT '''+ @select + ''' AS [strings] FROM '+@input
    exec sp_executesql @stmt

    -- Output the final insert statement 
    SELECT 'INSERT INTO ' + @target + ' (' + @fields + ') VALUES (' + REPLACE(strings, '''NULL''', 'NULL') +')' FROM #ConvertQueryToInsertTemp

    -- Clean up temp tables
    DROP TABLE #ConvertQueryToInsertTemp
    SET @stmt = 'DROP TABLE ' + @input
    exec sp_executesql @stmt
END

次に、クエリの出力を一時テーブルに書き込み、プロシージャを実行することで、それを使用できます。

-- Example table
CREATE TABLE Dummy (Id INT, Comment NVARCHAR(50), TimeStamp DATETIME)
INSERT INTO Dummy VALUES (1 , 'Foo', GetDate()), (2, 'Bar', GetDate()), (3, 'Foo Bar', GetDate())

-- Run query and procedure
SELECT * INTO #TempTableForConvert FROM Dummy WHERE Id < 3
EXEC dbo.ConvertQueryToInsert '#TempTableForConvert', 'dbo.Dummy'

注:この手順では、値が文字列にキャストされるだけで、データが少し違って見える場合があります。たとえば、DATETIMEの場合、秒は失われます。


2

これはより用途の広いソリューションであり(質問の回答よりも少し多く機能します)、新しいストアドプロシージャを作成しなくてもクエリウィンドウで使用できます。たとえば、書き込みアクセス権がないプロダクションデータベースで役立ちます。 。

コードを使用するには、その使用方法を説明するインラインコメントに従って変更してください。その後、このクエリをクエリウィンドウで実行するだけで、必要なINSERTステートメントが出力されます。

SET NOCOUNT ON

-- Set the ID you wish to filter on here
DECLARE @id AS INT = 123

DECLARE @tables TABLE (Name NVARCHAR(128), IdField NVARCHAR(128), IdInsert BIT, Excluded NVARCHAR(128))

-- Add any tables you wish to generate INSERT statements for here. The fields are as thus:
 -- Name: Your table name
 -- IdField: The field on which to filter the dataset
 -- IdInsert: If the primary key field is to be included in the INSERT statement
 -- Excluded: Any fields you do not wish to include in the INSERT statement
INSERT INTO @tables (Name, IdField, IdInsert, Excluded) VALUES ('MyTable1', 'Id', 0, 'Created,Modified')
INSERT INTO @tables (Name, IdField, IdInsert, Excluded) VALUES ('MyTable2', 'Id', 1, 'Created,Modified')

DECLARE @numberTypes TABLE (sysId TINYINT)

-- This will ensure INT and BIT types are not surrounded with quotes in the
-- resultant INSERT statement, but you may need to add more (from sys.types)
INSERT @numberTypes(SysId) VALUES(56),(104)

DECLARE @rows INT = (SELECT COUNT(*) FROM @tables)
DECLARE @cnt INT = 1

DECLARE @results TABLE (Sql NVARCHAR(4000))

WHILE @cnt <= @rows
BEGIN
    DECLARE @tablename AS NVARCHAR(128)
    DECLARE @idField AS NVARCHAR(128)
    DECLARE @idInsert AS BIT
    DECLARE @excluded AS NVARCHAR(128)
    SELECT
        @tablename = Name,
        @idField = IdField,
        @idInsert = IdInsert,
        @excluded = Excluded
    FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS RowId FROM @tables) t WHERE t.RowId = @cnt

    DECLARE @excludedFields TABLE (FieldName NVARCHAR(128))
    DECLARE @xml AS XML = CAST(('<X>' + REPLACE(@excluded, ',', '</X><X>') + '</X>') AS XML)
    INSERT INTO @excludedFields SELECT N.value('.', 'NVARCHAR(128)') FROM @xml.nodes('X') AS T(N)

    DECLARE @setIdentity NVARCHAR(128) = 'SET IDENTITY_INSERT ' + @tablename

    DECLARE @execsql AS NVARCHAR(4000) = 'SELECT ''' + CASE WHEN @idInsert = 1 THEN @setIdentity + ' ON' + CHAR(13) ELSE '' END + 'INSERT INTO ' + @tablename + ' ('
    SELECT @execsql = @execsql +
    STUFF
    (
        (
            SELECT CASE WHEN NOT EXISTS(SELECT * FROM @excludedFields WHERE FieldName = name) THEN ', ' + name ELSE '' END
            FROM sys.columns
            WHERE object_id = OBJECT_ID('dbo.' + @tablename)
            FOR XML PATH('')
        ), 1, 2, ''
    ) +
    ')' + CHAR(13) + 'VALUES (' +
    STUFF
    (
        (
            SELECT
                CASE WHEN NOT EXISTS(SELECT * FROM @excludedFields WHERE FieldName = name) THEN
                    ''', '' + ISNULL(' +
                    CASE WHEN EXISTS(SELECT * FROM @numberTypes WHERE SysId = system_type_id) THEN '' ELSE ''''''''' + ' END +
                    'CAST(' + name + ' AS VARCHAR)' +
                    CASE WHEN EXISTS(SELECT * FROM @numberTypes WHERE SysId = system_type_id) THEN '' ELSE ' + ''''''''' END +
                    ', ''NULL'') + '
                ELSE ''
                END
            FROM sys.columns
            WHERE object_id = OBJECT_ID('dbo.' + @tablename)
            FOR XML PATH('')
        ), 1, 3, ''
    ) +
    ''')' + CASE WHEN @idInsert = 1 THEN CHAR(13) + @setIdentity + ' OFF' ELSE '' END +
    ''' FROM ' + @tablename + ' WHERE ' + @idField + ' = ' + CAST(@id AS VARCHAR)

    INSERT @results EXEC (@execsql)
    DELETE @excludedFields
    SET @cnt = @cnt + 1
END

DECLARE cur CURSOR FOR SELECT Sql FROM @results
OPEN cur

DECLARE @sql NVARCHAR(4000)
FETCH NEXT FROM cur INTO @sql
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @sql
    FETCH NEXT FROM cur INTO @sql
END

CLOSE cur
DEALLOCATE cur



1

私は以下を作成しましたprocedure

if object_id('tool.create_insert', 'P') is null
begin
  exec('create procedure tool.create_insert as');
end;
go

alter procedure tool.create_insert(@schema    varchar(200) = 'dbo',
                                   @table     varchar(200),
                                   @where     varchar(max) = null,
                                   @top       int = null,
                                   @insert    varchar(max) output)
as
begin
  declare @insert_fields varchar(max),
          @select        varchar(max),
          @error         varchar(500),
          @query         varchar(max);

  declare @values table(description varchar(max));

  set nocount on;

  -- Get columns
  select @insert_fields = isnull(@insert_fields + ', ', '') + c.name,
         @select = case type_name(c.system_type_id)
                      when 'varchar' then isnull(@select + ' + '', '' + ', '') + ' isnull('''''''' + cast(' + c.name + ' as varchar) + '''''''', ''null'')'
                      when 'datetime' then isnull(@select + ' + '', '' + ', '') + ' isnull('''''''' + convert(varchar, ' + c.name + ', 121) + '''''''', ''null'')'
                      else isnull(@select + ' + '', '' + ', '') + 'isnull(cast(' + c.name + ' as varchar), ''null'')'
                    end
    from sys.columns c with(nolock)
         inner join sys.tables t with(nolock) on t.object_id = c.object_id
         inner join sys.schemas s with(nolock) on s.schema_id = t.schema_id
   where s.name = @schema
     and t.name = @table;

  -- If there's no columns...
  if @insert_fields is null or @select is null
  begin
    set @error = 'There''s no ' + @schema + '.' + @table + ' inside the target database.';
    raiserror(@error, 16, 1);
    return;
  end;

  set @insert_fields = 'insert into ' + @schema + '.' + @table + '(' + @insert_fields + ')';

  if isnull(@where, '') <> '' and charindex('where', ltrim(rtrim(@where))) < 1
  begin
    set @where = 'where ' + @where;
  end
  else
  begin
    set @where = '';
  end;

  set @query = 'select ' + isnull('top(' + cast(@top as varchar) + ')', '') + @select + ' from ' + @schema + '.' + @table + ' with (nolock) ' + @where;

  insert into @values(description)
  exec(@query);

  set @insert = isnull(@insert + char(10), '') + '--' + upper(@schema + '.' + @table);

  select @insert = @insert + char(10) + @insert_fields + char(10) + 'values(' + v.description + ');' + char(10) + 'go' + char(10)
    from @values v
   where isnull(v.description, '') <> '';
end;
go

次に、そのように使用できます。

declare @insert varchar(max),
        @part   varchar(max),
        @start  int,
        @end    int;

set @start = 1;

exec tool.create_insert @schema = 'dbo',
                        @table = 'customer',
                        @where  = 'id = 1',
                        @insert = @insert output;

-- Print one line to avoid the maximum 8000 characters problem
while len(@insert) > 0
begin
  set @end = charindex(char(10), @insert);

  if @end = 0
  begin
    set @end = len(@insert) + 1;
  end;

  print substring(@insert, @start, @end - 1);
  set @insert = substring(@insert, @end + 1, len(@insert) - @end + 1);
end;

出力は次のようになります。

--DBO.CUSTOMER
insert into dbo.customer(id, name, type)
values(1, 'CUSTOMER NAME', 'F');
go

行の範囲を取得するだけの場合は、次のように@topパラメーターを使用します。

declare @insert varchar(max),
        @part   varchar(max),
        @start  int,
        @end    int;

set @start = 1;

exec tool.create_insert @schema = 'dbo',
                        @table = 'customer',
                        @top    = 100,
                        @insert = @insert output;

-- Print one line to avoid the maximum 8000 characters problem
while len(@insert) > 0
begin
  set @end = charindex(char(10), @insert);

  if @end = 0
  begin
    set @end = len(@insert) + 1;
  end;

  print substring(@insert, @start, @end - 1);
  set @insert = substring(@insert, @end + 1, len(@insert) - @end + 1);
end;

役に立ちましたが、このフィールド "6C2A94737A456C405FDCF793DFA6E661:BqRc / DpUIe27"が "6C2A94737A456C405FDCF793DFA6E6"に切り捨てられました
アダムメンドーサ

0

Oracleを使用している(またはアプリケーションをSQL Serverに構成している)場合、Oracle SQL Developerがこれを行います。テーブルの[アンロード]を選択し、オプションに従ってください(すべてのテーブルを作成したくない場合は、DDLをオフにします)。


1
これは明らかにSQL Serverの質問としてマークされています...
BentOnCoding 2013年

sqlサーバーでoracle sql開発者を使用することもできます。返信を編集しました。
Liam

0

私はこのSMSMS Boostアドオンを見つけました。これは無料で、とりわけこれを正確に実行します。結果を右クリックして、[スクリプトデータ]を選択できます。


スクリプトグリッドデータを表示したが、結果からSQL挿入を生成しなかった
Kiquenet 2017年


-1

INSERT INTO SELECTステートメントを使用して、選択クエリの結果をテーブルに挿入できます。http://www.w3schools.com/sql/sql_insert_into_select.asp

例:

INSERT INTO Customers (CustomerName, Country) SELECT SupplierName, Country FROM Suppliers WHERE Country='Germany';

1
これは、SELECTステートメントがINSERTステートメントに変換する結果とは関係ありません。これは単なるINSERTステートメントです。
Niels Lucas

機能的に同等ではないですか?
プロテクター1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.