|

Introduction
The stored procedure InsertGenerator generates the INSERT..VALUES statements for the specified table name.
Background
SQL Server doesn’t allow generation of INSERT statements for the table data, when Generate SQL Script option is selected. The workaround is to make use of DTS for transferring data across servers. However, there exists a need to generate INSERT statements from the tables for porting data. Simplest example is when small or large amount of data needs to be taken out on a removable storage media and copied to a remote location, INSERT..VALUES statements come handy.
Using the codeThis small yet useful stored procedure will take as parameter the table name and generates the INSERT SQL statements for the same. The output can be redirected to either text format (Ctrl+T in Query Analyzer) or Output to a text file. The procedure accepts an input varchar type parameter that has to be the table name under consideration for statement generation.
CREATE PROC InsertGenerator
(@tableName varchar(100)) 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 cursCol CURSOR FAST_FORWARD FOR
SELECT column_name,data_type FROM information_schema.columns
WHERE table_name = @tableName
OPEN cursCol
DECLARE @string nvarchar(3000)
DECLARE @stringData nvarchar(3000)
DECLARE @dataType nvarchar(1000)
SET @string='INSERT '+@tableName+'('
SET @stringData=''
DECLARE @colName nvarchar(50)
FETCH NEXT FROM cursCol INTO @colName,@dataType
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')
BEGIN
SET @stringData=@stringData+'''''''''+
isnull(cast('+@colName+' as varchar(2000)),'''')+'''''',''+'
END
ELSE
IF @dataType = 'money'
BEGIN
SET @stringData=@stringData+'''convert(money,''''''+
isnull(cast('+@colName+' as varchar(200)),''0.0000'')+''''''),''+'
END
ELSE
IF @dataType='datetime'
BEGIN
SET @stringData=@stringData+'''convert(datetime,''''''+
isnull(cast('+@colName+' as varchar(200)),''0'')+''''''),''+'
END
ELSE
IF @dataType='image'
BEGIN
SET @stringData=@stringData+'''''''''+
isnull(cast(convert(varbinary,'+@colName+')
as varchar(6)),''0'')+'''''',''+'
END
ELSE
BEGIN
SET @stringData=@stringData+'''''''''+
isnull(cast('+@colName+' as varchar(200)),''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(4000)
SET @query ='SELECT '''+substring(@string,0,len(@string)) + ')
VALUES(''+ ' + substring(@stringData,0,len(@stringData)-2)+'''+'')''
FROM '+@tableName
exec sp_executesql @query
Eventually, close and de-allocate the cursor created for columns information. CLOSE cursCol
DEALLOCATE cursCol
After the procedure is compiled and created, just run it in Query Analyzer by using the following syntax: InsertGenerator <tablename>
E.g.: USE pubs
GO
InsertGenerator employee
GO
Then copy the INSERT statements and run’em in the query analyzer.
Before the INSERTs are run, SET IDENTITY_INSERT <TABLENAME>ON should be passed for adding values in an identity-based column.
Points of Interest
D: T-SQL lovers might wish to extend this procedure for providing support for binary data types such as IMAGE etc.
History
- Ver 0.1b added Dec 5, 03.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 34 (Total in Forum: 34) (Refresh) | FirstPrevNext |
|
 |
