为SQL Server表自动生成INSERT语句的最佳方法是什么?

Jos*_*ons 569 sql-server ssms code-generation

我们正在编写一个新的应用程序,在测试时,我们需要一堆虚拟数据.我通过使用MS Access将excel文件转储到相关表中来添加该数据.

我们经常要"刷新"相关表,这意味着将它们全部删除,重新创建它们,并运行已保存的MS Access追加查询.

第一部分(删除和重新创建)是一个简单的sql脚本,但最后一部分让我感到畏缩.我想要一个单一的安装脚本,它有一堆INSERT来重新生成虚拟数据.

我现在有表格中的数据.从该数据集自动生成大型INSERT语句列表的最佳方法是什么?

我能想到的唯一方法是将表保存到excel表,然后编写一个excel公式来为每一行创建一个INSERT,这肯定不是最好的方法.

我正在使用2008 Management Studio连接到SQL Server 2005数据库.

小智 971

Microsoft应该宣传SSMS 2008的此功能.您要查找的功能内置于Generate Script实用程序中,但默认情况下该功能处于关闭状态,并且必须在编写表脚本时启用该功能.

这是一个快速运行INSERT,为SQL Management Studio 2008中没有脚本或加载项生成表中所有数据的语句:

  1. 右键单击数据库,然后转到" 任务" >" 生成脚本".
  2. 选择要生成脚本的表(或对象).
  3. 转到" 设置脚本选项"选项卡,然后单击" 高级"按钮.
  4. 在" 常规"类别中,转到" 脚本数据类型"
  5. 有3个选项:仅架构,唯一的数据,以及架构和数据.选择适当的选项,然后单击" 确定".

然后,您将直接从SSMS 获取该CREATE TABLE语句和所有INSERT数据语句.

  • 高级按钮处于一个非常愚蠢的位置.难怪没有人能够独立发现这一点.它似乎与"保存到文件"选项一致.另外,我想知道为什么它不会生成更高效的insert语句而不是许多多个insert语句 (15认同)
  • 请务必阅读下面的Noonand评论 - 复选框不在SCRIPT DATA = TRUE下,而是在General部分下,为'Script to data'选择合适的选项. (10认同)
  • 如果您只想生成一个insert语句,请执行以下操作; 从现有表格中选择*进入newtable [where where子句],然后在新表上执行上述操作 (7认同)
  • 这在新版本中的工作方式也相同.在SSMS 2014中证实了这一点. (5认同)
  • 仅供参考,如果您选择“仅数据”并遇到“找到循环依赖项”错误,请切换到“架构和数据”以避免该错误。发生在 Management Studio v17 中。 (3认同)
  • 在 SSMS 17.3 中,仅当您选择 1 个表时,您才能更改“脚本的数据类型”。对于 1 个以上的表,“仅架构”是预先选择的,我无法更改它。 (2认同)

Sha*_*mer 85

我们使用这个存储过程 - 它允许您定位特定的表,并使用where子句.你可以在这里找到文字.

例如,它允许您这样做:

EXEC sp_generate_inserts 'titles'
Run Code Online (Sandbox Code Playgroud)

  • 我也得到了这个错误.要解决此问题,请将"EXEC master.dbo.sp_MS_upd_sysobj_category 2"替换为"EXEC sp_MS_marksystemobject sp_generate_inserts"并删除"EXEC master.dbo.sp_MS_upd_sysobj_category 1"行. (9认同)
  • 我正在获取 - 消息536,级别16,状态5,过程sp_generate_inserts,331行传递给SUBSTRING函数的长度参数无效.消息536,级别16,状态5,过程sp_generate_inserts,行332传递给SUBSTRING函数的长度参数无效.消息50000,级别16,状态1,过程sp_generate_inserts,行336没有要选择的列.至少应该有一列来生成输出么? (6认同)
  • @InfinitiesLoop,只是有时您需要能够通过代码自动化它,而不是让用户通过GUI手动执行任务. (5认同)
  • @jcollum - 它实际上不是内置的存储过程.如果您按照链接,您可以获取存储过程的文本. (3认同)
  • 需要注意的是,您应该避免使用“sp_”作为用户定义存储过程的前缀,因为这是 Microsoft 用于内置存储过程的命名空间,如果他们发布同名的存储过程,您的代码将会崩溃。另外,如果您使用不同的命名约定,并且在使用元表时,您可以轻松区分用户和系统存储过程。 (3认同)

noo*_*and 43

正如@Mike Ritacco所述,但针对SSMS 2008 R2进行了更新

  1. 右键单击数据库名称
  2. 选择"任务>生成脚本"
  3. 根据您的设置,可以显示或不显示介绍页面
  4. 选择"选择特定数据库对象",
  5. 展开树视图并检查相关表
  6. 点击下一步
  7. 单击高级
  8. 在"常规"部分下,为"脚本数据类型"选择适当的选项
  9. 完成向导

