tags:

views:

88

answers:

3

Does anybody know of a proc or script which will generate any row into an insert statement into the same table?

Basically, I'd like to call something like

exec RowToInsertStatement 'dbo.user', 45;

And the following code would be output

insert into dbo.MyTable( FirstName, LastName, Position)
values( 'John', 'MacIntyre', 'Software Consultant');

I realize I could

insert into dbo.MyTable
select * from dbo.MyTable where id=45;

But this obviously won't work, because the ID column will complain (I hope it complains) and there's no way to just override that one column without listing all columns, and in some tables there could be hundreds.

So, does anybody know of a proc that will write this simple insert for me?

EDIT 3:04: The purpose of this is so I can make a copy of the row, so after the INSERT is generated, I can modify it into something like

insert into dbo.MyTable( FirstName, LastName, Position)
values( 'Dave', 'Smith', 'Software Consultant');

.. no obviously this contrived example is so simple it doesn't make sense, but if you have a table with 60 columns, and all you need is to change 3 or 4 values, then it starts to be a hassle.

Does that make sense?

+5  A: 

Update

I believe the following dynamic query is what you want:

declare @tableName varchar(100), @id int, @columns varchar(max), @pk varchar(20)
set @tableName = 'MyTable'
set @pk = 'id'
set @id = 45

set @columns = stuff((select ',['+c.name+']' [text()] from sys.tables t
join sys.columns c on t.object_id = c.object_id
where t.name = @tableName and c.name <> @pk for xml path('')),1,1,'')

print 'insert into [' + @tableName + '] (' + @columns + ')
select ' + @columns + '
from [' + @tableName + '] 
where ' + @pk + ' = ' + cast(@id as varchar)

Update 2

The actual thing that you wanted:

declare @tableName varchar(100), @id int, @columns nvarchar(max), @pk nvarchar(20), @columnValues nvarchar(max)
set @tableName = 'MyTable'
set @pk = 'id'
set @id = 45

set @columns = stuff((select ',['+c.name+']' [text()] from sys.tables t
join sys.columns c on t.object_id = c.object_id
where t.name = @tableName and c.name <> @pk for xml path('')),1,1,'')

set @columnValues = 'set @actualColumnValues = (select' +
stuff((select ','','''''' + cast(['+c.name+'] as varchar(max)) + '''''''' [text()]' [text()] 
from sys.tables t
join sys.columns c on t.object_id = c.object_id
where t.name = @tableName and c.name <> @pk for xml path('')),1,1,'')
+ 'from [' + @tableName + ']
where ' + @pk + ' = ' + cast(@id as varchar) 
+ 'for xml path(''''))'

--select @columnValues
declare @actualColumnValues nvarchar(max), @columnValuesParams nvarchar(500)
SET @columnValuesParams = N'@actualColumnValues nvarchar(max) OUTPUT';
EXECUTE sp_executesql @columnValues, @columnValuesParams, @actualColumnValues OUTPUT;
--SELECT stuff(@actualColumnValues, 1,1, '')

declare @statement nvarchar(max)
set @statement =
'insert into [' + @tableName + '] (' + @columns + ')
select ' + stuff(@actualColumnValues,1,1,'')

print @statement

What it does is this: It generates the insert statement and then it queries the actual data from the table and generates the select statement with that data. May not work correctly for some really complex datatypes but for varchars, datetimes and ints should work like a charm.

Denis Valeev
Thanks for the script. Hope you don't mind the one tweak I made.
John MacIntyre
+2  A: 

This stored proc works great for me:

http://vyaskn.tripod.com/code.htm#inserts

steveschoon
+1  A: 

Did you know that in Enterprise Manager and SQL Server Management Studio that you can, from the object browser, drag the list of columns into the text window and it will drop the names of all the columns into the text, separated by commas?

Emtucifor
@Emtucifor I believe the problem here is that the OP wants to generate an insert statement with some sample data already supplied to it via a select. You know, this laziness thingy that we all have.
Denis Valeev
Yeah, I know about that, but to be honest, I use it so infrequently that I completely forgot about it. But truth be told, I'd prefer to just call a proc, and generate it. KWIM? Thanks for the response though, and if you were sitting in the next cube, that's exactly what I would've done.
John MacIntyre
@Denis I understood the problem. I just thought that people may not know this (since I didn't know it for a long time) and for anyone who's too lazy to write a stored procedure at least they can limp along with this technique.
Emtucifor
@Emtucifor I don't know about you but I press `tab` after `*` with RedGate Prompt and it expands all the available columns.
Denis Valeev
I hated how slow RedGate Prompt was when I tried it... I don't even like the built-in SSMS 2008 intellisense because it interferes with my typing. I have to build my own!
Emtucifor