|
|
create PROCEDURE [dbo].[procUtils_InsertGenerator] ( @domain_user varchar(50), @tableName varchar(100) ) as --Declare a cursor to retrieve column specific information for the specified table DECLARE cursCol CURSOR FAST_FORWARD FOR --old takes the PK's SELECT column_name,data_type FROM information_schema.columns WHERE table_name = @tableName
/* NEW without PK's */ select object_name(c.object_id) "TABLE_NAME", c.name "COLUMN_NAME", s.name "DATA_TYPE" from sys.columns c join sys.systypes s on (s.xtype = c.system_type_id) where object_name(c.object_id) in (select name from sys.tables where name not like 'sysdiagrams') AND object_name(c.object_id) in (select name from sys.tables where [name]=@tableName ) and c.is_identity=0
OPEN cursCol DECLARE @string nvarchar(3000) --for storing the first half of INSERT statement DECLARE @stringData nvarchar(3000) --for storing the data (VALUES) related statement DECLARE @dataType nvarchar(1000) --data types returned for respective columns DECLARE @IDENTITY_STRING nvarchar ( 100 ) SET @IDENTITY_STRING = ' ' select @IDENTITY_STRING SET @string='INSERT '+@tableName+'(' SET @stringData='' DECLARE @colName nvarchar(50) FETCH NEXT FROM cursCol INTO @tableName , @colName,@dataType 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+','''')+'''''',''+' SET @stringData=@stringData+''''+'''+isnull('''''+'''''+'+@colName+'+'''''+''''',''NULL'')+'',''+' END ELSE if @dataType in ('text','ntext') --if the datatype is text or something else BEGIN SET @stringData=@stringData+'''''''''+isnull(cast('+@colName+' as varchar(2000)),'''')+'''''',''+' END ELSE IF @dataType = 'money' --because money doesn't get converted from varchar implicitly BEGIN SET @stringData=@stringData+'''convert(money,''''''+isnull(cast('+@colName+' as varchar(200)),''0.0000'')+''''''),''+' END ELSE IF @dataType='datetime' BEGIN --SET @stringData=@stringData+'''convert(datetime,''''''+isnull(cast('+@colName+' as varchar(200)),''0'')+''''''),''+' --SELECT 'INSERT Authorizations(StatusDate) VALUES('+'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations --SET @stringData=@stringData+'''convert(money,''''''+isnull(cast('+@colName+' as varchar(200)),''0.0000'')+''''''),''+' SET @stringData=@stringData+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200),'+@colName+',121)+'''''+''''',''NULL'')+'',121),''+' -- 'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations 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 varchar(200)),''0'')+'''''',''+' --SET @stringData=@stringData+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200),'+@colName+',121)+'''''+''''',''NULL'')+'',121),''+' SET @stringData=@stringData+''''+'''+isnull('''''+'''''+convert(varchar(200),'+@colName+')+'''''+''''',''NULL'')+'',''+' END SET @string=@string+@colName+',' FETCH NEXT FROM cursCol INTO @tableName , @colName,@dataType END DECLARE @Query nvarchar(4000) SET @query ='SELECT '''+substring(@string,0,len(@string)) + ') VALUES(''+ ' + substring(@stringData,0,len(@stringData)-2)+'''+'')'' FROM '+@tableName exec sp_executesql @query --select @query CLOSE cursCol DEALLOCATE cursCol /* use MyDataBase go DECLARE @RC int DECLARE @domain_user varchar(50) DECLARE @tableName varchar(100) -- TODO: Set parameter values here. set @domain_user='myDomainUser' set @tableName = 'MyTableName' EXECUTE @RC = [POC].[dbo].[procUtils_InsertGenerator] @domain_user ,@tableName */
<div class="ForumMod">modified on Wednesday, November 19, 2008 1:41 PM</div>
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
<code> -- MSSQL 2005 declare @table_name nvarchar(100) declare @columns nvarchar(max) declare @values nvarchar(max) declare @identity bit declare @sql nvarchar(max)
set @table_name = 'MyTable' set @columns ='' set @values ='' set @identity = 0
select @identity = @identity | columnproperty(object_id(@table_name), column_name, 'IsIdentity'), @columns = @columns + ',' + '['+column_name+']', @values = @values + '+'',''+isnull(master.dbo.fn_varbintohexstr(cast(['+column_name+'] as varbinary(max))),''NULL'')' from information_schema.columns where table_name = @table_name and data_type != 'timestamp'
set @sql = 'select ''insert into [' + @table_name + '] (' + substring(@columns,2,len(@columns)) + ') values (''+' + substring(@values,6,len(@values)) + '+'')'' from ' + @table_name if @identity=1 print 'set identity_insert [' + @table_name + '] on' exec sp_executesql @sql if @identity=1 print 'set identity_insert [' + @table_name + '] off' </code>
|
| Sign In·View Thread·PermaLink | 4.50/5 (4 votes) |
|
|
|
 |
|
|
I ran the SP and it did produced an inserts that breaks if the fields of type varchar include the (') character. Here is an updated version
Hany~
-- ---
SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
ALTER PROC InsertGenerator (@tableName varchar(100)) as
--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 OPEN cursCol DECLARE @string nvarchar(3000) --for storing the first half of INSERT statement DECLARE @stringData nvarchar(3000) --for storing the data (VALUES) related statement DECLARE @dataType nvarchar(1000) --data types returned for respective columns SET @string='INSERT '+@tableName+'(' SET @stringData=''
DECLARE @colName nvarchar(50)
FETCH NEXT FROM cursCol INTO @colName,@dataType 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+','''')+'''''',''+' -- SET @stringData=@stringData+''''+'''+isnull('''''+'''''+REPLACE('+ @colName +',char(39), (char(39) + char(39)+ char(39))) +'''''+''''',''NULL'')+'',''+'
END ELSE if @dataType in ('text','ntext') --if the datatype is text or something else BEGIN SET @stringData=@stringData+'''''''''+isnull(cast('+@colName+' as varchar(2000)),'''')+'''''',''+' END ELSE IF @dataType = 'money' --because money doesn't get converted from varchar implicitly BEGIN SET @stringData=@stringData+'''convert(money,''''''+isnull(cast('+@colName+' as varchar(200)),''0.0000'')+''''''),''+' END ELSE IF @dataType='datetime' BEGIN --SET @stringData=@stringData+'''convert(datetime,''''''+isnull(cast('+@colName+' as varchar(200)),''0'')+''''''),''+' --SELECT 'INSERT Authorizations(StatusDate) VALUES('+'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations --SET @stringData=@stringData+'''convert(money,''''''+isnull(cast('+@colName+' as varchar(200)),''0.0000'')+''''''),''+' SET @stringData=@stringData+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200),'+@colName+',121)+'''''+''''',''NULL'')+'',121),''+' -- 'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations 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 varchar(200)),''0'')+'''''',''+' --SET @stringData=@stringData+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200),'+@colName+',121)+'''''+''''',''NULL'')+'',121),''+' SET @stringData=@stringData+''''+'''+isnull('''''+'''''+convert(varchar(200),'+@colName+')+'''''+''''',''NULL'')+'',''+' END
SET @string=@string+@colName+','
FETCH NEXT FROM cursCol INTO @colName,@dataType END DECLARE @Query nvarchar(4000) SET @query ='SELECT '''+substring(@string,0,len(@string)) + ') VALUES(''+ ' + substring(@stringData,0,len(@stringData)-2) +'''+'')'' FROM '+@tableName exec sp_executesql @query CLOSE cursCol DEALLOCATE cursCol
GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This SP does not take into account Auto-Increment PK Columns, so the generated sql statements have to be modified to work.
Still a usefull SP though!
|
| Sign In·View Thread·PermaLink | 2.67/5 (2 votes) |
|
|
|
 |
|
|
 |
|
|
Thanks for the script. It was very helpful to me. Saved a lot of time. Works like a marvel.
I am trying to generate INSERT script where each statement becomes more than 8192 character. It does not show on query window, nor does it get writen properly in output file properly. Statements get truncated because there are too many texts in the table.
Do you have any solution?
Regards, Omar AL Zabir Visual C# MVP
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
This nearly did what I needed it to do, except for escaping the quotes within the data. Perhaps you could update the stored procedure to fix this..
|
| Sign In·View Thread·PermaLink | 1.50/5 (2 votes) |
|
|
|
 |
|
|
I had some trouble generating the insert statements on converting to varchar because some of the collumns in my database used a different COLLATE.
I therefor enhanced the statements with the COLLATE clauses needed:
SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
ALTER PROC InsertGenerator (@tableName varchar(100)) as
--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 OPEN cursCol DECLARE @string nvarchar(3000) --for storing the first half of INSERT statement DECLARE @stringData nvarchar(3000) --for storing the data (VALUES) related statement DECLARE @dataType nvarchar(1000) --data types returned for respective columns SET @string='INSERT ' + @tableName + '(' SET @stringData=''
DECLARE @colName nvarchar(50)
FETCH NEXT FROM cursCol INTO @colName,@dataType
IF @@fetch_status<>0 begin print 'Table '+@tableName+' not found, processing skipped.' close curscol deallocate curscol return END
WHILE @@FETCH_STATUS=0 BEGIN print @colname + ' ' + @datatype IF @dataType in ('varchar','char','nchar','nvarchar') BEGIN SET @stringData=@stringData+''''+'''+isnull('''''+'''''+REPLACE('+@colName+','''''+''''','''''+'''''+'''''+''''')+'''''+''''',''NULL'')+'',''+' --SET @stringData=@stringData+'''''''''+isnull(['+@colName+'],'''')+'''''',''+' --SET @stringData=@stringData+''''+'''+isnull('''''+'''''+'+@colName+'+'''''+''''',''NULL'')+'',''+' END ELSE if @dataType in ('text','ntext') --if the datatype is text or something else BEGIN SET @stringData=@stringData+'''''''''+isnull(REPLACE(cast('+@colName+' as varchar(2000))COLLATE database_default ,'''''+''''','''''+'''''+'''''+'''''),'''')+'''''',''+' --SET @stringData=@stringData+'''''''''+isnull(cast(['+@colName+'] as varchar(2000)),'''')+'''''',''+' END ELSE IF @dataType = 'money' --because money doesn't get converted from varchar implicitly BEGIN SET @stringData=@stringData+'''convert(money,''''''+isnull(cast(['+@colName+'] as varchar(200)) COLLATE database_default ,''0.0000'')+''''''),''+' END ELSE IF @dataType='timestamp' BEGIN SET @stringData=@stringData+'''''+ ''NULL'' +'',''+' END
ELSE IF @dataType='datetime' BEGIN --SET @stringData=@stringData+'''convert(datetime,''''''+isnull(cast('+@colName+' as varchar(200)),''0'')+''''''),''+' --SELECT 'INSERT Authorizations(StatusDate) VALUES('+'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations --SET @stringData=@stringData+'''convert(money,''''''+isnull(cast('+@colName+' as varchar(200)),''0.0000'')+''''''),''+' SET @stringData=@stringData+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200) COLLATE database_default ,['+@colName+'],121)+'''''+''''',''NULL'')+'',121),''+' -- 'convert(datetime,'+isnull(''''+convert(varchar(200),StatusDate,121)+'''','NULL')+',121),)' FROM Authorizations END ELSE IF @dataType='image' BEGIN SET @stringData=@stringData+'''''''''+isnull(cast(convert(varbinary,['+@colName+']) as varchar(6)) COLLATE database_default,''0'')+'''''',''+' END ELSE --presuming the data type is int,bit,numeric,decimal BEGIN --print @colname + 'other datatype' SET @stringData=@stringData+''''+ '''+isnull(convert(varchar(200),['+ @colName + ']) COLLATE database_default,''NULL'')+'',''+' --SET @stringData=@stringData+'''convert(datetime,'+'''+isnull('''''+'''''+convert(varchar(200),'+@colName+',121)+'''''+''''',''NULL'')+'',121),''+' --SET @stringData=@stringData+''''+'''+isnull('''''+'''''+convert(varchar(200),'+@colName+')+'''''+''''',''NULL'')+'',''+' END
SET @string=@string+@colName+','
FETCH NEXT FROM cursCol INTO @colName,@dataType END print 'All fields fetched' DECLARE @Query nvarchar(4000) SET @query ='SELECT '''+substring(@string,0,len(@string)) + ') VALUES(''+ ' + substring(@stringData,0,len(@stringData)-2)+'''+'')'' FROM '+@tableName print @query exec sp_executesql @query --select @query
CLOSE cursCol DEALLOCATE cursCol
GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
Milo van der Linden GIS consultant AVD-ict
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Your code does not accept null values to be inserted in datetime fields instead it generates 01/01/1900. How can I allow the code to insert nulls using the code? Thanks
Yomi
|
| Sign In·View Thread·PermaLink | 1.67/5 (3 votes) |
|
|
|
 |
|
|
 |
|
|
 |
|
|
I'm very new to SQL and this program has been great. I'm currently trying to make the output for int,bit,numeric and decimal come without the quotes, Any suggestions?
Thanks. Jelias
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Ok,I have found the answer:
SET @stringData=@stringData+''''+'''+isnull(convert(varchar200),'+@colName+'),''NULL'')+'',''+'
Thanks!!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Often, you will encounter a column name that matches a SQL keyword (e.g., Desc). The column name must then be enclosed in brackets in sql scripts.
I had to modify this stored proc by putting brackets around the @colName param in the code ( e.g., ...+['+@colName+']+....)
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
Hi,
I downloaded this script & it works fine, but not returns full output, INSERT statement truncated in between, see the below rows generated by this script,
INSERT tabemployee(vcempid,vcempname,vcemplastname,dtdob,dtdoh,vcssno,vcaddress,vccity,vcstate,vccountry,vczipcode,vcphone1,vcphone2,vcroleid,vcusername,vcemptype,vccustid,vcwhid,cdeleted) VALUES('10','Puru','V',convert(datetime,'1979-02-23 00:00:00.000',1 INSERT tabemployee(vcempid,vcempname,vcemplastname,dtdob,dtdoh,vcssno,vcaddress,vccity,vcstate,vccountry,vczipcode,vcphone1,vcphone2,vcroleid,vcusername,vcemptype,vccustid,vcwhid,cdeleted) VALUES('2','admin',NULL,convert(datetime,NULL,121),convert(datetime INSERT tabemployee(vcempid,vcempname,vcemplastname,dtdob,dtdoh,vcssno,vcaddress,vccity,vcstate,vccountry,vczipcode,vcphone1,vcphone2,vcroleid,vcusername,vcemptype,vccustid,vcwhid,cdeleted) VALUES('3','cfs','cfs',convert(datetime,'1900-01-01 00:00:00.000',1 INSERT tabemployee(vcempid,vcempname,vcemplastname,dtdob,dtdoh,vcssno,vcaddress,vccity,vcstate,vccountry,vczipcode,vcphone1,vcphone2,vcroleid,vcusername,vcemptype,vccustid,vcwhid,cdeleted) VALUES('4','Smith','Wilber',convert(datetime,'1900-01-01 00:00:00.0 INSERT tabemployee(vcempid,vcempname,vcemplastname,dtdob,dtdoh,vcssno,vcaddress,vccity,vcstate,vccountry,vczipcode,vcphone1,vcphone2,vcroleid,vcusername,vcemptype,vccustid,vcwhid,cdeleted) VALUES('5','Harrison','Ford',convert(datetime,'1900-01-01 00:00:00. INSERT tabemployee(vcempid,vcempname,vcemplastname,dtdob,dtdoh,vcssno,vcaddress,vccity,vcstate,vccountry,vczipcode,vcphone1,vcphone2,vcroleid,vcusername,vcemptype,vccustid,vcwhid,cdeleted) VALUES('6','John','Sanders',convert(datetime,'1900-01-01 00:00:00.0
what could be the problem,
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Try this - in query analyser, select Tools, Options, select the Results tab then change the "Maximum characters per column:" value to something bigger than 256. Worked for me.
|
| Sign In·View Thread·PermaLink | 3.00/5 (3 votes) |
|
|
|
 |
|
|
Hi Sumit, ...great job!
This is a suggestion of how to change your st. proc to handle the "'" within text based datatypes:
a) varchar,char,nchar,nvarchar SET @stringData=@stringData+''''+'''+isnull('''''+'''''+REPLACE('+@colName+','''''+''''','''''+'''''+'''''+''''')+'''''+''''',''NULL'')+'',''+'
b) text,ntext: SET @stringData=@stringData+'''''''''+isnull(REPLACE(cast('+@colName+' as varchar(2000)),'''''+''''','''''+'''''+'''''+'''''),'''')+'''''',''+'
I have tested and it works.
Claudiu
|
| Sign In·View Thread·PermaLink | 4.50/5 (2 votes) |
|
|
|
 |
|
|
Thanks Claudiu
I was struggling with this problem for about half an hour before I noticed your excellent solution, much appreciated - I should have read the threads first
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
| | |