Av rating:
Total votes: 33
Total comments: 20


Phil Factor
Automating Common SQL Server Tasks using DMO
27 November 2006

This article includes the source of stored procedures that will:

  1. List all available servers
  2. Enumerate all database on a Server
  3. Create a new database on any available server
  4. Copy an entire database within a server or between servers
  5. Copy selected tables or stored procedures between databases
  6. Write out a complete build script for a database
  7. Write out build scripts for every database on a server
  8. Write out a series of source files for the objects in a database in a suitable format for source-control systems
  9. List the database roles and the users assigned to them, for a particular database
  10. Checks the jobs on a server for their success or otherwise and accesses the history records

Its main intention is to show how easy it is to use DMO (and its successor, SMO) from within SQL Server, and how any COM object that does not rely on events can be used.

                                                                                ===+===

What follows in this article provides a taster of the sort of things you can do with DMO, showing the code to carry out the first three tasks in the above list.

All of the other procedures, with full source code, are freely available from the following link:

ACCESS ALL DMO PROCEDURES AND SOURCE CODE

                                                                                ===+===

When Microsoft made its decision to remove Distributed Management Objects (DMO) from SQL Server 2005, they had underestimated the extent to which it is used. DMO was the "secret" application behind Enterprise Manager and, with it, one could automate almost anything that one could do by hand with EM.

Eventually, Microsoft bowed to pressure and released "Microsoft SQL Server 2005 Backward Compatibility Components" which included the DMO. However, MSDN gives dire warnings that the DMO won't be supported much longer. SQL Server 2005 supplements SQL-DMO with two .NET based object libraries: SQL Server Management Objects (SMO) and Replication Management Objects (RMO). These components are more powerful than the DMO, and can be used with SQL 2000 and v7. Hopefully, a subsequent article will cover the SMO.

The application we originally knew as SQLOLE has survived two name-changes, but the fundamental concepts remain the same. DMO presents a simple programmatic interface via COM, so it can be used in a number of languages, including scripting Shell, PHP, VB, C# and even within SQL Server itself.

In this article, we'll be tackling the use of the DMO in SQL Server. This might seem an odd thing to want to do, but, in fact, it allows you to perform administrative functions that simply cannot be done in any other way. One must also explain why it is worth tackling a subject that has been the subject of many previous articles, and book chapters. The reason is that so many of the examples are poorly written, and make the whole process seem far more complex than it really is.

Getting started with DMO: listing all available servers

Busy DBAs can't afford to perform routine processes manually. There just isn't time. Everything has to be scripted, automated and scheduled, with a system of checks and alerts. Whenever I find myself doing something with SSMS, or EM, more than a couple of times, I script the task and then automate it. Quite often, the scripting is done using SQL Server.

The DMO COM interface consists of:

  • sp_OAGetProperty which gets the value of a property.
  • sp_OASetProperty which sets the value of a property.
  • sp_OAMethod which calls a method.
  • sp_OAGetErrorInfo which obtains the most recent error information.

There is no way to handle events from COM objects. The best way of getting started with DMO is via a simple example. This procedure creates a result with the names of all the available servers, just as appears in the drop-down list in Enterprise Manager when registering a server:

CREATE PROCEDURE spAllAvailableServers
AS
DECLARE @hr INT,       --the HRESULT returned from the OLE operation
       @ii INT,         --a simple counter
       @iimax INT,              --the max of the iteration
       @objApplication INT,     --the application object
       @ErrorObject INT,        --the error object
       @ErrorMessage VARCHAR(255),--the potential error message
       @command VARCHAR(255),   --the command
       @Server VARCHAR(255)     --The String with the current server

SET nocount ON

EXEC @hr sp_OACreate 'SQLDMO.Application'@objApplication OUT
SELECT @errorMessage=
'Getting the number of available servers in the collection',
       @ErrorObject=@objApplication
IF @HR=0  EXEC @hr sp_OAGetProperty @objApplication,
'ListAvailableSQLServers.Count'
        @iimax OUT
