THE SQL Server Blog Spot on the Web
Welcome to SQLblog.com - The SQL Server blog spot on the web Sign in | Join | Help
in Search

Allen White

Using PowerShell and SQL Server Together

I've mentioned before my company manages trade shows, and we've got a series of web sites managed by an application which uses a different SQL Server database for each site, with a master database (I'll call it Global, to differentiate it from SQL Server's master database). Well, we have a number of shows which have multiple show locations, and these use a parent-child set of databases, where information pertaining to all the shows is in the parent database, and then information to each specific location is in the child database.

There is information that is important to both parent and child, and that's kept in the parent database, and we have views in the child which return the data from the parent database that's specific to the child. The problem is when the application is changed, and the views need to be modified. Each child site has a technically different view based on it's show ID and the name of the parent database.

Yesterday I had to make such a change, and I decided a PowerShell script was the best way to approach the problem. Now, there's a table defining all the parent/child relationships in the Global database, so the first step is to query that table to get the necessary information:

#build_exibitors_view.ps1
#This script will recreate the 'exhibitors' view in all child databases

$cn = new-object system.data.SqlClient.SqlConnection("Data Source=MyServer\MyInstance;Integrated Security=TRUE;Initial Catalog=Global");
$ds = new-object "System.Data.DataSet" "dsChildSites"
$q = "SELECT [childShowID]"
$q = $q + " ,[parentDBName]"
$q = $q + " ,[childDBName]"
$q = $q + " FROM [Global].[dbo].[ParentChild]"
$da = new-object "System.Data.SqlClient.SqlDataAdapter" ($q, $cn)
$da.Fill($ds)

Now, once the DataSet is populated it's time to loop through the results building the new view for each child database. I create a DataTable from the DataSet, then use the FOREACH-OBJECT cmdlet to step through the results, and then create variables for the values returned for each iteration.

$dtChild = new-object "System.Data.DataTable" "dsChildSites"
$dtChild = $ds.Tables[0]
$dtChild | FOREACH-OBJECT {
$pDB = $_.parentDBName
$cDB = $_.childDBName
$cshowID = $_.childShowID

Inside the loop I need to connect to each child database and first drop the existing view. I concatenate the name of the child database to the connection string for the SqlCommand object.

	$cn = new-object System.Data.SqlClient.SqlConnection("Data Source=MyServer\MyInstance;Integrated Security=TRUE;Initial Catalog=" + $cDB)
$cn.Open()
$sql = "IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[exhibitors]')) DROP VIEW [dbo].[exhibitors]"
$cmd = new-object "System.Data.SqlClient.SqlCommand" ($sql, $cn)
$cmd.ExecuteNonQuery() | out-null

Once the existing view is deleted I can create the new one. Here I concatenate the name of the parent database in the FROM clause, and filter the resultset based on the showID of the child show.

	$sql = "CREATE VIEW [dbo].[exhibitors]"
$sql = $sql + " AS"
$sql = $sql + " SELECT exhibID, name, description"
$sql = $sql + " FROM " + $pDB + ".dbo.exhibitors"
$sql = $sql + " WHERE (showID = " + [string]$cshowID + ")"

Now that the view has been built for the child database I can execute the query to create it.

	$cmd2 = new-object "System.Data.SqlClient.SqlCommand" ($sql, $cn)
$cmd2.ExecuteNonQuery() | out-null
$cn.Close()

}

(Note that the actual view used is much more complicated than this, but I wanted to share the technique.) Rather than use an editor to make changes to a couple of dozen views across as many databases I used PowerShell to automate the process and made the changes in a few seconds.

Allen


Published Friday, January 25, 2008 12:05 PM by AllenMWhite

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

 

Linchi Shea said:

Why not just use T-SQL? Would that be simpler?

I consider myself a scripting guy, but I must admit that I have not seen any compelling reason for using PowerShell in general. Most PS examples from MS seem to be rather contrived, and have better alternative solutions.

January 25, 2008 3:19 PM
 

AllenMWhite said:

I could have used T-SQL.  We're incorporating a variety of technology tools together here to automate processes, though, and by doing this in PowerShell the network admins who don't know T-SQL can run scripts like this when setting up a new trade show web site without running SSMS.  They just have to run a set of scripts and the site is done.

The best way to accomplish any given task?  It depends.

January 25, 2008 3:24 PM
 

Jason Haley said:

January 26, 2008 10:12 AM
 

moff said:

@Linchi - "I have not seen any compelling reason for using PowerShell in general"

With respect, I don't think you can have been looking very hard then. How about scripting out some objects in a database?

[reflection.assembly]::LoadwithPartialName("Microsoft.SQLServer.SMO") | out-Null

$server = New-Object 'Microsoft.sqlserver.management.smo.server' '<servername>'

$server.JobServer.jobs| foreach-Object {$_.script()}

