THE SQL Server Blog Spot on the Web

Welcome to SQLblog.com - The SQL Server blog spot on the web Sign in | |
in Search

Buck Woody

Carpe Datum!

Code that Writes Code

I have scripts that re-create my databases for testing and development purposes. But sometimes I want to take the data from a set of tables and move it as well – I could use SSIS, or a SELECT INTO statement, but what if I want to “re-set” the data to a point in time? In other words, load it with some “base data”?

I thought this might be a good place to demonstrate “code that writes code”. No, it isn’t that big of a deal – most DBAs know how to do this, but in the interest of those who don’t, I thought I would share.

So the end result I want in this case is to have a bunch of INSERT statements that contain my base data from a table where that data already exists. I could script out the table from SSMS and use the replacement parameter feature to fill out each record individually:

I have a table in one of my databases that I right-clicked to show the INSERT statement:

-- Person

INSERT

INTO [WAVS].[dbo].[Person]

([PersonName]

,[Street]

,[CityStateZip]

,[PersonType])

VALUES

(<PersonName, varchar(150),>

,<PersonStreet, varchar(100),>

,<PersonCityStateZip, varchar(255),>

,<PersonPersonType, varchar(100),>)

I can use the CTRL-SHIFT-M keys to replace the VALUES part with the values I want. 

But I already had a copy of that “base” data before I turned the database over to the testers. Before I give it to them, I run code like this on each table – this one is for the Person table above (note that there should only be two lines here):

SELECT

'INSERT INTO [WAVS].[dbo].[Person] ([PersonID], [PersonName], [Street], [CityStateZip], [PersonType]) VALUES (' + CAST([PersonID] AS VARCHAR(5))+ ', ''' + [PersonName]+ ''', ''' + [Street]+ ''', ''' + [CityStateZip] + ''', ''' + [PersonType] + ''')'

FROM

[WAVS].[dbo].[Person]

When I run this code, I get these statements:

INSERT INTO [WAVS].[dbo].[Person] ([PersonID], [PersonName], [Street], [CityStateZip], [PersonType]) VALUES (1, 'Buck Woody', '123 Here Street', 'Covington, WA 98042', 'Vet')
INSERT INTO [WAVS].[dbo].[Person] ([PersonID], [PersonName], [Street], [CityStateZip], [PersonType]) VALUES (2, 'Jane Doe', '231 Function Ave', 'Redmond, WA 98052', 'Vet')
INSERT INTO [WAVS].[dbo].[Person] ([PersonID], [PersonName], [Street], [CityStateZip], [PersonType]) VALUES (3, 'Diane Wilson', '34251 Appt 3 7th Street', 'Seattle, WA 98061', 'Vet')
INSERT INTO [WAVS].[dbo].[Person] ([PersonID], [PersonName], [Street], [CityStateZip], [PersonType]) VALUES (4, 'John Kelso', '89734 Country Lane', 'Covington, WA 98042', 'Farmer')
INSERT INTO [WAVS].[dbo].[Person] ([PersonID], [PersonName], [Street], [CityStateZip], [PersonType]) VALUES (5, 'Marjorie Christian', '9893452 Changein Lane', 'Maple Valley, WA 98072', 'Farmer')
INSERT INTO [WAVS].[dbo].[Person] ([PersonID], [PersonName], [Street], [CityStateZip], [PersonType]) VALUES (6, 'Joanne Lister', '98904 Mapelwood Drive', 'Spokanne, WA 98045', 'Zoo Worker')

All I have to do is copy those statements into my “initialization” scripts just after the table creations, and then I can run them at will to create my new database (I know I can take a backup – I have reasons for not doing that).

There are two keys for writing code that writes code: The first is to simply use the single tick (') to write out what the end code should say (INSERT INTO, in my case) and then to use multiple ticks (''') when you want the code to contain the ticks themselves. This “escapes” the characters so that you can embed them. If you use SSMS to write your queries, the color coding will look as mine does above. You’ll also need to remember to CAST or CONVERT any data types that don’t concatenate (+) together well. In my case I had to CAST an integer value – but that’s OK, since it is only printing to the screen and I don’t include the ticks, the INSERT works fine.

You can use this method not only with INSERTS, but with lots of operations. And you can also even fire off the code once you create it – but that’s another post :)

 

Published Wednesday, November 25, 2009 7:01 AM by BuckWoody

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Luciano Evaristo Guerche (Gorše) said:

Buck,

Just in case you are not aware of, SQL Server Management Studio 2008 Script Wizard has a built-in option which generates these INSERT clauses (http://sqlblog.com/blogs/john_paul_cook/archive/2009/10/13/ssms-tips-and-tricks-scripting-inserts.aspx)

Regards,

November 25, 2009 10:51 AM
 

The Bad Ambassador said:

.. and if you aren't using SQL 2008, this stored proc allows you to generate insert scripts for any table.

<a href="http://vyaskn.tripod.com/code/generate_inserts_2005.txt">http://vyaskn.tripod.com/code/generate_inserts_2005.txt</a>

November 25, 2009 11:11 AM
 

BuckWoody said:

Thanks both of you - good points!  My goal here was to show the code that writes code, not the INSERTS themselves...

Thanks for reading!

November 25, 2009 1:20 PM
 

Lee Everest, M.S. said:

Beware of the new feature, Luciano - only a moderate amount of

data quickly bloats a file beyond manageability.  UltraEdit's

suspend temp file works well up to 2GB :)

Lee

www.texastoo.com

November 25, 2009 2:47 PM
 

jb said:

Probably worth adding that you'll need to watch nulls.  Either set concat null yields null off, or add coalesce() to each field.  Otherwise, you'll end up with missing inserts.  Thanks for sharing!

November 26, 2009 10:15 AM

Leave a Comment

(required) 
(required) 
Submit

About BuckWoody

http://buckwoody.com/BResume.html

This Blog

Syndication

Powered by Community Server (Commercial Edition), by Telligent Systems
  Privacy Statement