将表里的数据批量生成INSERT语句的存储过程 增强版

有时候,我们需要将某个表里的数据全部或者根据查询条件导出来,迁移到另一个相同结构的库中

目前SQL Server里面是没有相关的工具根据查询条件来生成INSERT语句的,只有借助第三方工具(third party tools)

这种脚本网上也有很多,但是网上的脚本还是欠缺一些规范和功能,例如:我只想导出特定查询条件的数据,网上的脚本都是导出全表数据

如果表很大,对性能会有很大影响

这里有一个存储过程(适用于SQLServer2005 或以上版本)

-- Author: <桦仔> -- Blog: <http://www.cnblogs.com/lyhabc/> -- Create date: <//> -- Description: <根据查询条件导出表数据的insert脚本> -- ============================================= CREATE PROCEDURE InsertGenerator ( @tableName NVARCHAR(MAX), @whereClause NVARCHAR(MAX) ) AS --Then it includes a cursor to fetch column specific information (column name and the data type thereof) --from information_schema.columns pseudo entity and loop through for building the INSERT and VALUES clauses --of an INSERT DML statement. DECLARE @string NVARCHAR(MAX) --for storing the first half of INSERT statement DECLARE @stringData NVARCHAR(MAX) --for storing the data (VALUES) related statement DECLARE @dataType NVARCHAR(MAX) --data types returned for respective columns DECLARE @schemaName NVARCHAR(MAX) --schema name returned from sys.schemas DECLARE @schemaNameCount int--shema count DECLARE @QueryString NVARCHAR(MAX) -- provide for the whole query, set @QueryString=' ' --如果有多个schema,选择其中一个schema SELECT @schemaNameCount=COUNT(*) FROM sys.tables t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id WHERE t.name = @tableName WHILE(@schemaNameCount>) BEGIN --如果有多个schema,依次指定 select @schemaName = name from ( SELECT ROW_NUMBER() over(order by s.schema_id) RowID,s.name FROM sys.tables t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id WHERE t.name = @tableName ) as v where RowID=@schemaNameCount --Declare a cursor to retrieve column specific information --for the specified table DECLARE cursCol CURSOR FAST_FORWARD FOR SELECT column_name , data_type FROM information_schema.columns WHERE table_name = @tableName AND table_schema = @schemaName OPEN cursCol SET @string = 'INSERT INTO [' + @schemaName + '].[' + @tableName + '](' SET @stringData = '' DECLARE @colName NVARCHAR() FETCH NEXT FROM cursCol INTO @colName, @dataType PRINT @schemaName PRINT @colName IF @@fetch_status <> BEGIN PRINT 'Table ' + @tableName + ' not found, processing skipped.' CLOSE curscol DEALLOCATE curscol RETURN END WHILE @@FETCH_STATUS = BEGIN IF @dataType IN ( 'varchar', 'char', 'nchar', 'nvarchar' ) BEGIN SET @stringData = @stringData + '''''''''+ isnull(' + @colName + ','''')+'''''',''+' END ELSE IF @dataType IN ( 'text', 'ntext' ) --if the datatype --is text or something else BEGIN SET @stringData = @stringData + '''''''''+ isnull(cast(' + @colName + ' as nvarchar(max)),'''')+'''''',''+' END ELSE IF @dataType = 'money' --because money doesn't get converted --from varchar implicitly BEGIN SET @stringData = @stringData + '''convert(money,''''''+ isnull(cast(' + @colName + ' as nvarchar(max)),''.'')+''''''),''+' END ELSE IF @dataType = 'datetime' BEGIN SET @stringData = @stringData + '''convert(datetime,''''''+ isnull(cast(' + @colName + ' as nvarchar(max)),'''')+''''''),''+' END ELSE IF @dataType = 'image' BEGIN SET @stringData = @stringData + '''''''''+ isnull(cast(convert(varbinary,' + @colName + ') as varchar()),'''')+'''''',''+' END ELSE --presuming the data type is int,bit,numeric,decimal BEGIN SET @stringData = @stringData + '''''''''+ isnull(cast(' + @colName + ' as nvarchar(max)),'''')+'''''',''+' END SET @string = @string + '[' + @colName + ']' + ',' FETCH NEXT FROM cursCol INTO @colName, @dataType END --After both of the clauses are built, the VALUES clause contains a trailing comma which needs to be replaced with a single quote. The prefixed clause will only face removal of the trailing comma. DECLARE @Query NVARCHAR(MAX) -- provide for the whole query, -- you may increase the size PRINT @whereClause IF ( @whereClause IS NOT NULL AND @whereClause <> '' ) BEGIN SET @query = 'SELECT ''' + SUBSTRING(@string, , LEN(@string)) + ') VALUES(''+ ' + SUBSTRING(@stringData, , LEN(@stringData) - ) + '''+'')'' FROM ' +@schemaName+'.'+ @tableName + ' WHERE ' + @whereClause PRINT @query -- EXEC sp_executesql @query --load and run the built query --Eventually, close and de-allocate the cursor created for columns information. END ELSE BEGIN SET @query = 'SELECT ''' + SUBSTRING(@string, , LEN(@string)) + ') VALUES(''+ ' + SUBSTRING(@stringData, , LEN(@stringData) - ) + '''+'')'' FROM ' + @schemaName+'.'+ @tableName END CLOSE cursCol DEALLOCATE cursCol SET @schemaNameCount=@schemaNameCount- IF(@schemaNameCount=) BEGIN SET @QueryString=@QueryString+@query END ELSE BEGIN SET @QueryString=@QueryString+@query+' UNION ALL ' END PRINT convert(varchar(max),@schemaNameCount)+'---'+@QueryString END EXEC sp_executesql @QueryString --load and run the built query --Eventually, close and de-allocate the cursor created for columns information.

