Using Visual Basic with SQL-DMO and SQL-NSJune 13, 2000 Disclaimer: This code is free for anyone to use. No one may sell it, lease it, rent it, or otherwise charge or collect fees for it. Also by using this code you release me and the people you downloaded this example code from, from any and all legal recourse for anything this code may do to your database or computer systems.As all of you know reading this article "What is SQL-DMO, let alone SQL-NS". Well the myth is about to be uncovered in this multipart demonstration. I plan to show you how to use each of these features for database information, scheduling, and other information purposes with some generic functions and examples. You can do anything that SQL Server Enterprise Manager can do. Also some of the functions in SQL-NS give more information than going through SQL Server EM. Why I don't know but they do even thought they are supposed to be the same API function calls. The only requirements are that you have good VB and SQL Server experience. Whatever you do don't run this code on production boxes, this is meant for example purposes only. DefinitionsSQL-DMO (Distributed Management Objects) Is a collection of objects that encapsulate SQL Server's database, scheduling, and replication management. SQL-NS (Namespace) Is a collection of objects that encapsulate SQL Server's enterprise manager functionality. Help referencesBOK (Books Online) SQL Distributed Management Objects SQL Namespace WROX SQL Server 7.0 SQL-DMO, SQL-NS, & DTS Note: When programming in SQL-NS in VB there is a missing file (feature) that Microsoft did not include called the "sqlns.hlp" file so you will have to refer to my code for examples and to books online. SQL-DMOIn this segment, we will explore the following using SQL-DMO (the next segment will add in the SQL-NS): 1. How to get a list of the servers via (frmMenu) a. Mod1. GetSrvNames() i. SQL-DMO to get a list of all of the SQL Servers running on the domain you are logged into. ii. In the following code we create a SQLDMO Application, and a NameList object in which we fill with avaible SQL Server names running on the same domain. Public Function GetSrvNames()
Dim iCount As Integer
Dim DMOApp As SQLDMO.Application
Dim DMONameList As SQLDMO.NameList
On Error GoTo Err
' Create the Application object
Set DMOApp = New SQLDMO.Application
' Get the list of servers
Set DMONameList = DMOApp.ListAvailableSQLServers
'Get the server names
For iCount = 1 To DMONameList.Count
frmMenu.cmbSrvName.AddItem DMONameList(iCount)
Next
' Close the objects
Set DMONameList = Nothing
Set DMOApp = Nothing
Err:
Resume Next 'Replace with good error handling
End Function
2. How to connect to a SQL Server (frmMenu) a. Mod1.SQL_CONNECTOR(Form Name as parameter) i. Connect to SQL Server via SQL-DMO ii. Below we create a SQLDMO Server object and then connect to it via trusted connection or the "sa" login based on the option chosen in the initial logon screen. Public Function SQL_CONNECTOR(objForName As Object)
' SQLDMO Connect string
Set MySqlServer = CreateObject("SQLDMO.SQLServer")
If bConnected = True Then
MySqlServer.Connect ServerName:=sSRVNameDMO, _
Login:="sa", _
Password:=sPassword
Else
MySqlServer.LoginSecure = True
MySqlServer.Connect ServerName:=sSRVNameDMO
End If
End Function
3. How to do some basic table maintenance and get the scripting (frmMaint) a. Form_Load() i. SQL-DMO on how to get a list of databases on the server you are logged into. ii. Here we use a simple combo box and populate it with all of the available database names. Private Sub Form_Load() Dim Db As Object On Error GoTo LOAD_ERROR frmMaint.MousePointer = 13 Call SQL_CONNECTOR(frmMaint) ' Fill the Combo Box on the form with the available databases by ' using the SQL Server databases collection For Each Db In MySqlServer.Databases ' Make sure is ok If Db.Status <> 992 Or Db.Status <> 32768 Or Db.Status <> 32 Or Db.Status <> 512 _ Or Db.Status <> 192 Or Db.Status <> 256 Then cmbDatabase.AddItem Db.Name Else MsgBox "Database: """ + Db.Name _ + " "" is can not be accessed at this time.", _ vbCritical, "Database Error" End If Next Set Db = Nothing ' Set the combo box to the first database listed. If cmbDatabase.ListCount > 0 Then cmbDatabase.ListIndex = 0 End If ' Get db infor on the selected database Call DBInfo LOAD_ERROR_Exit: frmMaint.MousePointer = 0 Exit Sub LOAD_ERROR: Resume LOAD_ERROR_Exit End Sub b. cmdUpdateStats_Click() i. Update the (DBCC UPDATESTATISTICS) statistics for the currently selected table ii. With this SQLDMO we can create a one touch button to run "DBCC UPDATESTATISTICS" ( Hint. No more ISQL or having to remember the syntax ) Private Sub cmdUpdateStats_Click() Dim WorkTable As SQLDMO.Table Dim iX As Integer On Error GoTo Up_Stats_Error frmMaint.MousePointer = 13 DoEvents ' Execute Update Statistics command on selected tables For iX = 0 To lstTables.Selected(lstTables.ListCount - 1) Set WorkTable = WorkDB.Tables(lstTables.List(iX)) ' Update Statistics on the Table - using the UpdateStatistics Method WorkTable.UpdateStatistics ' Release the Work Table object Set WorkTable = Nothing Next iX Up_Stats_Exit: MsgBox "Satistics Updated", vbInformation, "Statistics Updated" frmMaint.MousePointer = 0 Exit Sub Up_Stats_Error: Me.MousePointer = 0 Resume Next 'Replace with good error handling Resume Up_Stats_Exit End Sub c. cmdCheckIdent_Click() i. Check the identity column (DBCC CHECKIDENT) ii. This simple code issues another DBCC command to check the Identity column of a table. Private Sub cmdCheckIdent_Click() Dim WorkTable As SQLDMO.Table Dim iX As Integer On Error GoTo Up_Identity_Error frmMaint.MousePointer = 13 DoEvents ' Execute CheckIdentityValue command on selected tables For iX = 0 To lstTables.Selected(lstTables.ListCount - 1) Set WorkTable = WorkDB.Tables(lstTables.List(iX)) ' Check Identity values on the Table - using the CheckIdentityValue Method If WorkTable.Attributes = 1 Then WorkTable.CheckIdentityValue End If ' Release the Work Table object Set WorkTable = Nothing Next iX Up_Identity_Exit: MsgBox "Identity Values Checked", vbInformation, "Check Identity" frmMaint.MousePointer = 0 Exit Sub Up_Identity_Error: Me.MousePointer = 0 Resume Next 'Replace with good error handling Resume Up_Identity_Exit End Sub d. cmdTruncate_Click() i. Truncate all of the data in a table (TRUNCATE TABLE) ii. Be careful with this code, it is the same as issing "TRUNCATE TABLE TableName, and will delete all the data in that table just as fast as in the ISQL window. Private Sub cmdTruncate_Click()
Dim WorkTable As SQLDMO.Table
Dim iX As Integer
Dim sTRUNOut As String
On Error GoTo Up_Check_Error
frmMaint.MousePointer = 13
DoEvents
If MsgBox("Do you want to truncate the tables selected?", vbYesNo, "Are you sure?") = vbYes Then
' Execute Truncate Table command on selected tables
For iX = 0 To lstTables.Selected(lstTables.ListCount - 1)
Set WorkTable = WorkDB.Tables(lstTables.List(iX))
' Use the TruncateData Method
WorkTable.TruncateData
MsgBox RTrim$(WorkTable.Name) & " Truncateded", vbInformation, "Table Truncate"
' Release the Work Table object
Set WorkTable = Nothing
Next iX
End If
Up_Check_Exit:
frmMaint.MousePointer = 0
Exit Sub
Up_Check_Error:
Me.MousePointer = 0
Resume Next 'Replace with good error handling
Resume Up_Check_Exit
End Sub
e. cmdMemory_Click() i. Shows memory used by SQL Server (DBCC MEMUSAGE) ii. This DBCC command is in SQLDMO and is kept around for reverse compatibility just like it says in BOL. Private Sub cmdMemory_Click() Dim WorkTable As SQLDMO.Table Dim iX As Integer Dim sTRUNOut As String On Error GoTo Up_Check_Error frmMaint.MousePointer = 13 DoEvents ' Check server memory MsgBox WorkDB.GetMemoryUsage, vbInformation, "MemoryUsage" Up_Check_Exit: frmMaint.MousePointer = 0 Exit Sub Up_Check_Error: Me.MousePointer = 0 Resume Next 'Replace with good error handling Resume Up_Check_Exit End Sub 4. How to get Job Maintenance information (frmScheduler) a. LoadTasks() i. Retrieves names and counts of all jobs on the SQL Server ii. This code simply goes through and gets a total count of all the jobs you have and places their names in a listbox. Private Sub LoadTasks() Dim lTask As Object On Error GoTo LoadTasks_Error frmJobs.MousePointer = 13 lstJobs.Clear For Each lTask In MySqlServer.JobServer.Jobs lstJobs.AddItem lTask.Name Next LoadTasks_Exit: frmJobs.MousePointer = 0 Set lTask = Nothing Exit Sub LoadTasks_Error: Me.MousePointer = 0 Resume Next 'Replace with good error handling Resume LoadTasks_Exit End Sub b. LoadInfo() i. Retrieves information on the currently selected job ii. This long procedure is rather simple in that it retrieves basic information on a job some of which may not be readily avaible even in EM, or you might have to dig deep in the GUI to get to it. Private Sub LoadInfo() Dim iX As Integer Dim WorkJob As SQLDMO.Job Dim iJ As String Dim sMonth As String Dim sYear As String Dim sDay As String On Error GoTo LoadInfo_Error frmJobs.MousePointer = 13 If lstJobs.ListIndex = -1 Then Exit Sub End If For iX = lstJobs.ListCount - 1 To 0 Step -1 If lstJobs.Selected(iX) = True Then ' Set icount for the history and add job Set WorkJob = SQLSRVJOB.Jobs(lstJobs.List(iX)) ' Job owner txtJobOwner.Text = RTrim$(WorkJob.Owner) ' Create date txtDateCreated.Text = RTrim$(WorkJob.DateCreated) ' Run Status iJ = RTrim$(WorkJob.CurrentRunStatus) Select Case iJ Case "3" txtRunStatus.Text = "Job Between Retries" Case "1" txtRunStatus.Text = "Job is executing" Case "4" txtRunStatus.Text = "Job is idle" Case "7" txtRunStatus.Text = "All executtable steps completed" Case "5" txtRunStatus.Text = "Job Suspended" Case "0" txtRunStatus.Text = "Cannot determine status" Case "6" txtRunStatus.Text = "Awaiting step outcome" Case "2" txtRunStatus.Text = "Job is blocked" End Select ' Run Step txtRunStep.Text = RTrim$(WorkJob.CurrentRunStep) ' Last Modified txtLastModDate.Text = RTrim$(WorkJob.DateLastModified) ' Description txtDesc.Text = RTrim$(WorkJob.Description) ' Enabled txtEnabled.Text = RTrim$(WorkJob.Enabled) ' LastRun Date sYear = Left(RTrim$(WorkJob.LastRunDate), 4) sMonth = Mid(RTrim$(WorkJob.LastRunDate), 5, 2) sDay = Right(RTrim$(WorkJob.LastRunDate), 2) If sYear = "0" And sMonth = "" And sDay = "0" Then txtLastRunDate.Text = "Job never ran" Else txtLastRunDate.Text = Format(sMonth & sDay & sYear, "##/##/####") ' Last run time txtLastRunDate.Text = txtLastRunDate.Text & " - " & Format(RTrim$(WorkJob.LastRunTime), "##:##:##") End If ' Next Run Date sYear = Left(RTrim$(WorkJob.NextRunDate), 4) sMonth = Mid(RTrim$(WorkJob.NextRunDate), 5, 2) sDay = Right(RTrim$(WorkJob.NextRunDate), 2) If sYear = "0" And sMonth = "" And sDay = "0" Then txtNRunDate.Text = "No Run Date" Else txtNRunDate.Text = Format(sMonth & sDay & sYear, "##/##/####") ' Next Run Time txtNRunDate.Text = txtNRunDate.Text & " - " & Format(RTrim$(WorkJob.NextRunTime), "##:##:##") End If ' Operator email txtOprEmail.Text = RTrim$(WorkJob.OperatorToEmail) ' Operator netsend txtOprNetSend.Text = RTrim$(WorkJob.OperatorToNetSend) ' Operator pager txtOprPager.Text = RTrim$(WorkJob.OperatorToPage) ' Pager notification levels iJ = RTrim$(WorkJob.PageLevel) Select Case iJ Case "6" txtPagerLevel.Text = "Page regardless" Case "3" txtPagerLevel.Text = "Page regardless" Case "2" txtPagerLevel.Text = "Page on failure" Case "0" txtPagerLevel.Text = "Do not page" Case "1" txtPagerLevel.Text = "Page on success" Case "4096" txtPagerLevel.Text = "Invalid Value" End Select ' Event Log level iJ = RTrim$(WorkJob.EventlogLevel) Select Case iJ Case "0" txtEventLog.Text = "Always" Case "1" txtEventLog.Text = "Log on success" Case "2" txtEventLog.Text = "Log on failure" Case "3" txtEventLog.Text = "Log on completion" End Select Set WorkJob = Nothing End If Next LoadInfo_Exit: frmJobs.MousePointer = 0 Exit Sub LoadInfo_Error: Me.MousePointer = 0 Resume Next 'Replace with good error handling Resume LoadInfo_Exit End Sub c. cmdRefresh_Click() i. Refreshes the information on the currently selected job. ii. Refreshes the jobs job list and count on the user screen ( just in case something has changed ) Private Sub cmdRefresh_Click() Dim WorkJob As SQLDMO.Job Dim iX As Integer On Error GoTo cmdRefresh_Error frmJobs.MousePointer = 13 For iX = lstJobs.ListCount - 1 To 0 Step -1 If lstJobs.Selected(iX) = True Then Set WorkJob = SQLSRVJOB.Jobs(lstJobs.List(iX)) WorkJob.Refresh MsgBox "Job - " & WorkJob.Name & " refreshed.", vbInformation, "Job Status" End If Next Call LoadTasks cmdRefresh_Exit: frmJobs.MousePointer = 0 Set WorkJob = Nothing Exit Sub cmdRefresh_Error: Me.MousePointer = 0 Resume Next 'Replace with good error handling Resume cmdRefresh_Exit End Sub I hope you find this information educational and learn from it. You can built your own custom applications to do anything and then some that you may rely heavily on EM for. Other Code: On to Part 2 of this article...
|