Use PowerShell
Real Admins Script
Real Admins Script
UPDATE: The script was moved to Google Code. The links in the post have been updated to reflect that. Or you can just go here… http://code.google.com/p/poshcodegen/
I’ve been working on some data conversion at work, converting records from one system to a new system. I’ve built quite a library of SQL queries with PowerShell wrappers for dealing with data in the first system, but I don’t have the same luxury with the new system.
The new system does, however, have a nice set of stored procedures that make moving data into their application much easier.
I started writing my conversion scripts in PowerShell, since I do have to do some processing on the records to accommodate the new workflow and data layout. I was looking at having to call almost 100 stored procedures through various parts of this process. That is a lot of boiler plate code or referring back to the database often to check parameter names and types. So, I’ve written a little PowerShell script that will take stored procedures (either as a parameter or from the pipeline) and create a function that wraps that stored procedure.
The benefits of this are great with V2 CTP3 or with a more advanced editor (one that will provide tab completion on parameters).
One a wider scope, I think that this type of utility is one of PowerShell’s great strengths. Using PowerShell for metaprogramming (another example here on the Telling Machine blog) can be a great time saver. I spent a couple of hours working on this script, but it would have cost me much more time to handle each case individually.
Now, when I hear “metaprogramming”, my head starts to hurt a bit as I start to think about programs about programs about programs, but this isn’t that bad. PowerShell makes this pretty easy to understand though. To create a function dynamically, all that is needed is a string that contains text that the PowerShell runtime can evaluate (PowerShell will check for syntax errors, but not logic errors – as is the case with any script or function).
Example:
$text = ‘Get-ChildItem *.ps1 | Measure-Object’
Set-Item –Path function:global:Get-PowerShellScriptCount –Value $Text
This takes advantage of the Function provider and creates a function object in the global scope with the specified name and $Text is turned into a scriptblock. I can then call that function as needed.
Since I know PowerShell, to build dynamic functions I just have to create text that can be evaluated to do the function I need.
Here’s what my script does after it runs a query against the database to get the stored procedure’s text:
What are you automating with PowerShell?
How about trying to automate some of your automation code?
New-StoredProcFunction.ps1 here.
PSMDTAG:metaprogramming sql stored procedure
UPDATED SCRIPT: Thanks to Chad Miller for the idea.. instead of parsing the text of the stored procedure, the parameter information is available in the Information_Schema.Parameters
April 9, 2009 - 10:43 am
function New-StoredProcFunction currently doesn’t work when the the stored procedure return resultssets. Replacing lines 119 – 123 with
$ScriptText += @’
$connection.Open() | out-null
#$command.ExecuteNonQuery() | out-null
$adapter = New-Object System.Data.SqlClient.SqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
[void] $adapter.Fill($dataSet)
$connection.Close()
$dataSet.Tables | ForEach-Object {$_.Rows}
‘@
Brings you one step further. But then there are still sp’s returning more than 1 Resultset and of course those returning no resultsets. There is still some work to be done to get it all round.
April 9, 2009 - 10:46 am
Bernd,
Nice catch.. I’ve only been testing with a number of stored procedures that return most of their values via output parameters. I’ll have to create some stored procs to test with that return result sets.
Thanks!