这里要声明一下,如果你有多个schema,并且每个schema下面都有同一张表,那么脚本只会生成其中一个schema下面的表insert脚本

比如我现在有三个schema,下面都有customer这个表

CREATE TABLE dbo.[customer](city int,region int) CREATE SCHEMA test CREATE TABLE test.[customer](city int,region int) CREATE SCHEMA test1 CREATE TABLE test1.[customer](city int,region int)

在执行脚本的时候他只会生成dbo这个schema下面的表insert脚本

INSERT INTO [dbo].[customer]([city],[region]) VALUES('1','2')

这个脚本有一个缺陷

无论你的表的字段是什麽数据类型,导出来的时候只能是字符

表结构

CREATE TABLE [dbo].[customer](city int,region int)

导出来的insert脚本

INSERT INTO [dbo].[customer]([city],[region]) VALUES('1','2')

我这里演示一下怎麽用

有两种方式

1、导全表数据

InsertGenerator 'customer', null

InsertGenerator 'customer', ' '

2、根据查询条件导数据

InsertGenerator 'customer', 'city=3'

或者

InsertGenerator 'customer', 'city=3 and region=8'

点击一下,选择全部

然后复制

新建一个查询窗口,然后粘贴

其实SQLServer的技巧有很多

最后,大家可以看一下代码,非常简单,如果要支持SQLServer2000,只要改一下代码就可以了

补充:创建一张测试表

CREATE TABLE testinsert (id INT,name VARCHAR(100),cash MONEY,dtime DATETIME) INSERT INTO [dbo].[testinsert] ( [id], [name], [cash], [dtime] ) VALUES ( 1, -- id - int 'nihao', -- name - varchar(100) 8.8, -- cash - money GETDATE() -- dtime - datetime ) SELECT * FROM [dbo].[testinsert]

测试

InsertGenerator 'testinsert' ,'' InsertGenerator 'testinsert' ,'name=''nihao''' InsertGenerator 'testinsert' ,'name=''nihao'' and cash=8.8'

datetime类型会有一些问题

生成的结果会自动帮你转换

INSERT INTO [dbo].[testinsert]([id],[name],[cash],[dtime]) VALUES('1','nihao',convert(money,'8.80'),convert(datetime,'02 8 2015 5:17PM'))

