I've written a Powershell script that scripts out the appropriate SQL scripts for all databases on a server as well as creating BCP files for the contents of each. This is to allow the restoration of a database from a higher level of SQL to a lower level where backup and restore will be impossible (but there are no features or functions used that are incompatible otherwise). This is great, to automatically run them against the destination server is problematic.
Each script created contains small problems. For example the table scripts all start with dropping the table by name if it already exists. This is fine in SSMS because you can just remove that line if the table doesn't already exist to avoid the "doesn't exist or you don't have permission" errors. There's other things you'd remove too like creating indexes that already exist from having run other scripts that make other tables from the same database.
Invoke-sqlcmd -inputfile dbo.SomeTable.sql stops and fails on these errors. How can I make either invoke-sqlcmd ignore them and just do what it can (in the knowledge that's fine), or temporarily make SQL tolerant of those and not raise stopping errors, or what else can I use to programatically apply the scripts SQL server generates to an SQL server without manual intervention?
Best Answer
Test to see if the object exists before trying to drop it or create it. That way you'll still throw errors in the event that the DROP or CREATE itself fails rather than for collisions.
[Note: This syntax comes from the scripts that
Microsoft.SqlServer.Management.Smo.Scripter
generates.]I'm assuming that your PowerShell scripting script is using
Microsoft.SqlServer.Management.SMO.Scripter
? Why not specifyScripter.Options.IncludeIfNotExists = $true
? You get all the same options that you get with SSMS's Generate Scripts tool. Do something like this:This scripts the tables using SQL Server 2008 syntax (
Version100
). I'm using a version of the libraries that ships with Sql Server Management Studio 17.