之前,在codeproject发表过一篇关于用现有表中数据创建insert的sql语句的存储过程,今天将其搬到这里来,注意本存储过程仅适用于sql server。
介绍
一些时候,你想导出一些现有表中记录的sql脚本以便你可以插入这些数据到另一个数据库的相似表中。有很多方式可以做到,现在,我将跟大家分享一个存储过程来一起实现它。希望对各位有所帮助。
代码
首先,请在你的sql server数据库中创建如下名为[dbo].[sp_createinsertscript]存储过程
[dbo].[sp_createinsertscript] content:
--=============================================
-- author: mark kang
-- company: www.ginkia.com
-- create date: 2016-03-06
-- description: generat the insert sql script according to the data in the specified table.
-- it does not support the columns with timestamp,text,image.
-- demo : exec sp_createinsertscript '[dbo].[country]','[continent_name]=''north america'''
-- change history:
-- 1.2016-03-06 created and published
-- 2.2016-03-08 based on mike's suggestions, i optimized the codes
-- 3.2019-03-09 1)add code lines to avoid error when @con is empty string
-- 2)based on lukas macedo's suggetstions, add surrounding brackets for column name
-- 3)simplify when...case
-- =============================================
create proc [dbo].[sp_createinsertscript] (
@tablename nvarchar(256) -- table name
,@con nvarchar(400) -- condition to filter data
,@ignoreidentitycol bit=0 --indicate if ignore columne with identity
,@isdebug bit=0 --indicate if this is used to debug. when 1,output the internal sql string
)
as
begin
set nocount on
declare @sqlstr nvarchar(max);
declare @valuestr1 nvarchar(max);
declare @colsstr nvarchar(max);
select @sqlstr='select ''insert '+@tablename;
select @valuestr1='';
select @colsstr='(';
select @valuestr1='values (''+';
if rtrim(ltrim(@con))=''
set @con='1=1';
select @valuestr1=@valuestr1+col+'+'',''+'
,@colsstr=@colsstr+'['+name +'],'
from (
select
case
/* xtype=173 'binary'
xtype=165 'varbinary'*/
when sc.xtype in (173,165) then 'case when ['+sc.name+'] is null then ''null'' else '+'convert(nvarchar('+convert(nvarchar(4),sc.[length]*2+2)+'),['+sc.name +'])'+' end'
/*xtype=104 'bit'*/
when sc.xtype =104 then 'case when ['+sc.name+'] is null then ''null'' else '+'convert(nvarchar(1),['+sc.name +'])'+' end'
/*xtype=61 'datetime'
xtype=58 'smalldatetime'*/
when sc.xtype in(58,61) then 'case when ['+sc.name+'] is null then ''null'' else '+'''n''''''+'+'convert(nvarchar(23),'+sc.name +',121)'+ '+'''''''''+' end'
/*xtype=175 'char'
xtype=36 'uniqueidentifier'
xtype=167 'varchar'
xtype=231 'nvarchar'
xtype=239 'nchar'*/
when sc.xtype in (36,175,167,231,239) then 'case when ['+sc.name+'] is null then ''null'' else '+'''n''''''+'+'replace(['+sc.name+'],'''''''','''''''''''')' + '+'''''''''+' end'
/*xtype=106 'decimal'
xtype=108 'numeric'*/
when sc.xtype in(106,108) then 'case when ['+sc.name+'] is null then ''null'' else '+'convert(nvarchar('+convert(nvarchar(4),sc.xprec+2)+'),['+sc.name +'])'+' end'
/*xtype=59 'real'
xtype=62 'float'*/
when sc.xtype in (59,62) then 'case when ['+sc.name+'] is null then ''null'' else '+'convert(nvarchar(23),'+sc.name +',2)'+' end'
/*xtype=48 'tinyint'
xtype=52 'smallint'
xtype=56 'int'
xtype=127 'bigint'
xtype=122 'smallmoney'
xtype=60 'money'*/
when sc.xtype in (48,52,56,127,122,60) then 'case when ['+sc.name+'] is null then ''null'' else '+'convert(nvarchar(23),['+sc.name +'])'+' end'
else '''null'''
end as col
,sc.colid
,sc.name
from syscolumns as sc
where sc.id = object_id(@tablename)
and sc.xtype <>189 --xtype=189 'timestamp'
and sc.xtype <>34 --xtype=34 'image'
and sc.xtype <>35 --xtype= 35 'text'
and (columnproperty(sc.id, sc.name, 'isidentity') = 0 or @ignoreidentitycol=0)
) as t
order by colid;
set @colsstr=left(@colsstr,len(@colsstr)-1)+') ';
set @valuestr1=left(@valuestr1,len(@valuestr1)-3)+')''';
select @sqlstr=@sqlstr+@colsstr+@valuestr1+' as sql from '+@tablename + ' where 1=1 and ' + isnull(@con,'1=1');
if @isdebug=1
begin
print '1.columns string: '+ @colsstr;
print '2.values string: '+ @valuestr1
print '3.'+@sqlstr;
end
exec( @sqlstr);
set nocount off
end
go
示例
下来,我举一个例子帮大家理解如何使用它,假设在你的数据库中有个表country(国家),你想得到这个表中一些数据记录的用于插入的sql语句,记录筛选条件是列continent_name(洲名)的值为north america的记录。表的创建脚本如下:
create table [dbo].[country](
[geoname_id] [varchar](50) null,
[locale_code] [varchar](50) null,
[continent_code] [varchar](50) null,
[continent_name] [varchar](50) null,
[country_iso_code] [varchar](50) null,
[country_name] [varchar](50) null
) on [primary]
下来,通过调用你创建的存储过程,用如下语句执行以便产生你想要的sql的插入(insert)语句。调用执行脚本如下:
exec sp_createinsertscript '[dbo].[country]','[continent_name]=''north america'''
执行之后,你会得到你想要结果,下图为我电脑的截图。
现在,你就可以拷贝这些结果或者通过右键菜单的选项保持输出结果为一个查询或者文本文件,以便你下来使用。thanks!