然后,您将直接从SSMS获取数据的所有INSERT语句.

编辑2016-10-25 SQL Server 2016/SSMS 13.0.15900.1

  1. 右键单击数据库名称

  2. 选择"任务>生成脚本"

  3. 根据您的设置,可以显示或不显示介绍页面

  4. 选择"选择特定数据库对象",

  5. 展开树视图并检查相关表

  6. 点击下一步

  7. 单击高级

  8. 在"常规"部分下,为"脚本数据类型"选择适当的选项

  9. 单击确定

  10. 选择是否要将输出转到新查询,剪贴板或文件

  11. 单击下一步两次

  12. 您的脚本是根据您在上面选择的设置准备的

  13. 单击完成


Mar*_*tin 40

这也可以使用Visual Studio(至少在2013版本以后).

在VS 2013中,还可以过滤 insert语句所基于的行列表,这在SSMS中是不可能的,因为我知道.

执行以下步骤:

  • 打开"SQL Server对象资源管理器"窗口(菜单:/ View/SQL Server对象资源管理器)
  • 打开/展开数据库及其表
  • 右键单击表格,然后从上下文菜单中选择"查看数据"
  • 这将在主区域中显示数据
  • 可选步骤:单击过滤器图标"排序和过滤数据集"(结果上方行左侧的第四个图标)并将一些过滤器应用于一个或多个列
  • 单击"脚本"或"脚本到文件"图标(顶行右侧的图标,它们看起来像小纸张)

这将为选定的表创建(条件)插入语句到活动窗口或文件.


"过滤器"和"脚本"按钮Visual Studio 2013:

在此输入图像描述

  • 现在,这是我从一个数据库中提取记录以插入其他地方的首选方法 - 它似乎比通过SSMS中的向导简单得多. (3认同)
  • 我无法让它导出二进制字段:( (2认同)

Bin*_*ker 27

您可以使用SSMS工具包(适用于SQL Server 2005和2008).它带有一个用于生成插入语句的功能.

http://www.ssmstoolspack.com/


Eri*_*est 23

我正在使用SSMS 2008版本10.0.5500.0.在此版本中,作为Generate Scripts向导的一部分,而不是Advanced按钮,下面是屏幕.在这种情况下,我只想插入数据而没有创建语句,因此我不得不更改两个带圆圈的属性脚本选项


har*_*ott 13

Jane Dallaway的存储过程:http://docs.google.com/leaf?id = 0B_AkC4ZdTI9tNWVmZWU3NzAtMWY1My00NjgwLWI3ZjQtMTY1NDMxYzBhYzgx&hl = en_GB .文档是一系列博客文章:https://www.google.com/search?q = spu_generateinsert&as_sitesearch = http%3A %% 2F%2Fjane.dallaway.com


joh*_*ash 9

sp_generate_inserts的第一个链接非常酷,这是一个非常简单的版本:

DECLARE @Fields VARCHAR(max); SET @Fields = '[QueueName], [iSort]' -- your fields, keep []
DECLARE @Table  VARCHAR(max); SET @Table  = 'Queues'               -- your table

DECLARE @SQL    VARCHAR(max)
SET @SQL = 'DECLARE @S VARCHAR(MAX)
SELECT @S = ISNULL(@S + '' UNION '', ''INSERT INTO ' + @Table + '(' + @Fields + ')'') + CHAR(13) + CHAR(10) + 
 ''SELECT '' + ' + REPLACE(REPLACE(REPLACE(@Fields, ',', ' + '', '' + '), '[', ''''''''' + CAST('),']',' AS VARCHAR(max)) + ''''''''') +' FROM ' + @Table + '
PRINT @S'

EXEC (@SQL)
Run Code Online (Sandbox Code Playgroud)

在我的系统上,我得到了这个结果:

INSERT INTO Queues([QueueName], [iSort])
SELECT 'WD: Auto Capture', '10' UNION 
SELECT 'Car/Lar', '11' UNION 
SELECT 'Scan Line', '21' UNION 
SELECT 'OCR', '22' UNION 
SELECT 'Dynamic Template', '23' UNION 
SELECT 'Fix MICR', '41' UNION 
SELECT 'Fix MICR (Supervisor)', '42' UNION 
SELECT 'Foreign MICR', '43' UNION 
...
Run Code Online (Sandbox Code Playgroud)


dru*_*sta 9

如果需要编程访问,则可以使用开源存储过程GenerateInsert.

INSERT语句生成器

就像一个简单快速的例子一样,为表生成INSERT语句AdventureWorks.Person.AddressType执行以下语句:

USE [AdventureWorks];
GO
EXECUTE dbo.GenerateInsert @ObjectName = N'Person.AddressType';
Run Code Online (Sandbox Code Playgroud)

这将生成以下脚本:

SET NOCOUNT ON
SET IDENTITY_INSERT Person.AddressType ON
INSERT INTO Person.AddressType
([AddressTypeID],[Name],[rowguid],[ModifiedDate])
VALUES
 (1,N'Billing','B84F78B1-4EFE-4A0E-8CB7-70E9F112F886',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(2,N'Home','41BC2FF6-F0FC-475F-8EB9-CEC0805AA0F2',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(3,N'Main Office','8EEEC28C-07A2-4FB9-AD0A-42D4A0BBC575',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(4,N'Primary','24CB3088-4345-47C4-86C5-17B535133D1E',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(5,N'Shipping','B29DA3F8-19A3-47DA-9DAA-15C84F4A83A5',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(6,N'Archive','A67F238A-5BA2-444B-966C-0467ED9C427F',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
SET IDENTITY_INSERT Person.AddressType OFF
Run Code Online (Sandbox Code Playgroud)

  • 这实际上比 EXEC sp_generate_inserts 'titles' 效果更好 (2认同)

chu*_*uck 8

我对这个问题的贡献,一个Powershell INSERT脚本生成器,它允许您编写脚本多个表而无需使用繁琐的SSMS GUI.非常适合将"种子"数据快速保存到源代码管理中.

  1. 将以下脚本保存为"filename.ps1".
  2. 对"CUSTOMIZE ME"下的区域进行自己的修改.
  3. 您可以按任何顺序将表列表添加到脚本中.
  4. 您可以在Powershell ISE中打开脚本并点击"播放"按钮,或者只需在Powershell命令提示符下执行脚本.

默认情况下,生成的INSERT脚本将与脚本位于同一文件夹下的"SeedData.sql".

您将需要安装SQL Server管理对象程序集,如果安装了SSMS,则应该存在该程序集.

Add-Type -AssemblyName ("Microsoft.SqlServer.Smo, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91")
Add-Type -AssemblyName ("Microsoft.SqlServer.ConnectionInfo, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91")



#CUSTOMIZE ME
$outputFile = ".\SeedData.sql"
$connectionString = "Data Source=.;Initial Catalog=mydb;Integrated Security=True;"



$sqlConnection = new-object System.Data.SqlClient.SqlConnection($connectionString)
$conn = new-object Microsoft.SqlServer.Management.Common.ServerConnection($sqlConnection)
$srv = new-object Microsoft.SqlServer.Management.Smo.Server($conn)
$db = $srv.Databases[$srv.ConnectionContext.DatabaseName]
$scr = New-Object Microsoft.SqlServer.Management.Smo.Scripter $srv
$scr.Options.FileName = $outputFile
$scr.Options.AppendToFile = $false
$scr.Options.ScriptSchema = $false
$scr.Options.ScriptData = $true
$scr.Options.NoCommandTerminator = $true

$tables = New-Object Microsoft.SqlServer.Management.Smo.UrnCollection



#CUSTOMIZE ME
$tables.Add($db.Tables["Category"].Urn)
$tables.Add($db.Tables["Product"].Urn)
$tables.Add($db.Tables["Vendor"].Urn)



[void]$scr.EnumScript($tables)

$sqlConnection.Close()
Run Code Online (Sandbox Code Playgroud)


Kli*_*lik 6

GenerateData是一个了不起的工具。对其进行调整也非常容易,因为您可以使用源代码。几个不错的功能:

  • 人名和地名的名称生成器
  • 能够保存生成配置文件(下载并在本地设置后)
  • 能够通过脚本自定义和操作生成
  • 数据的许多不同输出(CSV、Javascript、JSON 等)(以防您需要在不同环境中测试该集合并希望跳过数据库访问)
  • 免费。但是,如果您发现该软件有用,请考虑捐赠:)。

图形用户界面


TAH*_*URI 6

为了获得带有过滤记录的 INSERT 语句(WHERE QUERY),您可以

  1. 右键单击表脚本表为 > 创建到 > 新查询

  2. 使用 TEMP_TABLE 重命名它

  3. 现在运行

    从您的第一个表中选择 TEMP_TABLE,现在您的标准在这里

通过这种方式,您的临时表将只包含您想要的记录,现在通过运行脚本向导(如@Mike Ritacco所解释) ,仅使用 DATA,您将获得准确的插入语句。

  • 更好、更容易地使用 SELECT INTO NEW_TABLE 语法,无需“CREATE”:https://www.w3schools.com/sql/sql_select_into.asp (3认同)

Shu*_*oUk 5

不要使用插入,使用BCP

  • 在大多数情况下有效,但可能有充分的理由想要使用插入件。 (2认同)