"I hear and I forget. I see and I remember. I do and I understand."
Confucius
Jorge Novo Development Solutions,Ideas, and Crazy Thoughts.
Email: ETLDEVDBA(at)gmail.com
Tweeter: @ETLDEVDBA
November 15, 2011
Create and populate a table remotely using SMO
A love using the SQL Server Management Objects (SMO) , one of the great advantages is been able to create sql server objects and execute sql scripts remotely. One good example is when a table schema is needed from a Source to a Destination, this task can be accomplish very easy using SSIS, but, where is the challenge doing that. So I create create an SMO script that will do just that. Now that's a challenge:
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports Microsoft.SqlServer.Management.Smo
Imports Microsoft.SqlServer.Management.Common
Imports System.Text
<System.AddIn.AddIn("ScriptMain", Version:="1.0", Publisher:="", Description:="")> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
' The execution engine calls this method when the task executes.
' To access the object model, use the Dts object. Connections, variables, events,
' and logging features are available as static members of the Dts class.
' Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.
'
' To open Code and Text Editor Help, press F1.
' To open Object Browser, press Ctrl+Alt+J.
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
Public Sub Main()
Dim SourceServerName As String = Dts.Variables("User::str_SourceServer").Value.ToString
Dim SourceDB As String = Dts.Variables("User::str_SourceDatabase").Value.ToString
Dim SourceSchema As String = Dts.Variables("User::str_SourceSchema").Value.ToString
Dim SourceTable As String = Dts.Variables("User::str_SourceTable").Value.ToString
Dim SourceTable1 As String = SourceTable
Dim DestServerName As String = Dts.Variables("User::str_DestinationServer").Value.ToString
Dim DestDB As String = Dts.Variables("User::str_DestinationDatabase").Value.ToString
Dim DestSchema As String = Dts.Variables("User::str_DestinationSchema").Value.ToString
Dim DestTable As String = Dts.Variables("User::str_DestinationTable").Value.ToString
Dim DestTable1 As String = DestTable
Dim TableScript As Scripter
Dim objectsToCopy As System.Collections.ArrayList
Dim TableToCopy As String = SourceTable.ToLower()
Dim DestinationTableName As String = DestTable.ToLower()
Dim SourceServer As Server
Dim SourceSrvConn As New ServerConnection
Dim SourceConnStr As String = "Server=" + SourceServerName + ";Database=" + SourceDB + ";Trusted_Connection=True;"
Dim TableScripts As System.Collections.Specialized.StringCollection
Dim CriptingOpt As ScriptingOptions = New ScriptingOptions
Dim DestConnStr As String = "Server=" + DestServerName + ";Database=" + DestDB + ";Trusted_Connection=True;"
Dim col As System.Collections.Specialized.StringEnumerator
SourceTable = SourceSchema + "." + SourceTable
DestTable = DestSchema + "." + DestTable
'Set Servers
SourceSrvConn.ConnectionString = SourceConnStr
SourceServer = New Server(SourceSrvConn)
CriptingOpt.WithDependencies = False
CriptingOpt.SchemaQualifyForeignKeysReferences = False
'CriptingOpt.NoTablePartitioningSchemes = True
CriptingOpt.NoFileGroup = True
CriptingOpt.IncludeIfNotExists = True
CriptingOpt.Triggers = False
CriptingOpt.AllowSystemObjects = False
CriptingOpt.AnsiPadding = False
CriptingOpt.ClusteredIndexes = False
CriptingOpt.ConvertUserDefinedDataTypesToBaseType = False
CriptingOpt.DriAllConstraints = False
CriptingOpt.DriAllKeys = False
CriptingOpt.DriChecks = False
CriptingOpt.DriForeignKeys = False
CriptingOpt.EnforceScriptingOptions = True
CriptingOpt.NoCollation = False
CriptingOpt.DriPrimaryKey = True
Dim DestinationServer As Server
Dim DestinationConn As New ServerConnection
DestinationConn.ConnectionString = DestConnStr
DestinationServer = New Server(DestinationConn)
Dim s As StringBuilder = New StringBuilder
Try
'Dim t As Table
Dim t1 As Table
Dim db As Database
db = SourceServer.Databases(SourceDB)
t1 = db.Tables(SourceTable1, SourceSchema)
TableScripts = t1.Script(CriptingOpt)
col = TableScripts.GetEnumerator
While col.MoveNext
s.Append(" " + col.Current.ToString)
End While
s.Replace(TableToCopy, DestinationTableName)
's = Replace(s, SourceTable1, DestTable1)
Dim Connection As New SqlClient.SqlConnection(DestConnStr)
Dim CreateCmd As New SqlClient.SqlCommand(s.ToString, Connection)
CreateCmd.Connection.Open()
CreateCmd.ExecuteNonQuery()
CreateCmd.Connection.Close()
' Dts.Variables("User::str_CreateTable").Value = s.ToString
Dts.TaskResult = ScriptResults.Success
Catch ex As Exception
Dts.Events.FireError(0, "Create Table Failure", "Creating the table object Fail " + TableToCopy + " " + ex.Message, "", 0)
Dts.TaskResult = ScriptResults.Failure
Finally
s = Nothing
End Try
End Sub
End Class
Query the status of SQL Server Agent Jobs
How many times you get something from a friend that you can't wait to shared with the SQL community.
Well no so long ago a good friend gave the below script and it has become part of my personal SQL Script arsenal, Just like my friend Bernabe told me before handing the script to me he said...Enjoy:
SELECT DISTINCT
SUBSTRING(SYSJOBS.name, 1, 100) AS [Job Name] ,
SYSJOBSTEPS.step_name AS JobStep ,
SYSJOBSTEPS.command,
SYSCATEGORIES.name AS category ,
--SYSJOBS.description AS JobDescription ,
SYSJOBS.date_created AS CreateDate ,
'Enabled' = CASE WHEN SYSSCHEDULES.enabled = 0 THEN 'DISABLED'
WHEN SYSSCHEDULES.enabled = 1 THEN 'ENABLED'
END ,
-- substring(SYSSCHEDULES.name,1,30) AS [Name of the schedule],
'Job Frequency ' = CASE WHEN SYSSCHEDULES.freq_type = 1 THEN 'ONCE'
WHEN SYSSCHEDULES.freq_type = 4 THEN 'DAILY'
WHEN SYSSCHEDULES.freq_type = 8 THEN 'WEEKLY'
WHEN SYSSCHEDULES.freq_type = 16
THEN 'Monthly'
WHEN SYSSCHEDULES.freq_type = 32
THEN 'MONTHLY RELATIVE'
WHEN SYSSCHEDULES.freq_type = 32
THEN 'START AUTOMATICALLY WHEN SQL AGENT STARTS'
END ,
'Days jobs run' = CASE WHEN SYSSCHEDULES.[freq_interval] = 1
THEN ' SUNDAY'
WHEN SYSSCHEDULES.[freq_interval] = 2
THEN ' MONDAY'
WHEN SYSSCHEDULES.[freq_interval] = 3
THEN ' TUESDAY'
WHEN SYSSCHEDULES.[freq_interval] = 4
THEN ' WEDNESDAY'
WHEN SYSSCHEDULES.[freq_interval] = 5
THEN ' THURSDAY'
WHEN SYSSCHEDULES.[freq_interval] = 6
THEN ' FRIDAY'
WHEN SYSSCHEDULES.[freq_interval] = 7
THEN ' SATURDAY'
WHEN SYSSCHEDULES.[freq_interval] = 8
THEN ' DAILY'
WHEN SYSSCHEDULES.[freq_interval] = 9
THEN ' WEEKLY'
WHEN SYSSCHEDULES.[freq_interval] = 10
THEN 'WEEKEND'
WHEN SYSSCHEDULES.[freq_interval] = 62
THEN 'MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY'
WHEN SYSSCHEDULES.[freq_interval] = 64
THEN 'SATURDAY'
WHEN SYSSCHEDULES.[freq_interval] = 65
THEN 'SATURDAY, SUNDAY'
WHEN SYSSCHEDULES.[freq_interval] = 126
THEN 'MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY'
END ,
'INTERVAL TYPE' = CASE WHEN SYSSCHEDULES.freq_subday_type = 1
THEN 'At the specified time'
WHEN SYSSCHEDULES.freq_subday_type = 2
THEN 'Seconds'
WHEN SYSSCHEDULES.freq_subday_type = 4
THEN 'Minutes'
WHEN SYSSCHEDULES.freq_subday_type = 8
THEN 'Hours'
END ,
CAST(CAST(SYSSCHEDULES.active_start_date AS VARCHAR(15)) AS DATETIME) AS StartDate ,
CAST(CAST(SYSSCHEDULES.active_end_date AS VARCHAR(15)) AS DATETIME) AS EndDate ,
STUFF(STUFF(RIGHT('000000'
+ CAST(SYSJOBSCHEDULES.next_run_time AS VARCHAR), 6),
3, 0, ':'), 6, 0, ':') AS Run_Time
FROM msdb..sysjobs SYSJOBS
INNER JOIN msdb..sysjobhistory SYSJOBHISTORY ON SYSJOBHISTORY.job_id = SYSJOBS.job_id
INNER JOIN msdb..sysJobschedules SYSJOBSCHEDULES ON SYSJOBSCHEDULES.job_id = SYSJOBS.job_id
INNER JOIN msdb..SysSchedules SYSSCHEDULES ON SYSSCHEDULES.Schedule_id = SYSJOBSCHEDULES.Schedule_id
INNER JOIN msdb..sysjobsteps SYSJOBSTEPS ON SYSJOBSTEPS.job_id = SYSJOBS.job_id
INNER JOIN msdb..syscategories SYSCATEGORIES ON SYSCATEGORIES.category_id = SYSJOBS.category_id
Well no so long ago a good friend gave the below script and it has become part of my personal SQL Script arsenal, Just like my friend Bernabe told me before handing the script to me he said...Enjoy:
SELECT DISTINCT
SUBSTRING(SYSJOBS.name, 1, 100) AS [Job Name] ,
SYSJOBSTEPS.step_name AS JobStep ,
SYSJOBSTEPS.command,
SYSCATEGORIES.name AS category ,
--SYSJOBS.description AS JobDescription ,
SYSJOBS.date_created AS CreateDate ,
'Enabled' = CASE WHEN SYSSCHEDULES.enabled = 0 THEN 'DISABLED'
WHEN SYSSCHEDULES.enabled = 1 THEN 'ENABLED'
END ,
-- substring(SYSSCHEDULES.name,1,30) AS [Name of the schedule],
'Job Frequency ' = CASE WHEN SYSSCHEDULES.freq_type = 1 THEN 'ONCE'
WHEN SYSSCHEDULES.freq_type = 4 THEN 'DAILY'
WHEN SYSSCHEDULES.freq_type = 8 THEN 'WEEKLY'
WHEN SYSSCHEDULES.freq_type = 16
THEN 'Monthly'
WHEN SYSSCHEDULES.freq_type = 32
THEN 'MONTHLY RELATIVE'
WHEN SYSSCHEDULES.freq_type = 32
THEN 'START AUTOMATICALLY WHEN SQL AGENT STARTS'
END ,
'Days jobs run' = CASE WHEN SYSSCHEDULES.[freq_interval] = 1
THEN ' SUNDAY'
WHEN SYSSCHEDULES.[freq_interval] = 2
THEN ' MONDAY'
WHEN SYSSCHEDULES.[freq_interval] = 3
THEN ' TUESDAY'
WHEN SYSSCHEDULES.[freq_interval] = 4
THEN ' WEDNESDAY'
WHEN SYSSCHEDULES.[freq_interval] = 5
THEN ' THURSDAY'
WHEN SYSSCHEDULES.[freq_interval] = 6
THEN ' FRIDAY'
WHEN SYSSCHEDULES.[freq_interval] = 7
THEN ' SATURDAY'
WHEN SYSSCHEDULES.[freq_interval] = 8
THEN ' DAILY'
WHEN SYSSCHEDULES.[freq_interval] = 9
THEN ' WEEKLY'
WHEN SYSSCHEDULES.[freq_interval] = 10
THEN 'WEEKEND'
WHEN SYSSCHEDULES.[freq_interval] = 62
THEN 'MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY'
WHEN SYSSCHEDULES.[freq_interval] = 64
THEN 'SATURDAY'
WHEN SYSSCHEDULES.[freq_interval] = 65
THEN 'SATURDAY, SUNDAY'
WHEN SYSSCHEDULES.[freq_interval] = 126
THEN 'MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY'
END ,
'INTERVAL TYPE' = CASE WHEN SYSSCHEDULES.freq_subday_type = 1
THEN 'At the specified time'
WHEN SYSSCHEDULES.freq_subday_type = 2
THEN 'Seconds'
WHEN SYSSCHEDULES.freq_subday_type = 4
THEN 'Minutes'
WHEN SYSSCHEDULES.freq_subday_type = 8
THEN 'Hours'
END ,
CAST(CAST(SYSSCHEDULES.active_start_date AS VARCHAR(15)) AS DATETIME) AS StartDate ,
CAST(CAST(SYSSCHEDULES.active_end_date AS VARCHAR(15)) AS DATETIME) AS EndDate ,
STUFF(STUFF(RIGHT('000000'
+ CAST(SYSJOBSCHEDULES.next_run_time AS VARCHAR), 6),
3, 0, ':'), 6, 0, ':') AS Run_Time
FROM msdb..sysjobs SYSJOBS
INNER JOIN msdb..sysjobhistory SYSJOBHISTORY ON SYSJOBHISTORY.job_id = SYSJOBS.job_id
INNER JOIN msdb..sysJobschedules SYSJOBSCHEDULES ON SYSJOBSCHEDULES.job_id = SYSJOBS.job_id
INNER JOIN msdb..SysSchedules SYSSCHEDULES ON SYSSCHEDULES.Schedule_id = SYSJOBSCHEDULES.Schedule_id
INNER JOIN msdb..sysjobsteps SYSJOBSTEPS ON SYSJOBSTEPS.job_id = SYSJOBS.job_id
INNER JOIN msdb..syscategories SYSCATEGORIES ON SYSCATEGORIES.category_id = SYSJOBS.category_id
November 12, 2011
A deadlock was detected error
A good friend of mine call me in a desperate mode because of an particular problem they have added some changes and now the package is failing because of a deadlock against some of the variables in the package.
After some thoughts I ask how he was typically adding the variables into the ReadWriteVariables like most users, once he said that I said "Oh Nooo" even thought that made things simple is not always the best way to ensure deadblock will happen so. I said remove the variables from the ReadWriteVariables and modify your code using the below sample code:
Variables var = null ;
Dts.VariableDispenser.LockForWrite ("User::int_Sample1");
Dts.VariableDispenser.LockForWrite ("User::int_Sample2");
Dts.VariableDispenser.LockForWrite ("User::dt_today");
Dts.VariableDispenser.GetVariables (ref var );
var["User::int_Sample1"].Value = 1;
var["User::int_Sample2"].Value = 2;
var["User::dt_today"].Value = DateTime.Now;
var.Unlock();
Dts.TaskResult = (int)ScriptResults.Success;
He was delighted, and I explain to him developers need to act like mechanics, we love the new tools, but, once in awhile look inside the engine to get your hands dirty...
After some thoughts I ask how he was typically adding the variables into the ReadWriteVariables like most users, once he said that I said "Oh Nooo" even thought that made things simple is not always the best way to ensure deadblock will happen so. I said remove the variables from the ReadWriteVariables and modify your code using the below sample code:
Variables var = null ;
Dts.VariableDispenser.LockForWrite ("User::int_Sample1");
Dts.VariableDispenser.LockForWrite ("User::int_Sample2");
Dts.VariableDispenser.LockForWrite ("User::dt_today");
Dts.VariableDispenser.GetVariables (ref var );
var["User::int_Sample1"].Value = 1;
var["User::int_Sample2"].Value = 2;
var["User::dt_today"].Value = DateTime.Now;
var.Unlock();
Dts.TaskResult = (int)ScriptResults.Success;
He was delighted, and I explain to him developers need to act like mechanics, we love the new tools, but, once in awhile look inside the engine to get your hands dirty...
November 09, 2011
Lazy programmer
I consider myself as a lazy programmer. I believed on the motto due once, due right; during my military days there was a Sargent which we call Sargent C he always used to said "El flojo siempre trabaja doble" ( The lazy always works twice) and then he used to explain first is done quick and dirty and later has to fix what it should have done right on the first place, so as a lazy programmer I try to do things once and thing on the details of how it should be done.
Fit cum studio perfectionis, non arte
Subscribe to:
Posts (Atom)