加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

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

发布时间:2020-12-12 09:17:11 所属栏目:MsSql教程 来源:网络整理
导读:有时候,我们需要将某个表里的数据全部或者根据查询条件导出来,迁移到另一个相同结构的库中 目前SQL Server里面是没有相关的工具根据查询条件来生成INSERT语句的,只有借助第三方工具(third party tools) 这种脚本网上也有很多,但是网上的脚本还是欠缺一

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

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

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

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

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

-- Blog: -- 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(@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这个表

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


这个脚本有一个缺陷

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

表结构

导出来的insert脚本

我这里演示一下怎麽用

有两种方式

1、导全表数据




2、根据查询条件导数据


或者

点击一下,选择全部


然后复制


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

其实SQLServer的技巧有很多

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

补充:创建一张测试表

测试

datetime类型会有一些问题

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

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

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

'') BEGIN set @sql =@sql+' where '+@whereClause print @sql END exec (@sql) end GO

调用示例

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读