--------------------------------------------------------------------------------

群里的人共享的另一个脚本

IF OBJECT_ID('spGenInsertSQL','P') IS NOT NULL DROP PROC spGenInsertSQL GO CREATE proc spGenInsertSQL (@tablename varchar(256),@number BIGINT,@whereClause NVARCHAR(MAX)) as begin declare @sql varchar(8000) declare @sqlValues varchar(8000) set @sql =' (' set @sqlValues = 'values (''+' select @sqlValues = @sqlValues + cols + ' + '','' + ' ,@sql = @sql + '[' + name + '],' from (select case when xtype in (48,52,56,59,60,62,104,106,108,122,127) then 'case when '+ name +' is null then ''NULL'' else ' + 'cast('+ name + ' as varchar)'+' end' when xtype in (58,61,40,41,42) then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'cast('+ name +' as varchar)'+ '+'''''''''+' end' when xtype in (167) then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'replace('+ name+','''''''','''''''''''')' + '+'''''''''+' end' when xtype in (231) then 'case when '+ name +' is null then ''NULL'' else '+'''N'''''' + ' + 'replace('+ name+','''''''','''''''''''')' + '+'''''''''+' end' when xtype in (175) then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'cast(replace('+ name+','''''''','''''''''''') as Char(' + cast(length as varchar) + '))+'''''''''+' end' when xtype in (239) then 'case when '+ name +' is null then ''NULL'' else '+'''N'''''' + ' + 'cast(replace('+ name+','''''''','''''''''''') as Char(' + cast(length as varchar) + '))+'''''''''+' end' else '''NULL''' end as Cols,name from syscolumns where id = object_id(@tablename) ) T IF (@number!=0 AND @number IS NOT NULL) BEGIN set @sql ='select top '+ CAST(@number AS VARCHAR(6000))+' ''INSERT INTO ['+ @tablename + ']' + left(@sql,len(@sql)-1)+') ' + left(@sqlValues,len(@sqlValues)-4) + ')'' from '+@tablename print @sql END ELSE BEGIN set @sql ='select ''INSERT INTO ['+ @tablename + ']' + left(@sql,len(@sql)-1)+') ' + left(@sqlValues,len(@sqlValues)-4) + ')'' from '+@tablename print @sql END PRINT @whereClause IF ( @whereClause IS NOT NULL AND @whereClause <> '') BEGIN set @sql =@sql+' where '+@whereClause print @sql END exec (@sql) end GO

调用示例

--非dbo默认架构需注意 --支持数据类型 :bigint,int, bit,char,datetime,date,time,decimal,money, nvarchar(50),tinyint, nvarchar(max),varchar(max),datetime2 --调用示例 如果top行或者where条件为空,只需要把参数填上null spGenInsertSQL 'customer' --表名 , 2 --top 行数 , 'city=3 and didian=''大连'' ' --where 条件 --导出全表 where条件为空 spGenInsertSQL 'customer' --表名 , null --top 行数 ,null --where 条件 INSERT INTO [Department] ([DepartmentID],[Name],[GroupName],[Company],[ModifiedDate]) values (1,N'售后部',N'销售组',N'中国你好有限公司XX分公司','05 5 2015 5:58PM') INSERT INTO [Department] ([DepartmentID],[Name],[GroupName],[Company],[ModifiedDate]) values (2,N'售后部',N'销售组',N'中国你好有限公司XX分公司','05 5 2015 5:58PM')

以上所述是本文给大家分享的将表里的数据批量生成INSERT语句的存储过程 增强版,希望大家喜欢。

时间: 2024-07-30 10:54:25

将表里的数据批量生成INSERT语句的存储过程 增强版的相关文章

将表里的数据批量生成INSERT语句的存储过程 增强版_MsSql

有时候,我们需要将某个表里的数据全部或者根据查询条件导出来,迁移到另一个相同结构的库中 目前SQL Server里面是没有相关的工具根据查询条件来生成INSERT语句的,只有借助第三方工具(third party tools) 这种脚本网上也有很多,但是网上的脚本还是欠缺一些规范和功能,例如:我只想导出特定查询条件的数据,网上的脚本都是导出全表数据 如果表很大,对性能会有很大影响 这里有一个存储过程(适用于SQLServer2005 或以上版本) -- Author: <桦仔> -- Blog

