Chapter 12: Developing with SMO 469 Private Sub cmdCreateDB_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdCreateDB.Click ResetScript() Dim sDatabaseName As String 'Input the database name sDatabaseName = InputBox("Enter the new database name", _ "New Database") Try Dim oDatabase As New Database(oSQLServer, sDatabaseName) oDatabase.Create() 'Add the DB name to the list lstDatabases.Items.Add(oDatabase.Name) Catch SQLSMOError() End Try End Sub This subroutine begins by declaring a string object called sDatabaseName. The Visual Basic InputBox method is then called to prompt the user to enter a new database name to create, and the result is placed into the newly created string sDatabaseName. A new Database object is then instantiated using the current SQL Server instance and sDatabaseName string as parameters. To create the new database on the server, the database object’s Create method is called. The Create method creates the new database using default property settings; however, you can also set the database object properties before calling the Create method. Last, the list of databases displayed by the SMOSample application is updated with the new name by using the lstDatabases object’s Items.Add method to add the name of the new database to the list of databases. Transferring Tables In addition to creating and manipulating databases, SMO is capable of creating and managing tables and other databases objects. Using the SMOSample application, a user can copy tables in the selected database to another database on the server by clicking the Transfer Tables button. Clicking the Transfer Tables button executes the cmdTransferTables_Click event subroutine that you can see in the following listing. NOTE To use the Transfer utility class functions from a client system, the DTS run time needs to be installed on the client system. 470 Microsoft SQL Server 2005 Developer’s Guide The code in the cmdTransferTables_Click subroutine shows how the SMO Transfer utility class can be used to copy tables from one database to another database within a SQL Server system. Private Sub cmdTransferTables_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdTransferTables.Click ResetScript() Dim oCurDatabase As Database Dim oTrans As New Transfer() Try ' Set the database object from the current list selection If lstDatabases.SelectedIndex >= 0 Then oCurDatabase = oSQLServer.Databases(lstDatabases.SelectedIndex) Else oCurDatabase = oSQLServer.Databases(0) End If oTrans.Database = oCurDatabase ' Prompt for new table name oTrans.DestinationDatabase = InputBox( _ "Enter the destination database name:", "Destination Database") oTrans.DestinationServer = cboServer.Text oTrans.DestinationLoginSecure = False ' Setup a secure login for NT security If Me.optNTSecurity.Checked = True Then oTrans.DestinationLoginSecure = True Else oTrans.DestinationLogin = txtLogin.Text oTrans.DestinationPassword = txtPwd.Text End If oTrans.CopyAllTables = True oTrans.CopyData = True oTrans.CopySchema = True oTrans.TemporaryPackageDirectory = "c:\temp" oTrans.TransferData() Catch SQLSMOError() End Try End Sub At the beginning of the cmdTransferTables_Click subroutine, you can see where the Database object oCurDatabase is declared, which represents the current database Chapter 12: Developing with SMO 471 selected on the SMOSample dialog. A new oTrans object is then instantiated. The VB Try/Catch loop is enabled, and then the oCurDatabase object is assigned to correspond to the database name that’s currently selected on the dialog. If the user has previously clicked a database, then that database is used. Otherwise, the first database in the list is assigned as the current database. The oTrans.Database property is then set with the selected database. The Database property of the Transfer object is the source database from which the schema and/or data is transferred to the target location. Next, the user is prompted to input a destination database name using the InputBox function, and the value keyed by the user is assigned to the oTrans.DestinationDatabase property. The cmdTransferTables_Click subroutine then continues to set the other destination properties—DestinationServer, DestinationLoginSecure, DestinationLogin, and DestinationPassword—with the appropriate values displayed on the SMOSample application dialog. In the SMOSample application, all tables, including data and the schema, are to be transferred to the destination database; therefore, the oTrans object properties of CopyAllTables, CopyData, and CopySchema are all set to True. The next line in the subroutine sets the TemporaryPackageDirectory property to the c:\temp directory on the local hard drive. When the oTrans.TransferData method is called, several files will be generated and placed into the temporary directory. The following files and file types are generated: ᭤ Prologue SQL fi le ᭤ NonTransactable SQL fi le ᭤ Epilogue SQL fi le ᭤ CompensatingAction SQL fi le ᭤ TransferMetadata XML document ᭤ InnerPackage SSIS package fi le Each of the SQL files contains T-SQL statements that are generated in accordance with the Transfer object’s properties, the XML document contains the metadata information based on the Transfer object’s properties, and the SSIS package file is used to execute the transfer of the schema and/or data to the destination location. An example of the TransferMetadata file is shown in Figure 12-4. The oTrans.TransferData method is then called and the tables are copied from the selected database to the destination database. After the transfer completes, the files in the temporary directory are automatically deleted. 472 Microsoft SQL Server 2005 Developer’s Guide Showing T-SQL Script for Tables Another one of the handy utility classes found in SMO is the Scripter class. The Scripter class allows you to programmatically create a hierarchical tree object that represents the parent or child dependent relationships of SQL Server objects. You can also generate Transact-SQL scripts that can be used to re-create SQL Server objects. In the example SMOSample application, selecting a table name from the tables list and clicking the Show Script button displays a text box showing the T-SQL script that can be used to re-create the table object. The cmdShowScript_ Click subroutine is shown in the following listing: Private Sub cmdShowScript_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdShowScript.Click Dim oCurDatabase As Database Dim oCurTable As Table Dim sScript As String Figure 12-4 A sample TransferMetadata file Chapter 12: Developing with SMO 473 ' Clear the dependant objects, reset the textbox txtAttributes.Text = vbNullString Label4.Text = "Script" Label5.Visible = False txtAttributes.Width = 220 txtAttributes.Left = 379 Try ' Set the database object from the current list selection If lstDatabases.SelectedIndex >= 0 Then oCurDatabase = oSQLServer.Databases(lstDatabases.SelectedIndex) oCurTable = oCurDatabase.Tables(lstTables.SelectedIndex) Else ' otherwise pick the first table oCurDatabase = oSQLServer.Databases(0) oCurTable = oCurDatabase.Tables(0) lstTables.SetSelected(0, True) End If For Each sScript In oCurTable.Script() txtAttributes.Text += sScript & vbCrLf Next sScript Catch SQLSMOError() End Try End Sub At the top of the cmdShowScript_Click subroutine, you can see where two SMO objects are declared. The oCurDatabase object contains an instance of the current database object selected in the database list. Likewise, the oCurTable object can contain an instance of the current table object selected in the list of tables displayed by the SMOSample application. Next, a string variable named sScript is created. The next few lines of code reset the labels and text box that are displayed on the VB Windows form so that the generated script can be easily read. After all the working objects and variables have been declared, objects that represent the current database and table selected by the user are assigned. Essentially, this code determines the item in the lstDatabases and lstTables list boxes the user clicked, or it selects the first item if no selection has been made. Next, you can see where the Script function of the oCurTable object is called. The Script function returns a collection of string objects representing the T-SQL that is used to create the current table. A For Each loop is used to read each of the string items contained in the collection and then add each string object to the text box. Appending a vbCrLf character to each string object causes the contents of the text box to be presented to the end user as a list. 474 Microsoft SQL Server 2005 Developer’s Guide After the list of T-SQL strings has been added to the text box, it is displayed to the end user. Figure 12-5 shows the SMOSample application displayed by the cmdShowScript_Click subroutine. SMO Error Handling Errors that the SMO methods generate can be trapped using Visual Basic’s standard error handling. If an error is raised by one of the SMO methods and Visual Basic’s error handling is not implemented, the user sees a Visual Basic run-time error and the application is terminated. TIP Make use of Visual Basic’s built-in error handler to trap any SMO errors and prevent unexpected application errors from terminating the application. All the subroutines presented in the sample SMO application make use of the common SQLSMOError subroutine shown here: Figure 12-5 Showing a T-SQL script for a table Chapter 12: Developing with SMO 475 Public Function SQLSMOError() Dim sErrorMsg As String sErrorMsg = Err.Source & " Error: " & _ Err.Number - vbObjectError & ": " & Err.Description SQLSMOError = MsgBox(sErrorMsg, vbOKOnly, "SMO Error") End Function The SQLSMOError function is a relatively simple function, which displays a message box to the user that provides more information about any error conditions encountered. SMO errors can be displayed using the Visual Basic Err object. The Err.Source property contains the name of the SMO component that raised the error. Subtracting the vbObjectError constant from the Err.Number property results in the SMO error number. The Err.Description property contains a text description of the error. Summary As you can see from the code examples, SMO opens the power of SQL Server’s management functions to Visual Basic, and its .NET implementation makes it easy to use from Visual Basic and other .NET programming languages. The examples in this chapter illustrated a small section of the capabilities provided by SMO, which is capable of performing virtually every function you can manually perform using the SQL Server Management Studio. This page intentionally left blank 477 CHAPTER 13 Using sqlcmd IN THIS CHAPTER sqlcmd Components Developing sqlcmd Scripts Copyright © 2006 by The McGraw-Hill Companies. Click here for terms of use. 478 Microsoft SQL Server 2005 Developer’s Guide A nother new development tool that’s provided with SQL Server 2005 is the new sqlcmd utility, which is essentially a replacement for the older command-line osql and isql utilities found in the earlier releases of SQL Server. The old isql program used the now-deprecated SQL Server DB-library to connect to SQL Server, while the osql program used an ODBC interface. For backward compatibility, the osql utility is still shipped with SQL Server 2005; however, isql has been dropped. Like those tools, the sqlcmd utility is run from the command prompt and enables you to enter and execute T-SQL statements, stored procedures, and T-SQL batches. However, it connects to SQL Server using OLE DB and extends the power that was provided in those earlier command-line tools by adding support for variables and extended commands. sqlcmd Components The sqlcmd utility consists of four primary components: the sqlcmd command shell, its command-line parameters, and the built-in commands and variables that are supported by the sqlcmd shell, which enables to you build and execute batches of T-SQL commands. The command-line parameters enable you to pass in run-time information to the SqlCmd shell as well as run T-SQL commands and other sqlcmd scripts. The built-in variables enable your sqlcmd scripts to access system and environment information, while the built-in commands enable you to add extended control flow to your scripts. Command Shell Much like its earlier counterparts, isql and osql, sqlcmd uses a command shell to submit T-SQL commands to SQL Server. Entering sqlcmd at the command prompt starts the sqlcmd command shell. When the command shell is active, each line in the batch will be numbered until the batch is executed. The first line in the batch will be labeled with 1> prompt. You build the batch by entering T-SQL commands and then pressing the enter key following each command. The sqlcmd shell will add the line to the batch and increment the line number for the next command. Entering the T-SQL Go command will execute all of the commands in the current batch. You can see a simple example of using the sqlcmd shell in the following listing: C:\temp>sqlcmd 1> use adventureworks 2> select DepartmentID, Name from HumanResources.Department 3> go Changed database context to 'AdventureWorks'.DepartmentID Name . command-line osql and isql utilities found in the earlier releases of SQL Server. The old isql program used the now-deprecated SQL Server DB-library to connect to SQL Server, while the osql program. Click here for terms of use. 478 Microsoft SQL Server 2005 Developer’s Guide A nother new development tool that’s provided with SQL Server 2005 is the new sqlcmd utility, which is essentially. like its earlier counterparts, isql and osql, sqlcmd uses a command shell to submit T -SQL commands to SQL Server. Entering sqlcmd at the command prompt starts the sqlcmd command shell. When the