将选择结果转换为插入脚本-SQL Server


106

我有SQL Server 2008SQL Server Management Studio。

我需要从Table1database1中选择数据。然后,我必须在结果和insert values into Table1database2中编辑一些值。

或者让我换种说法。

如何将一个表中的数据转换为insert script


数据库是否在同一服务器上?如果是这样,您可以从一个插入另一个。插入database2.dbo.myTable中,从database1.dbo.anOtherTable中选择数据
u07ch 2010年

是的,两个数据库都在同一服务器上。但是我需要脚本。我将把这些脚本提供给我们的数据库人员。
漫画队长

这将有助于澄清这个问题。任何方法都行得通吗,或者您需要可以插入dba的插入脚本?
greg

Answers:


31

SSMS Toolpack(在啤酒中是免费的)具有多种强大功能-包括从表生成INSERT语句

更新:对于SQL Server Management Studio 2012(及更高版本),SSMS Toolpack不再免费,但需要适度的许可费用。


+1 @marc_s我在不使用T-SQL生成器脚本的情况下生成此类插入脚本方面做了很多工作,现在您告诉我有一个工具。
bernd_k 2010年

表格存储货币数据时请小心。这些数据类型可以存储比正常显示或SSMS Toolpack生成的脚本中更多的小数位-bernd_k
2010年

13
这不再是免费的。ssmstoolspack.com/Licensing
greg

@Greg:感谢您指出这一点。注意:该许可仅适用于SQL Server Management Studio 2012和更高版本-对于早期版本,该工具包仍然免费。
marc_s

4
SSMS工具包的替代
Kiquenet '17

154

这是另一种方法,在某些情况下,它可能比安装插件或外部工具更容易:

  • 做一个。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这里指的是您有权访问的任何架构。你可以创建一个(create schema temp),然后删除它,当你完成后,或(更好)简单地使用任何模式,你在目前的工作。
KT。

1
谢谢你,我知道一定有办法!顺便说一句,如果您只需要要编写的表中的全部数据,则可以跳过创建临时表。
FAB

我必须使用它来将数据导入Azure数据库。将其导入到非Azure数据库中,然后提取为SQL插入。
m12lrpv

2
仍然让我感到惊讶的是,SSMS尚未在结果集上添加此功能“将输出作为插入脚本查看” )应该这样。要在非常大的结果集上运行可能会永远花费
Traderhut Games

60

在SSMS中:

  • 右键单击数据库>任务>生成脚本

  • 下一个

  • 选择“选择特定的数据库对象”并检查要编写脚本的表,然后单击“下一步”。

  • 单击Advanced >选项列表,向下滚动至底部,然后找到“要编写脚本的数据类型”,然后将其更改为“仅数据”>确定

  • 选择“保存到新查询窗口”>下一步>下一步>完成

现在将所有180行写为180插入语句!


12
对几行有用。没用:如果一个表有20000行,而我只想20行插入20次。
Kiquenet '17

2
@Kiquenet-您可以首先创建一个视图,该视图选择所需的20行,然后按照以下步骤创建基于该视图的插入脚本。然后,您可以进行批量查找和替换,以将“视图”名称改回您需要插入的任何“表”名称。
tember

@tember不能像您说的那样在View上工作,但是在Visual Studio中可以使用:首先在sql Studio中创建具有所需选择的视图,然后打开Visual Studio,连接到sql server并在该创建的视图上生成脚本。
塞尔吉(Sergii)

谢谢你提供的信息。尽管丢弃整个表是一个过大的杀伤力,但它解决了我的问题。
paulz '19

救生员。我一生都在写剧本。
杰伊

38

本机方法

例如,如果您有桌子

Users(Id, name)

你可以这样做:

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

您可以通过这种方式进行操作,但是如果您有多个表,则需要键入一些内容。在谷歌上有写的并且可以找到的sps可以为您做到这一点,或者,如果您拥有VS2012,则可以让VS为您完成。请参阅下面的答案。
greg 2014年

1
对于很少字段的表很有用。如果表有50、60、100列,则无用。更好的SQL代码
Kiquenet '17

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)要从现有表中获取上述数据,我们必须编写select查询,以使输出将采用上述脚本的形式

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

我)并创建了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 '18年

14

可以通过Visual Studio SQL Server对象资源管理器来完成。

您可以从上下文菜单中单击“查看数据”以获取必要的表,过滤结果并将结果另存为脚本。


1
您的文章是正确的,并使用SQL Server数据工具在Visual Studio中,最简单的方法在这里这里是帖子里面介绍了如何插入语句生成第1000行希望帮助。
shaijut

8

使用Visual Studio,执行以下操作

创建类型为SQL Server-> SQL Server数据库项目的项目

打开sql server资源管理器CTL- \,CTL-S

通过右键单击“ SQL SERVER”图标来添加SQL Server。Selcet添加新服务器

导航到您感兴趣的表

右键单击->查看数据

单击左上方的单元格以突出显示所有内容(ctl-A似乎不起作用)

右键单击-> SCript

这太棒了。这些年来,我已经尝试了上面列出的所有内容。我知道那里有一个可以做到这一点的工具,而且想不出它的名字。但这非常昂贵。

祝好运。我只是想通了。尚未使用文本字段等对其进行广泛的测试,但看起来它使您走了很长一段路。

格雷格


1
这不会转换选择结果,它只是将表格脚本化。
埃里克·K

@QuantumDynamix-通过“如何将一个表中的数据转换为脚本”在底部阐明了原始问题。以下是我的方法的样本。这正是用户要求的。实际上,这是我所看到的唯一解决方案,它实际上可以按照用户的要求生成一个插入脚本。为什么要下票?“不转换选择结果”是什么意思?设置IDENTITY_INSERT [PMDB]。[BUAttr]插入[PMDB]中。[BUAttr]([id],[BU],[Name],[Value])值(1,N'ALASKA',N'GeoCenter Lat' ,N'67.07213')
greg

这与创建临时表一起为我完成了
hr-tis

4

使用into语句创建一个单独的表,例如

从[dbo]中选择*到Test_123。[Employee]其中“%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”
Adam Mendoza,

0

如果您正在使用Oracle(或将应用程序配置到SQL Server),则Oracle SQL Developer会为您执行此操作。为表选择“卸载”,然后遵循选项(如果您不希望所有表都创建东西,请取消选中DDL)。


1
这显然被标记为SQL Server问题...
BentOnCoding 2013年

也可以将oracle sql developer与sql server一起使用。我已经编辑了我的回复。
利亚姆

0

我找到了这个SMSMS Boost插件,它是免费的,除其他功能外,它确实可以做到这一点。您可以右键单击结果,然后选择“脚本数据为”。


我查看了
脚本网


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.