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

将表里的数据批量生成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 statementDECLARE @stringData NVARCHAR(MAX) --for storing the data (VALUES) related statementDECLARE @dataType NVARCHAR(MAX) --data types returned for respective columnsDECLARE @schemaName NVARCHAR(MAX) --schema name returned from sys.schemasDECLARE @schemaNameCount int--shema countDECLARE @QueryString  NVARCHAR(MAX) -- provide for the whole query, set @QueryString=' '--如果有多个schema,选择其中一个schemaSELECT @schemaNameCount=COUNT(*)FROM    sys.tables tINNER JOIN sys.schemas s ON t.schema_id = s.schema_idWHERE   t.name = @tableNameWHILE(@schemaNameCount>0)BEGIN--如果有多个schema,依次指定select @schemaName = name from (SELECT ROW_NUMBER() over(order by  s.schema_id) RowID,s.nameFROM    sys.tables tINNER JOIN sys.schemas s ON t.schema_id = s.schema_idWHERE   t.name =  @tableName) as vwhere RowID=@schemaNameCount--Declare a cursor to retrieve column specific information --for the specified tableDECLARE cursCol CURSOR FAST_FORWARDFORSELECT  column_name ,data_typeFROM    information_schema.columnsWHERE   table_name = @tableNameAND table_schema = @schemaNameOPEN cursColSET @string = 'INSERT INTO [' + @schemaName + '].[' + @tableName + ']('SET @stringData = ''DECLARE @colName NVARCHAR(500)FETCH NEXT FROM cursCol INTO @colName, @dataTypePRINT @schemaNamePRINT @colNameIF @@fetch_status <> 0BEGINPRINT 'Table ' + @tableName + ' not found, processing skipped.'CLOSE curscolDEALLOCATE curscolRETURNENDWHILE @@FETCH_STATUS = 0BEGINIF @dataType IN ( 'varchar', 'char', 'nchar', 'nvarchar' )BEGINSET @stringData = @stringData + '''''''''+isnull(' + @colName + ','''')+'''''',''+'ENDELSEIF @dataType IN ( 'text', 'ntext' ) --if the datatype --is text or something else BEGINSET @stringData = @stringData + '''''''''+isnull(cast(' + @colName + ' as nvarchar(max)),'''')+'''''',''+'ENDELSEIF @dataType = 'money' --because money doesn't get converted --from varchar implicitlyBEGINSET @stringData = @stringData+ '''convert(money,''''''+isnull(cast(' + @colName+ ' as nvarchar(max)),''0.0000'')+''''''),''+'ENDELSEIF @dataType = 'datetime'BEGINSET @stringData = @stringData+ '''convert(datetime,''''''+isnull(cast(' + @colName + ' as nvarchar(max)),''0'')+''''''),''+'ENDELSEIF @dataType = 'image'BEGINSET @stringData = @stringData + '''''''''+isnull(cast(convert(varbinary,' + @colName + ') as varchar(6)),''0'')+'''''',''+'ENDELSE --presuming the data type is int,bit,numeric,decimal BEGINSET @stringData = @stringData + '''''''''+isnull(cast(' + @colName + ' as nvarchar(max)),''0'')+'''''',''+'ENDSET @string = @string + '[' + @colName + ']' + ','FETCH NEXT FROM cursCol INTO @colName, @dataTypeEND
--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 sizePRINT @whereClauseIF ( @whereClause IS NOT NULLAND @whereClause <> '')BEGIN  SET @query = 'SELECT ''' + SUBSTRING(@string, 0, LEN(@string))+ ') VALUES(''+ ' + SUBSTRING(@stringData, 0,LEN(@stringData) - 2)+ '''+'')'' FROM ' +@schemaName+'.'+ @tableName + ' WHERE ' + @whereClausePRINT @query-- EXEC sp_executesql @query --load and run the built query
--Eventually, close and de-allocate the cursor created for columns information.ENDELSEBEGIN SET @query = 'SELECT ''' + SUBSTRING(@string, 0, LEN(@string))+ ') VALUES(''+ ' + SUBSTRING(@stringData, 0,LEN(@stringData) - 2)+ '''+'')'' FROM ' + @schemaName+'.'+ @tableNameENDCLOSE cursColDEALLOCATE cursColSET @schemaNameCount=@schemaNameCount-1IF(@schemaNameCount=0)BEGINSET @QueryString=@QueryString+@queryENDELSEBEGINSET @QueryString=@QueryString+@query+' UNION ALL 'ENDPRINT convert(varchar(max),@schemaNameCount)+'---'+@QueryStringENDEXEC 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 - moneyGETDATE()  -- 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'))

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

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

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

    文章继续 桦仔兄的文章 将表里的数据批量生成INSERT语句的存储过程 增强版 继续增强... 本来打算将该内容回复于桦仔兄的文章的下面的,但是不知为何博客园就是不让提交!.... 所以在这里贴出来吧 ...

  2. Excel 数据批量生成SQL语句

    假设excel表格中有三列(A.B.C)数据,我们希望可以利用这三列数据批量生成SQL语句 第一步:新增D列,在D1中输入公式:=CONCATENATE("insert into user  ...

  3. 批量生成insert语句的方法(word转excel,excel用公式生成insert)

    拿到的是word文档: 一.将word转为excel文档(我使用中文格式的:作为列分隔符): 先将这部分复制粘贴到excel中: 然后选中这一列 完成分列 如果选择下一步,那就默认或者文本方式都可以, ...

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

    sql server根据表中数据生成insert语句 -- ====================================================== --根据表中数据生成inser ...

  5. 【excel数据转脚本批量插入数据库】将excel中的数据快速生成insert脚本

    1.excel快速批量生成insert语句 打开excel,在空白的列插入以下函数 ="INSERT INTO TABLENAME(UserId,UserName,UserPwd) VALU ...

  6. 如何使用excel批量生成sql语句

    使用excel批量生成sql语句 1.将sql数据导出到excel文件 2.去除execl中多余的空格 设置单元格格式(如果不定义数据格式,去除数据前的空格后数据前的00会消失,如"001& ...

  7. 引用excel数据快速生成sql语句

    有时候我们需要把excel表格中的数据更新,或者插入到数据库表格中,这种往往是需要每一行写一个代码的,或者把excel导入数据库后再写SQL语句进行下一步的更新或者插入的处理. 现在介绍一个我摸索出来 ...

  8. Excel生成insert 语句

    选中表格最后一行,改为自己需要的数据,然后选中需要填充的行,比如   J1:J200 按下Ctrl+D,即可完成填充,生成insert语句,复制出来即可执行. =CONCATENATE("i ...

  9. datatable如何生成级联数据_如何把Excel表数据批量生成条形码

    条形码属于一维条码,是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符,条形码的种类比较多,比如常用的Code128码,Code39码,Code93码,EAN-13码, ...

最新文章

  1. IOS沙盒Files目录说明和常用操作
  2. hdu1394线段树点修改,区间求和
  3. Dotnet core使用JWT认证授权最佳实践(一)
  4. css 容器内 div 底部,CSS:在div容器的底部放置一個div容器
  5. android捕获全局异常,并对异常做出处理
  6. 符号级别(二)--实际应用
  7. javascript之生成一个指定范围内的随机数
  8. 从声学模型算法角度总结 2016 年语音识别的重大进步
  9. java 27 - 7 反射之 通过反射越过泛型检查
  10. 使用Lettuce执行命令,应该有多个返回值却只取到一个。
  11. android jni javah,JAVAH找不到类(android ndk)
  12. FU-A STAP-A
  13. 行人跟踪之身份识别(一)
  14. oracle32位迁移64位,Windows下Oracle10g32位遷移到11g64位
  15. matlab正弦余弦与圆的关系
  16. 连接mysql提示不允许连接_用数据库工具连接mysql出现不允许连接的解决办法
  17. 当你迷茫时,请努力做好现在的工作
  18. python读word文档计算字数,Python 实现word count 简单计算源代码中的字符数、词数、行数。...
  19. C语言中的switch语句
  20. 教程:科研论文绘制流程图并导入Latex

热门文章

  1. 浅谈软件自动化集成测试的流程
  2. [转] JavaScript仿淘宝智能浮动
  3. 7——ThinkPhp中的响应和重定向:
  4. 用es6 (proxy 和 reflect)轻松实现 观察者模式
  5. unix网络编程之简介
  6. 引用与传递——内存分析
  7. jQuery的选择器(一)
  8. Bloom Filter:海量数据的HashSet
  9. Xamarin SimplerCursorAdapter 适配器(三)
  10. Sierpinski三角形