码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-02-07 17:09:14      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:

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

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

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

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

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

 

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

=============================================
-- Author:      <桦仔>
-- Blog:        <http://www.cnblogs.com/lyhabc/>
-- Create date: <2014/10/18>
-- 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 --如果有多个schema,选择其中一个schema SELECT TOP 1 @schemaName = s.name FROM sys.tables t INNER JOIN sys.schemas s ON t.schema_id = s.schema_id WHERE t.name = @tableName ORDER BY [s].[schema_id] --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(500) FETCH NEXT FROM cursCol INTO @colName, @dataType PRINT @schemaName PRINT @colName IF @@fetch_status <> 0 BEGIN PRINT Table + @tableName + not found, processing skipped. CLOSE curscol DEALLOCATE curscol RETURN END WHILE @@FETCH_STATUS = 0 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)),‘‘0.0000‘‘)+‘‘‘‘‘‘),‘‘+ END ELSE IF @dataType = datetime BEGIN SET @stringData = @stringData + ‘‘‘convert(datetime,‘‘‘‘‘‘+ isnull(cast( + @colName + as nvarchar(max)),‘‘0‘‘)+‘‘‘‘‘‘),‘‘+ END ELSE IF @dataType = image BEGIN SET @stringData = @stringData + ‘‘‘‘‘‘‘‘‘+ isnull(cast(convert(varbinary, + @colName + ) as varchar(6)),‘‘0‘‘)+‘‘‘‘‘‘,‘‘+ END ELSE --presuming the data type is int,bit,numeric,decimal BEGIN SET @stringData = @stringData + ‘‘‘‘‘‘‘‘‘+ isnull(cast( + @colName + as nvarchar(max)),‘‘0‘‘)+‘‘‘‘‘‘,‘‘+ 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, 0, LEN(@string)) + ) VALUES(‘‘+ + SUBSTRING(@stringData, 0, LEN(@stringData) - 2) + ‘‘‘+‘‘)‘‘ FROM + @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, 0, LEN(@string)) + ) VALUES(‘‘+ + SUBSTRING(@stringData, 0, LEN(@stringData) - 2) + ‘‘‘+‘‘)‘‘ FROM + @tableName EXEC sp_executesql @query --load and run the built query --Eventually, close and de-allocate the cursor created for columns information. END CLOSE cursCol DEALLOCATE cursCol

 

这里要声明一下,如果你有多个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,只要改一下代码就可以了

 

如有不对的地方,欢迎大家拍砖o(∩_∩)o 

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

标签:

原文地址:http://www.cnblogs.com/lyhabc/p/4278937.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!