根据表中数据生成insert语句的存储过程

存储过程|数据|语句 有个缺点--就是标识种子的列 也insert了 CREATE   proc spGenInsertSQL (@tablename varchar(256)) as begin declare @sql varchar(8000) declare @sqlValues varchar(8000) set @sql =' (' set @sqlValues = 'values (''+' select @sqlValues = @sqlValues + cols + ' + '

sql server根据表中数据生成insert语句

几个收藏的根据数据库生成Insert语句的存储过程[修正版] -- ======================================================--根据表中数据生成insert语句的存储过程--建立存储过程,执行spGenInsertSQL 表名--感谢playyuer----感谢szyicol-- ======================================================CREATE proc [dbo].[spGenInser

处理数据批量生成sql插入语句

最近在做一个天气预报模块,首先需要将客户端公网ip转换成所在城市,然后将所在城市名转换成对应的城市代码, 在网上找到了城市代码,但是需要处理一下,看了看,有三百多城市及对应的城市代码,想存到数据库.就想着做一个 数据处理自动生成sql语句的工具,提高效率. 直辖市 "北京","上海","天津","重庆" "101010100","101020100","101030100&qu

SQL Server生成数据发布的INSERT语句

[问题]DB结构的发布,SQL Server的管理器可以生成脚本:那么数据如何发布呢? [思路]生成INSERT INTO ... VALUES...语句 /*-- ============================================= -- Author: Yew -- Create date: 2012-05-18 -- Description: 生成数据发布的INSERT脚本 ----TestCode--------------------------- EXEC [T

SQL Server 存储过程生成insert语句

你肯定有过这样的烦恼,同样的表,不同的数据库,加入你不能执行select  insert 那么你肯定需要一条这样的存储过程,之需要传入表明,就会给你生成数据的插入语句. 当然数据表数量太大,你将最好用别的方式 Create proc [dbo].[spGenInsertSQL] (@tablename varchar(256)) as begin declare @sql varchar(8000) declare @sqlValues varchar(8000) set @sql =' ('

【SQL Sever】将SQL Sever中的一个数据表的数据导出为insert语句

例如:这SQL   Sever中的一张数据表,想要将这张数据表中的数据  转化成一个一个的insert语句存储在txt的文档中,那么不论走到那里这个insert语句一执行,我们就能将这个数据表中的数据插入到另一个地方了. 1>在新建查询中,创建一个对象,这个对象就是用来产生这个对象的,名字叫proc_insert,我们可以创建多个不重名的对象,当然也可以删除这个对象. 1 create proc proc_insert (@tablename varchar(256)) 2 as 3 begin

手把手教你-----巧用Excel批量生成SQL语句,处理大量数据

     在做系统或者做项目的时候,经常会遇到这样的要求:用户给我们发过来一些数据,要求我们把这些数据导入到数 据库中,对于少量的数据来说,用最原始的方法就可以解决,直接在SQL里面用语句来实现,但是如果有成千上万条的 数据呢?如果你还继续单独写SQL语句,估计写个几十条你就会有跳楼的冲动,其实有两种简单的方法:    1.将Excel的数据整理好,通过SQL的导入功能直接导入到数据库中,但是要保证数据库的字段和Excel的字段一致.    2.通过Excel生成相应的SQL语句,然后,放到SQ

SQL Server存储过程生成insert语句实例

你肯定有过这样的烦恼,同样的表,不同的数据库,加入你不能执行select  insert那么你肯定需要一条这样的存储过程,之需要传入表明,就会给你生成数据的插入语句.当然数据表数量太大,你将最好用别的方式 复制代码 代码如下:Create   proc [dbo].[spGenInsertSQL] (@tablename varchar(256))asbegindeclare @sql varchar(8000)declare @sqlValues varchar(8000)set @sql =