First Post in this series: SQL Advent Calendar 2013-Day 1- Placeholders in SQL Prompt Snippets
As I was hanging our family Advent Calendar up, I thought I would make one for you, my readers. I’ll be sharing my scripts from two of my favorite products as well as tips on how to create your own.
Second Step Is Creating The Change Tracking Fields
Today I’ll share with you my macro called Add Change Tracking Attributes. This script will add the attributes InsertedBy, InsertedDTS, ModifiedBy, and ModifiedDTS to the selected entities. These attributes are based on the domains that were created by the macro in yesterday’s post found here. If you add these fields, and then decide you don’t want them, you can use my macro called Remove Attribute From Selected Tables, which I blogged about here to remove them.
'---------------------------------------------------------------------------- ' PURPOSE: This macro adds Change Tracking Attributes to Selected Entities. ' Author: Mickey Stuewe ' Date: 12/9/2013 '---------------------------------------------------------------------------- Sub Main Dim objModel As Model Dim objSelObject As SelectedObject Dim objEntity As Entity Dim objAttribute As AttributeObj Dim iCounter As Integer Dim dict As Dictionary Dim iInsertedDateID As Integer Dim iInsertedByID As Integer Dim iModifiedByID As Integer Dim iModifiedDateID As Integer ' Get the Local Data Dictionary. Set dict = DiagramManager.ActiveDiagram.Dictionary ' Determine Domains. Set MyDomain = dict.Domains.Item("InsertedDTS") iInsertedDateID = MyDomain.ID Set MyDomain = dict.Domains.Item("InsertedBy") iInsertedByID = MyDomain.ID Set MyDomain = dict.Domains.Item("ModifiedDTS") iModifiedDateID = MyDomain.ID Set MyDomain = dict.Domains.Item("ModifiedBy") iModifiedByID = MyDomain.ID Set objModel = DiagramManager.ActiveDiagram.ActiveModel ' Iterate through all the selected objects in the current ' model. For Each objSelObject In objModel.ActiveSubModel.SelectedObjects 'Get the object type - we are only concerned 'with entities. If objSelObject.Type = 1 Then ' Get the actual entity object with this ID. ' The model contains the collection of all the ' entities. Set objEntity = objModel.Entities.Item(objSelObject.ID) 'Create Tracking fields and set DomainIDs Set objAttribute = objEntity.Attributes.Add("InsertedBy", False) SetDefaultDomain objAttribute, iInsertedByID,objEntity.EntityName Set objAttribute = objEntity.Attributes.Add("InsertedDTS", False) SetDefaultDomain objAttribute, iInsertedDateID,objEntity.EntityName Set objAttribute = objEntity.Attributes.Add("ModifiedBy", False) SetDefaultDomain objAttribute, iModifiedByID,objEntity.EntityName Set objAttribute = objEntity.Attributes.Add("ModifiedDTS", False) SetDefaultDomain objAttribute, iModifiedDateID,objEntity.EntityName iCounter = iCounter + 1 End If Next objSelObject MsgBox "Four new Attributes were added to " & iCounter & " Table(s).", vbOkOnly + vbInformation, "Attributes Added To Tables" End Sub Sub SetDefaultDomain(objAttribute As AttributeObj, iDomainID As Integer, strEntityName As String) objAttribute.DomainId = iDomainID If Len(objAttribute.DeclaredDefault) > 0 Then 'if the attribute default is bound, then unbind it so that it can be named. If objAttribute.DomainId > 0 Then 'You have to override the bound default value and the default text (name). objAttribute.EnableOverride (1,True) objAttribute.EnableOverride (2,True) End If If Len(objAttribute.DefaultName) = 0 Then objAttribute.DefaultName = "DF_" & strEntityName & "_" & objAttribute.AttributeName ElseIf objAttribute.DefaultName <> "DF_" & strEntityName & "_" & objAttribute.AttributeName Then If MsgBox("The name of the Default Constraint does not match our naming standards. Would you like to replace it?" & vbCrLf & _ vbCrLf & vbCrLf & "Attribute: " & objAttribute.AttributeName & " - Default Name: " & objAttribute.DefaultName & " - Value: " & _ objAttribute.DeclaredDefault & vbCrLf & " Standardized Name: " & "DF_" & strEntityName & "_" & objAttribute.AttributeName, _ vbYesNo + vbQuestion, "Stadardize Name?") = vbYes Then objAttribute.DefaultName = "DF_" & strEntityName & "_" & objAttribute.AttributeName End If End If End If End Sub
Take a look at lines 81 and 82. These two lines are needed to be able to give the default a name and here is why: This macro creates attributes based off of domains. The Inserted attributes have defaults. If we don’t name the defaults, then SQL Server will provide names for them…and they are not pretty. In order for us to be able to override the domain, we have to set the enableoverride property for two properties. Then we’ll be able to provide a name to the default. This step can’t be done in the domain, because defaults are a type of constraint and all constraints need to have unique names.
Tomorrow I’ll show you a Red Gate Snippet used to create the triggers for the tables with these fields.
Previous Post In Series: SQL Advent Calendar 2013-Day 8-Creating Change Tracking Domains (1 of 3)