This is the kind of thing that PS with SMO is superb at.

January 28, 2008 9:41 AM
 

Linchi Shea said:

Moff;

How's that so different from the following:

using System;

using Microsoft.SqlServer.Management.Smo;

using Microsoft.SqlServer.Management.Smo.Agent;

using Microsoft.SqlServer.Management.Common;

using System.Collections.Specialized;

class Junk {

   static void Main() {

       Server svr = new Server(new ServerConnection("server", "user", "password"));    

       foreach (Job job in svr.JobServer.Jobs) {

           StringCollection sc = job.Script();

           foreach (string s in sc) { Console.WriteLine(s); }

       }

   }

}

I mean, the key to 'scripting' script is to understand SMO. Once you are comfortable with SMO, you can use any .NET language. PS doesn't really provide much added value in this particular example. To me and for this particular example, all that PS provides is syntactic sugar--that is of very limited usage scope--one can do without.

I'd love to see a more compelling example. (Of course, there is a vendor-related compelling reason that I fully understand. That is, if MS pushes PS to all its platforms an apps, and make it ubiquitous. But evne then not all apps are written by MS. Personally I think MS carves the problem space wrong with PS.)

January 28, 2008 3:25 PM
 

SQL Server, BizTalk Server, le 64 bits et au-delà !... said:

Two excellent articles giving samples on how to use SQL Server with PowerShell : Using PowerShell and

January 29, 2008 5:02 AM
 

moff said:

@ Linchi, it differs by about a fifth :-)

YMMV, I just prefer the simplicity and neatness of PS.

January 29, 2008 9:18 AM
 

Linchi Shea said:

I was being a bit facetious. I don't mind PS being so dependent on .NET and on these specialized .NET classes. It's fine to be able to pipe specialized .NET objects, but I wish PS were better in dealing with the traditional byte streams. More specifically, I'd like it to much better blend regular expressions into byte stream processing.

PS 2.0 does look a lot better. At least, it appears to be supporting background jobs and Script cmdlets.

January 29, 2008 12:18 PM
 

AllenMWhite said:

Linchi, in the presentations I've done both in local user group sessions and at the last two PASS conferences where I've presented SMO sessions I've gotten feedback that many DBA's aren't allowed to have Visual Studio on their desktops.  They're not developers, they're administrators.  For them, PowerShell is not just syntactic sugar, it's a way for pure administrators to automate processes.

January 29, 2008 8:01 PM
 

Linchi Shea said:

Allen;

But you don't need Visual Studio to write admin utilties in VB.NET or C#. I've written many console utilities in C# and never used VS.

I'm not here to try to convince anybody to agree that PS is bad. It's not that bad. But I personally don't think there is much gain for the kind of effort MS put in to develop PS. For the same amouont of investment, they could have just built on top of what has proven in many existing environments (e.g. a Korn shell, bash, or Perl), adding whatever they wanted to add (e.g. piping .NET objects).

We'll see how it plays out. But I doubt these pure administrators will really embrace PS if they are not real scripting guys. And if they are real scripting guys on the Windows platform, they would have to be versed in .NET. To be really versed in .NET, they need to know VB.NET or C#, and if they become comfortable in C# or VB.NET, they may go, "what the heck with this PS?" when they can go all way with VB.NET or C# without being shackled by the PS paradigm. Now, it may appear that I'm treating C# as a scripting language, in a way I am because of the .NET classes. Of course, C# is not a scripting language, and neither is PS. C# is too strongly typed and static for scripting, whereas I feel much handicapped or being put into a straightjack with PS. I'm baiscally a guy who likes to write quick dirty throw-away scripts to get a job done, and for that I want a scripting language that is powerful enough that I know I can always do it no matter what scripting job I may run into, and yet for many jobs often quicker to write a new dirty script than to find an old script that's tucked somewhere in an older folder.

January 29, 2008 11:35 PM
 

Max said:

I think this may be very cool becuase I am a .NET developer and I want scripts to run on any win machine to upsert records from access databases to SQL 2008. I've been looking for a script like this. As mentioned, there are few interesting PS scripts out there.  Anyway, the reader the author wrote for is probably me and I'm looking forward to trying these ideas out!  I already do a bunch of VBS scripts and not having the ease and power of .NET is a pain to anyone who scripts with wscript. Thanks!  Great work.

December 31, 2008 5:48 PM

Leave a Comment

(required) 
(optional)
(required) 
Submit

About AllenMWhite

Allen White is a SQL Server Trainer for Scalability Experts, a leading provider of scalable solutions, training and services based on Microsoft SQL Server. He has worked as a Database Administrator, Architect and Developer for over 30 years, supporting both the Sybase and Microsoft SQL Server platforms over that period.
Powered by Community Server (Commercial Edition), by Telligent Systems
  Privacy Statement