SELECT @errorMessage='Getting each item',@ii=1
CREATE TABLE #Servers (MyID INT IDENTITY(1,1), Server VARCHAR(255))
WHILE @hr=AND @ii<=@iiMax --FOR EACH in
       BEGIN
       SELECT @command='ListAvailableSQLServers.item
('
+CAST (@ii AS VARCHAR)+')'
       EXEC @hr sp_OAGetProperty @objApplication@command
               @Server OUT
       INSERT INTO #servers(serverSELECT @Server
       SELECT @ii=@ii+1
       END
--shared error-handling code
IF @hr<>0
       BEGIN
       DECLARE 
               @Source VARCHAR(255),
               @Description VARCHAR(255),
               @Helpfile VARCHAR(255),
               @HelpID INT
       
       EXECUTE sp_OAGetErrorInfo  @errorObject
               @source output,@Description output,
@Helpfile output,@HelpID output

       SELECT @ErrorMessage='Error whilst '+@Errormessage+', '+@Description
       RAISERROR (@ErrorMessage,16,1)
       END
EXEC sp_OADestroy @objApplication
SELECT FROM #servers
RETURN @hr
GO  

Check it out by simply executing exec spAllAvailableServers (note that you may need to enable OLE Automation objects, via Surface Area Configuration for Features)

Notice that there are no GOTO statements that one sees so often in such code. Also there are no cursors. These aren't necessary and they bulk up the code. This is a vital factor when you are creating more complex DMO procedures.

The first step when using an OLE Automation object in Transact-SQL is to call the sp_OACreate system stored procedure to create an instance of the object in the address space of the instance of the Database Engine. In this case, it is the SQLDMO application object. Then we just get from it the list of available SQL Servers. If an automation error occurs, the code drops through to the error handler and thence out, passing the HRESULT back to the calling procedure, but still providing an empty result.

Enumerating all databases on a Server

So what about adapting an example application from VB? Here is one that enumerates all the databases on a server, and gives their size in Mb (from Rick Dobson 12.06.2000): 

Sub call_enumerate_databases()

'Pass along server name, login, and password
'to routine to enumerate databases on a server
enumerate_databases "cabarmada", "sa", ""

End Sub

Sub enumerate_databases(srvname As String, _
    login As String, password As String)
Dim srv1 As SQLDMO.SQLServer
Dim dbs As SQLDMO.Database

'Connect to a SQL Server
Set srv1 = New SQLDMO.SQLServer
srv1.Connect srvname, login, password

'Enumerate the databases on connected server
For Each dbs In SQLDMO.SQLServers(srvname).Databases
    Debug.Print dbs.Name & " uses " & dbs.Size & _
        "MB of storage."
Next

'Cleanup routine
srv1.Disconnect
Set srv1 = Nothing

End Sub

We can use this code as the basis for a stored procedure, which will do exactly the same thing:

CREATE PROCEDURE spEnumerateDatabases
@strServer VARCHAR(100),
@login  VARCHAR(100)=NULL,
@password VARCHAR(100)=NULL

/*
--SQL Server Authentication
execute spEnumerateDatabases 'MyServer','MyLogin','MyPassword'
--Windows Authentication
execute spEnumerateDatabases 'MyServer'

*/
AS
DECLARE 
@hr INT,          --the HRESULT returned from the OLE operation
       
@ii INT,          --a simple counter
       
@iimax INT,               --the max of the iteration
       
@objServer INT,           --the Server object
       
@objDatabase INT,         --the Database object
       
@ErrorObject INT,         --the error object
       
@ErrorMessage VARCHAR(255), --the potential error message
       
@command VARCHAR(255),    --the command
       
@DatabaseName VARCHAR(255), --the current Database name
       
@DatabaseSize INT         --the current Database size

SET nocount ON

EXEC 
@hr sp_OACreate 'SQLDMO.SQLServer'@objServer OUT
IF @password IS NULL OR @login IS NULL
       
BEGIN
       
--use a trusted connection 
       
IF @hr=SELECT @ErrorMessage=
'Setting login to windows authentication on '
+@strServer,
       
@ErrorObject=@objServer
       
IF @hr=EXEC @hr sp_OASetProperty @objServer'LoginSecure'1
       
IF @hr=SELECT @ErrorMessage=
'logging in to the requested server using
windows authentication on '
+@strServer
       
IF @login IS NULL AND @hr=EXEC @hr sp_OAMethod @objServer,
'Connect', NULL, @strServer 
       
IF @login IS NOT NULL AND @hr=EXEC @hr sp_OAMethod @objServer,
'Connect', NULL, @strServer ,@Login
       
END
ELSE
       BEGIN
       IF 
@hr=SELECT @ErrorMessage 'Connecting to '''+@strServer+
               
''' with user ID '''+@login+''''@ErrorObject=@objServer
       
IF @hr=EXEC @hr sp_OAMethod @objServer,
'Connect', NULL, @strServer,
                           
@login @password
       
END
SELECT 
@errorMessage='finding the number of databases in '+@strServer,
       
@ErrorObject=@objServer
IF @HR=0  EXEC @hr sp_OAGetProperty @objServer'databases.Count'
       
@iimax OUT
SELECT @errorMessage='Getting each item',@ii=1
CREATE TABLE #Databases (MyID INT IDENTITY(1,1),
TheName VARCHAR(255),theSize INT)
WHILE @hr=AND @ii<=@iiMax
       
BEGIN
       SELECT 
@command='databases.item('+CAST (@ii AS VARCHAR)+').name'
       
EXEC @hr sp_OAGetProperty @objServer@command
               
@DatabaseName OUT
       
SELECT @command='databases.item('+CAST (@ii AS VARCHAR)+').size'
       
IF @HR=0  EXEC @hr sp_OAGetProperty @objServer@command
               
@DatabaseSize OUT
       
INSERT INTO #Databases(thename,thesize)
SELECT @DatabaseName,@DatabaseSize
       
SELECT @ii=@ii+1
       
END
 
--and handling any errors
IF @hr<>0
       
BEGIN
       DECLARE 
               
@Source VARCHAR(255),
               
@Description VARCHAR(255),
               
@Helpfile VARCHAR(255),
               
@HelpID INT
       
       EXECUTE 
sp_OAGetErrorInfo  @errorObject
               
@source output,@Description output,
@Helpfile output,@HelpID output

       
SELECT @ErrorMessage='Error whilst '+@Errormessage+', '+@Description
       
RAISERROR (@ErrorMessage,16,1)
       
END
EXEC 
sp_OADestroy @objServer
SELECT FROM #databases
RETURN @hr

Of course, in a working version, you'd want the available space in MB (SpaceAvailableInMB), the Status (e.g. Standby, Normal, Recovering etc) and a host of other information useful to the DBA. It is a simple matter of exploring the DMO Object model on MSDN and seeing what's available.

Create a database on any server

For this, we can take the MSDN example for creating a database as our basis:

Dim oDatabase As New SQLDMO.Database
Dim oDBFileData As New SQLDMO.DBFile
Dim oLogFile As New SQLDMO.LogFile

oDatabase.Name = "Northwind"

' Define the PRIMARY data file.
oDBFileData.Name = "NorthData1"
oDBFileData.PhysicalName = _
    "c:\program files\microsoft sql server\mssql\data\northwnd.mdf"
oDBFileData.PrimaryFile = True

' Specify file growth in chunks of fixed size for all data files.
oDBFileData.FileGrowthType = SQLDMOGrowth_MB
oDBFileData.FileGrowth = 1

oDatabase.FileGroups("PRIMARY").DBFiles.Add oDBFileData

' Define the database transaction log.
oLogFile.Name = "NorthLog1"
oLogFile.PhysicalName = _
    "c:\program files\microsoft sql server\mssql\data\northwnd.ldf"
oDatabase.TransactionLog.LogFiles.Add oLogFile

' Create the database as defined. Note: Create and connect of SQLServer
' object used is not illustrated in this example.
oSQLServer.Databases.Add oDatabase

A simple conversion of this routine allows us to create a database on any of the servers within our ‘stamping ground':

CREATE PROCEDURE spCreateDatabase
@strServer VARCHAR(100),   --the name of the database server
@login  VARCHAR(100),      --the login
@password VARCHAR(100),    --the password
@DatabaseName VARCHAR(100),--the name of the database to create
@DataFileName VARCHAR(100),--the name of the data file
@DataFilePath VARCHAR(100),--the full path and name of the file
@LogFileName VARCHAR(100), --the name of the log file
@LogFilePath VARCHAR(100)  --the full path and name of the log file

/*
--with SQL Server Authentication
spCreateDatabase 'Server',MyUserID,MyPassword,
               'MyDatabaseName',
               'MyLogicalDataFileName',
               'MyPhysicalDataPathandfilename',
               'MyLogicalLogFileName',
               'MyPhysicalLogPathandfilename'

--with Windows Authentication
spCreateDatabase 'Server',default,default,
               'MyDatabaseName',
               'MyLogicalDataFileName',
               'MyPhysicalDataPathandfilename',
               'MyLogicalLogFileName',
               'MyPhysicalLogPathandfilename'

*/

AS
DECLARE 
@hr INT,         --the HRESULT returned from the OLE operation
       
@ii INT,         --a simple counter
       
@iimax INT,              --the max of the iteration
       
@objServer INT,          --the Server object
       
@objDatabase INT,        --the Database object
       
@objDBfileData INT,      --the Database file
       
@objLogFile INT--the log file
       
@ErrorObject INT,        --the error object
       
@strErrorMessage VARCHAR(255)--the potential error message

--and our 'constants'
DECLARE @SQLDMOGrowth_MB INT SET @SQLDMOGrowth_MB 0
DECLARE @SQLDMOGrowth_Percent INT SET @SQLDMOGrowth_Percent 1
DECLARE @SQLDMOGrowth_Invalid INT SET @SQLDMOGrowth_Invalid 99


SET nocount ON

EXEC 
@hr sp_OACreate 'SQLDMO.SQLServer'@objServer OUT

IF @password IS NULL OR @login IS NULL
       
BEGIN
       
--use a trusted connection 
       
IF @hr=SELECT @strErrorMessage=
'Setting login to windows authentication on '
+@strServer,@ErrorObject=@objServer
       
IF @hr=EXEC @hr sp_OASetProperty @objServer'LoginSecure'1
       
IF @hr=SELECT @strErrorMessage=
'logging in to the requested server
using windows authentication on '
+@strServer
       
IF @login IS NULL AND @hr=EXEC @hr sp_OAMethod @objServer,
'Connect', NULL, @strServer 
       
IF @login IS NOT NULL AND @hr=EXEC @hr sp_OAMethod @objServer,
'Connect', NULL, @strServer ,@Login
       
END
ELSE
       BEGIN
       SELECT 
@strErrorMessage=
'logging in to the requested server
using SQL Server authentication to '
+@strServer,
               
@ErrorObject=@objServer
       
IF @hr=EXEC @hr sp_OAMethod @objServer,
'Connect', NULL, @strServer ,
                           
@login @password
       
END

IF 
@hr=SELECT @strErrorMessage='creating new database'
+@strServer,
        
@ErrorObject =NULL
IF @hr=EXEC @hr sp_OACreate 'SQLDMO.Database'@objDatabase OUT
IF @hr=SELECT @strErrorMessage='creating new DBFile'+@strServer
IF @hr=EXEC @hr sp_OACreate 'SQLDMO.DBFile'@objDBfileData OUT
IF @hr=SELECT @strErrorMessage='creating new Logfile'+@strServer
IF @hr=EXEC @hr sp_OACreate 'SQLDMO.LogFile'@objLogFile OUT

IF @hr=SELECT @strErrorMessage 'setting the Database name',
               
@ErrorObject=@objDatabase
IF @hr=EXEC @hrsp_OASetProperty @objDatabase'Name',@DatabaseName

IF @hr=SELECT @strErrorMessage 'setting the DataFile properties',
               
@ErrorObject=@objDBFileData
IF @hr=EXEC @hrsp_OASetProperty @objDBFileData'Name',@DataFileName
IF @hr=EXEC @hrsp_OASetProperty @objDBFileData'PhysicalName',
               
@DataFilePath
IF @hr=EXEC @hrsp_OASetProperty @objDBFileData'PrimaryFile',1
--Specify file growth in chunks of fixed size for all data files.
IF @hr=EXEC @hrsp_OASetProperty @objDBFileData'FileGrowthType',
       
@SQLDMOGrowth_MB
IF @hr=EXEC @hrsp_OASetProperty @objDBFileData'FileGrowth',1

IF @hr=SELECT @strErrorMessage='using method to add '+@DataFileName,
               
@ErrorObject=@objDatabase
IF @hr=EXEC @hr sp_OAMethod @objDatabase,
'FileGroups("PRIMARY").DBFiles.Add',NULL,
                
@objDBFileData

IF @hr=SELECT @strErrorMessage='Setting the logfile properties of '
+@LogFileName,
               
@ErrorObject=@objLogFile
IF @hr=EXEC @hrsp_OASetProperty @objLogFile'Name',@LogFileName
IF @hr=EXEC @hrsp_OASetProperty @objLogFile'PhysicalName',
               
@LogFilePath
IF @hr=SELECT @strErrorMessage='using method to add '
+@LogFileName,
                
@ErrorObject=@objDatabase
IF @hr=EXEC @hr sp_OAMethod @objDatabase,
'TransactionLog.LogFiles.Add',NULL,
               
@objLogFile

IF @hr=SELECT @strErrorMessage='using method to add '
+@DatabaseName+' to the server',
                
@ErrorObject=@objServer
IF @hr=EXEC @hr sp_OAMethod @objServer'Databases.Add',NULL,
               
@objDatabase

--and handling any errors
IF @hr<>0
       
BEGIN
       DECLARE 
               
@Source VARCHAR(255),
               
@Description VARCHAR(255),
               
@Helpfile VARCHAR(255),
               
@HelpID INT
       
       EXECUTE 
sp_OAGetErrorInfo  @errorObject
               
@source output,@Description output,
@Helpfile output,@HelpID output

       
SELECT @strErrorMessage='Error whilst '
+@strErrorMessage+', '+@Description
       
RAISERROR (@strErrorMessage,16,1)
       
END
EXEC 
sp_OADestroy @objServer     --the Server object
EXEC sp_OADestroy @objDatabase   --the Database object
EXEC sp_OADestroy @objDBfileData --the Database file
EXEC sp_OADestroy @objLogFile    --the Log file object

Hopefully, this has provided a taster of the power of DMO for automating common SQL server admin tasks. Again, to access the rest of the DMO procedures that accompany this article, just click on the link below:

ACCESS MORE DMO PROCEDURES



This article has been viewed 21420 times.
Phil Factor

Author profile: Phil Factor

Phil Factor (real name withheld to protect the guilty), aka Database Mole, has 25 years of experience with database-intensive applications. Despite having once been shouted at by a furious Bill Gates at an exhibition in the early 1980s, he has remained resolutely anonymous throughout his career. See also :

Search for other articles by Phil Factor

Rate this article:   Avg rating: from a total of 33 votes.


Poor

OK

Good

Great

Must read
 
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.


Subject: DMO
Posted by: Anonymous (not signed in)
Posted on: Monday, November 27, 2006 at 3:22 PM
Message: DMO isn't managed code. Why not show how to do this with SMO?

Subject: Re: DMO
Posted by: Phil Factor (view profile)
Posted on: Monday, November 27, 2006 at 4:55 PM
Message: I agree entirely. Next episode hopefully, if you are still interested. I just wanted to start by including the many users who were still stuck with SQL 2000. But as I say at the beginning of the article 'Hopefully, a subsequent article will cover the SMO.'. I can then talk about the changes.

Subject: Thanks
Posted by: Anonymous (not signed in)
Posted on: Monday, November 27, 2006 at 5:24 PM
Message: That's a cool DMO login procedure you've got there Phil. I think I'll have that (snip)

Subject: DMO
Posted by: Anonymous (not signed in)
Posted on: Tuesday, November 28, 2006 at 2:34 AM
Message: Very good set
I am waiting to continue :-)
Thanks

Subject: Re:Very Good Set
Posted by: Phil Factor (view profile)
Posted on: Tuesday, November 28, 2006 at 3:22 AM
Message: SMO coming soon, editor-permitting. Remember to click on ACCESS MORE DMO PROCEDURES
to get to the code for this article!

Subject: SP Permissions
Posted by: Anonymous (not signed in)
Posted on: Tuesday, November 28, 2006 at 3:22 AM
Message: How about a script to give execute permissions on all SPs in a database to a user (e.g. machine/Network Service). This is something that comes up regularly and would be realy helpful.

Subject: re: SP Permissions
Posted by: Phil Factor (view profile)
Posted on: Tuesday, November 28, 2006 at 3:37 AM
Message: Yes, that seems a very good idea. I'll see what I can do, as I would find that useful too! I had better provide something that removes permissions to database objects as well. I'm very much looking for ideas for the SMO article, but I'll try to do a DMO version where possible and post it with this article

Subject: re: SP Permissions
Posted by: Jacko (view profile)
Posted on: Tuesday, November 28, 2006 at 6:02 AM
Message: Here is a snippet to do this, but to be honest I would never call DMO from T-SQL, and to acheive the objective I would script off sp_MSForEachTable, replace 'IsUserTable' with 'IsProcedure' and save as sp_MSForEachSP. You can then call

sp_MSForEachSP 'Grant Exec on ? to TestRole'

check results with sp_helprotect


---------------------------
SQL_SERVERNAME = "(local)"
SQL_DBNAME = "DBName"
ROLE_NAME = "TestRole"

Set oSQLServer = CreateObject("SQLDMO.SQLServer2")
oSQLServer.LoginSecure = True
oSQLServer.Connect SQL_SERVERNAME

Set oDatabase = oSQLServer.Databases(SQL_DBNAME)

For Each oDatabaseObject In oDatabase.StoredProcedures
If oDatabaseObject.SystemObject Then
'do nothing (bypass system objects)
Else
cmd = "Grant Exec on dbo." & oDatabaseObject.Name & " to " & ROLE_NAME
oDatabase.ExecuteImmediate cmd
End If
Next

oSQLServer.Disconnect

Set oDatabase = Nothing
Set oSQLServer = Nothing

-------------------------------------------

HTH

Dave

Subject: problem posting comments
Posted by: Tony Davis (view profile)
Posted on: Tuesday, November 28, 2006 at 6:40 AM
Message: Apologies if some of you have experienced difficulties posting comments this morning -- I am investigating this issue right now

Tony D, Simple-Talk Ed.

Subject: re: SP Permissions
Posted by: Jacko (view profile)
Posted on: Tuesday, November 28, 2006 at 7:01 AM
Message: Actually, the DMO code below would be better written as
-------------------------------------------

SQL_SERVERNAME = "(local)"
SQL_DBNAME = "DBName"
ROLE_NAME = "TestRole"
SQLDMOPriv_Execute = 16

Set oSQLServer = CreateObject("SQLDMO.SQLServer2")
oSQLServer.LoginSecure = True
oSQLServer.Connect SQL_SERVERNAME

Set oDatabase = oSQLServer.Databases(SQL_DBNAME)

For Each oDatabaseObject In oDatabase.StoredProcedures
If oDatabaseObject.SystemObject Then
'do nothing (bypass system objects)
Else
oDatabaseObject.Grant SQLDMOPriv_Execute ,ROLE_NAME

End If
Next

oSQLServer.Disconnect

Set oDatabase = Nothing
Set oSQLServer = Nothing
-------------------------------------------

Dave

Subject: SP Permissions
Posted by: Phil Factor (view profile)
Posted on: Tuesday, November 28, 2006 at 2:09 PM
Message: Jacko/Dave,

The second version is wonderful. I'm dead impressed. Actually, both versions are valuable as they demonstrate interesting techniques.

On the subject of whether one should choose the DMO/SMO approach or execute SQL code remotely to do the same thing, (Or both, as you illustrated) I'm interested in your views.

Why use
SQL Server rather than a scripting language? The problem I normally have is that I'm maintaining quite a number of Internet sites that are driven by SQL Servers co-hosted remotely, and which need a single scheduled operation just to check that all is well. This needs to be recorded and audited so we know what was done and when. This is why my DMO logic tends to end up in TSQL, and executed on the Scheduler. This makes alerts, emails and SMS so much easier too, and everything is in one place for source management. However, I'd hate to think that there should be a hard and fast rule.

Subject: Re: SP Permissions
Posted by: Phil Factor (view profile)
Posted on: Wednesday, November 29, 2006 at 4:08 AM
Message: I've added the script to do this now.
Click here to get it
This stored procedure will grant or revoke permissions for a specified user on all user tables or stored procedures for the specified database(s) on the named server.
It uses either windows or SQL Server authentication.
It can grant or revoke Select, Update, Insert, Delete or execute permissions.
On Stored procedures, only Execute permissions are valid, on tables, all but execute permissions are valid.

I hope you like it.

Subject: SP permissions
Posted by: Tony Davis (view profile)
Posted on: Wednesday, November 29, 2006 at 6:10 AM
Message: I'd like to thank Jacko for his excellent contribution to this article. As a result, Phil has written a a DMO procedure that grants or revokes, to users or roles,bpermissions on tables or stored procedures. The script has been added to the CODE DOWNLOAD bundle (see the link in the box to the right of the article title).

Jacko -- I offer you a Simple-Talk goodie bag for your efforts. Just drop me a mail at: editor@simple-talk.com, with a mailing address.

Cheers,

Tony Davis, Simple-Talk Ed.

Subject: Re: SP Permissions
Posted by: Jacko (view profile)
Posted on: Wednesday, November 29, 2006 at 7:52 AM
Message: I would like to know what you use DMO for that you cannot do using system procedures, or custom T-SQL scripts, but go with what you know. And I know you know T-SQL better than I do. ;0)

I use DMO quite a lot, but not from T-SQL. Here are a couple of examples.

RestoreSQLViaDMO
DBtoVSS

Having said that, I agree there should be no hard fast rule, and I also like to script everything off in the Scheduler so as to get the 'look in one place' advantadge. I personally call DMO from vbs scripts, as per the examples above, and there is nothing to stop you calling the vbscript from the Scheduler via the Operating System Command (CmdExec) interface. Look for a page called 'SQL Job Report' on my site for an example of how to this. You can get fancy and use Errorlevel in batch files to raise the appropiate alert if you want. ;0)

Of course, you tend to go with what you are comfortable with. If you are used to handling errors in T-SQL, go with it.

I personally find converting scripts a non-trivial exercise, so I prefer to use languages in the environment for which they were designed, but using the 'no hard fast' rule, there is nothing to say you can't. As you can see from the 'SQL Job Report' page, I use what ever I can find to get the job done. That page uses a cmd file, a vbs file, utilising ADO Objects, and a PHP script I cobbled together from some example I found on the web to display text files.

BTW, the spGrantOrRevokePermissionToObject is a corker.

Dave 'Jacko' Jackson

Subject: Assigning passwords
Posted by: Anonymous (not signed in)
Posted on: Tuesday, December 12, 2006 at 4:59 PM
Message: I would like to use SMO to assign passwords since I presume it would be somewhat safer than using TSQL. I would really like to see you give an example of how that is done (How 'bout tomorrow? ;-) )

Subject: Re: Assigning passwords
Posted by: Anonymous (not signed in)
Posted on: Tuesday, December 12, 2006 at 5:00 PM
Message: And could you make it in C#?

Subject: DMO-SMO differences
Posted by: Skeleton (view profile)
Posted on: Monday, April 02, 2007 at 9:22 AM
Message: Love your examples using DMO with SQL, since I'm a DBA and not a VB or C# developer. Where can I find specific example showing the differences for SMO so I can develop processes that are up to date.

Subject: re: DMO-SMO Differences
Posted by: Phil Factor (view profile)
Posted on: Monday, April 23, 2007 at 12:29 PM
Message: Sorry, you'll have to stick with DMO. Sadly, although SMO started out with a COM interface when it was being developed, it is now only usable with VB.NET or other .net languages. I've never really bought the offical expanation for this, and it has been a big turn-off for the DBA who dislikes doing stuff in other languages.

Fortunatley, the Express versions of the .NET languages work fine with SMO once one gets over the odd quirk (See Alan White's second article for details).

Many of my DBA friends are still using DMO perfectly happily with SQL 2005 as they don't always need the new features. I'd suggest using PowerSMO as an alternative approach to running SMO.

Robyn Page doesn't mind using VB.NET with SMO and CLR so maybe I ought to get stuck in.



Subject: thanks for your help
Posted by: gonzalo (not signed in)
Posted on: Friday, September 21, 2007 at 5:38 PM
Message: HI
I have been looking by many places a similar article, that helps me to consult through a stored procedure which I have in SQL-Server2000 to controls the writing of errors in the applications log. How is this, you´r will be asking, I have tried to write the error when it fails on an INSERT, UPDATE, ETC. but with a friendly format than by defect bring SQLSERVER. But on this errors (Ins, Upd, etc)SQL Server automatically Brake/finishes the execution of the procedure and the JOB therefore I cannot control the writing of the error in the Aplicaciones Log in my Server. This I make from SQL Server + linked Server connected to an Oracle DB. If somebody can help... thanks Salud gonzalo.vidal@gmail.com

Subject: Recompile
Posted by: Anonymous (not signed in)
Posted on: Monday, May 12, 2008 at 3:24 AM
Message: I prefer the following as a recomile script. You can customise the where clause:


set nocount on
select [name] into #test from sysobjects where xtype = 'P'
and [name] not like '%.%' and [name] not like 'dt_%'

declare @Cur_name varchar(255)
DECLARE Compile_cursor CURSOR FOR
select [name] from #test

OPEN Compile_cursor

FETCH NEXT FROM Compile_cursor
INTO @Cur_name
WHILE @@FETCH_STATUS = 0
BEGIN
declare @sql varchar(150)
set @sql = 'exec sp_recompile '+ @Cur_Name
exec (@sql)

FETCH NEXT FROM Compile_cursor
INTO @Cur_name
END

CLOSE Compile_cursor
DEALLOCATE Compile_cursor

drop table #test

 










Phil Factor
Pivoting, Un-pivoting and Aggregating: A Quick Spin Around the Block
 In which Phil is asked to write a nice simple quick-start guide about aggregation, pivoting and un-pivoting... Read more...



 View the blog
Controlling Execution Plans with Hints
 The Query Optimizer gets it right most of the time, but occasionally it chooses a plan that isn't the... Read more...

SQL Server Execution Plans - eBook Download
 Why is my query running slow? Why isn't my index getting used? In order to answer these questions, you... Read more...

Using the Filtering API with the SQL Comparison SDK
 Red Gate's SQL Comparison SDK provides a means to compare and synchronize database schemas and data... Read more...

SQL Toolbelt 2008: Predominantly an Engineering Task
 The conversion of the Red-Gate tools to be compatible with SQL Server 2008 might not seem, on first... Read more...

Audit Crosschecks
 In this short article, the second of a 2-part series, William suggests a solution, using SQL Data... Read more...

Beginning SQL Server 2005 Reporting Services Part 1
 Steve Joubert begins an in-depth tour of SQL Server 2005 Reporting Services with a step-by-step guide... Read more...

Ten Common Database Design Mistakes
 Database design and implementation is the cornerstone of any data centric project (read 99.9% of... Read more...

Beginning SQL Server 2005 Reporting Services Part 2
 Continuing his in-depth tour of SQL Server 2005 Reporting Services, Steve Joubert demonstrates the most... Read more...

SQL Server Full Text Search Language Features
 SQL Full-text Search (SQL FTS) is an optional component of SQL Server 7 and later, which allows fast... Read more...

Executing SSIS Packages
 Nigel Rivett demonstrates how to execute all SSIS packages in a given folder using either an SSIS... Read more...

Over 150,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.

Join Simple Talk