<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>x002548's Blog</title>
        <link>http://weblogs.sqlteam.com/brettk/Default.aspx</link>
        <description>Not Just a Number - Brett Kaiser</description>
        <language>en-US</language>
        <copyright>Brett Kaiser (x002548)</copyright>
        <managingEditor>brettkaiser@aol.com</managingEditor>
        <generator>Subtext Version 1.9.4.0</generator>
        <image>
            <title>x002548's Blog</title>
            <url>http://weblogs.sqlteam.com/images/RSS2Image.gif</url>
            <link>http://weblogs.sqlteam.com/brettk/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>How can I update Multiple Tables at once</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2008/04/03/60560.aspx</link>
            <description>"CAN'T BE DONE" -- Crazy boy&lt;br /&gt;
&lt;br /&gt;
Well at first glance, that may very well be the answer, as in this thread:&lt;br /&gt;
&lt;br /&gt;
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=100207&lt;br /&gt;
&lt;br /&gt;
Now, this might not be what the OP is looking for, but if you employ a partitioned view, then yes, it's doable&lt;br /&gt;
&lt;br /&gt;
cut and paste the sample code to see it in action&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
USE Northwind&lt;br /&gt;
GO&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE myTable99 (Col1 int PRIMARY KEY CHECK (Col1 BETWEEN 1  AND 10), Col2 varchar(50))&lt;br /&gt;
CREATE TABLE myTable98 (Col1 int PRIMARY KEY CHECK (Col1 BETWEEN 11 AND 20), Col2 varchar(50))&lt;br /&gt;
GO&lt;br /&gt;
&lt;br /&gt;
INSERT INTO myTable99(Col1, Col2)&lt;br /&gt;
SELECT 1, 'x' UNION ALL&lt;br /&gt;
SELECT 2, 'y' UNION ALL&lt;br /&gt;
SELECT 3, 'z'&lt;br /&gt;
&lt;br /&gt;
INSERT INTO myTable98(Col1, Col2)&lt;br /&gt;
SELECT 11, 'x' UNION ALL&lt;br /&gt;
SELECT 12, 'y' UNION ALL&lt;br /&gt;
SELECT 13, 'z'&lt;br /&gt;
GO&lt;br /&gt;
&lt;br /&gt;
CREATE VIEW myView99&lt;br /&gt;
AS&lt;br /&gt;
SELECT Col1, Col2 FROM myTable99&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT Col1, Col2 FROM myTable98&lt;br /&gt;
GO&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM myView99&lt;br /&gt;
&lt;br /&gt;
UPDATE myView99 SET Col2 = 'x002548' WHERE Col2 = 'z'&lt;br /&gt;
&lt;br /&gt;
SELECT * FROM myView99&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
DROP VIEW myView99&lt;br /&gt;
DROP TABLE myTable99, myTable98&lt;br /&gt;
*/&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/60560.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2008/04/03/60560.aspx</guid>
            <pubDate>Thu, 03 Apr 2008 13:49:05 GMT</pubDate>
            <wfw:comment>http://weblogs.sqlteam.com/brettk/comments/60560.aspx</wfw:comment>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2008/04/03/60560.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/60560.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Because you're mine, I walk the line</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2007/07/26/60272.aspx</link>
            <description>&lt;p&gt;....ummm, well, that "line" would be walking through a line in a family tree.  I saw a post the other the day that asked, if I know a relative somewhere in a families "lineage", how can I find the entire family tree from top to bottom.&lt;/p&gt;
&lt;p&gt;Well here's a hack to do that...don't ask for effecienciey.  This for SQL Server 2000.  I have to determine if CTE's in 2k5 can come up with a better solution, but here it is for now.&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;CREATE TABLE Parent (&lt;br /&gt;
   ID_PK int IDENTITY(1,1)&lt;br /&gt;
 , [Name] varchar(20)&lt;br /&gt;
 , PhoneNum varchar(20)&lt;br /&gt;
 , Address varchar(30))&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;CREATE TABLE Child (&lt;br /&gt;
   ID_PK int&lt;br /&gt;
 , ParentID_FK int)&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;INSERT INTO Parent([Name],PhoneNum, Address)&lt;br /&gt;
SELECT 'Annie',     '111-111-1111', '1st Street' UNION ALL&lt;br /&gt;
SELECT 'Bob',       '222-222-2222', '2nd Street' UNION ALL&lt;br /&gt;
SELECT 'Cathy',     '333-333-3333', '3rd Street' UNION ALL&lt;br /&gt;
SELECT 'Don',       '444-444-4444', '4th Street' UNION ALL&lt;br /&gt;
SELECT 'Emily',     '555-555-5555', '5th Street' UNION ALL&lt;br /&gt;
SELECT 'Frank',     '666-666-6666', '6th Street' UNION ALL&lt;br /&gt;
SELECT 'Georgette', '777-777-7777', '7th Street' UNION ALL&lt;br /&gt;
SELECT 'Harry',     '888-888-8888', '8th Street'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;INSERT INTO Child(ID_PK, ParentID_FK)&lt;br /&gt;
SELECT 1, null UNION ALL&lt;br /&gt;
SELECT 2, 1    UNION ALL&lt;br /&gt;
SELECT 3, 2    UNION ALL&lt;br /&gt;
SELECT 4, 3    UNION ALL&lt;br /&gt;
SELECT 5, null UNION ALL&lt;br /&gt;
SELECT 6, 5    UNION ALL&lt;br /&gt;
SELECT 7, 6    UNION ALL&lt;br /&gt;
SELECT 8, 7&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;SELECT * FROM Parent p LEFT JOIN Child c ON p.ID_PK = c.ID_PK&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="3"&gt;CREATE FUNCTION udf_FindTree (@Child varchar(20))&lt;br /&gt;
RETURNS varchar(8000)&lt;br /&gt;
AS&lt;br /&gt;
BEGIN&lt;br /&gt;
DECLARE @p int, @p_save int, @rs varchar(8000)&lt;br /&gt;
SELECT @p = 0, @p_save = 0&lt;br /&gt;
SELECT @p = ParentID_FK FROM Child c JOIN Parent p ON c.ParentID_FK = p.ID_PK &lt;br /&gt;
 WHERE [Name] = @Child&lt;br /&gt;
--Loop Until @@rowcount = 0&lt;br /&gt;
WHILE Exists (SELECT ParentID_FK FROM Child c WHERE ID_PK = @p)&lt;br /&gt;
  BEGIN&lt;br /&gt;
 SELECT @p_save = @p&lt;br /&gt;
 SELECT @p = ParentID_FK FROM Child c WHERE ID_PK = @p_save&lt;br /&gt;
-- The Last assignement is the top Parent&lt;br /&gt;
  END&lt;br /&gt;
--Now Walk from the top Down until @@rowcount = 0&lt;br /&gt;
SELECT @p = @p_save&lt;br /&gt;
SELECT @rs = [Name] + ' ' + PhoneNum + ' ' + Address FROM Parent WHERE ID_PK = @p&lt;br /&gt;
WHILE EXISTS (SELECT ID_PK FROM Child WHERE ParentID_FK = @p)&lt;br /&gt;
  BEGIN&lt;br /&gt;
 SELECT @rs = @rs + ' ' + COALESCE([Name],'') FROM Parent WHERE ID_PK = @p&lt;br /&gt;
 SELECT @p = ID_PK FROM Child WHERE ParentID_FK = @p&lt;br /&gt;
  END&lt;br /&gt;
RETURN @rs&lt;br /&gt;
END&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;SELECT dbo.udf_FindTree('Cathy')&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;SELECT * FROM Child c JOIN Parent p ON c.ParentID_FK = p.ID_PK &lt;br /&gt;
 WHERE [Name] = 'Cathy'&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;CREATE PROC usp_FindTree @Child varchar(20)&lt;br /&gt;
AS&lt;br /&gt;
SET NOCOUNT ON&lt;br /&gt;
DECLARE @p int, @p_save int, @rs varchar(8000)&lt;br /&gt;
SELECT @p = 0, @p_save = 0&lt;br /&gt;
SELECT @p = ParentID_FK FROM Child c JOIN Parent p ON c.ParentID_FK = p.ID_PK &lt;br /&gt;
 WHERE [Name] = @Child&lt;br /&gt;
--Loop Until @@rowcount = 0&lt;br /&gt;
WHILE Exists (SELECT ParentID_FK FROM Child c WHERE ID_PK = @p)&lt;br /&gt;
  BEGIN&lt;br /&gt;
 SELECT @p_save = @p&lt;br /&gt;
 SELECT @p = ParentID_FK FROM Child c WHERE ID_PK = @p_save&lt;br /&gt;
-- The Last assignement is the top Parent&lt;br /&gt;
  END&lt;br /&gt;
--Now Walk from the top Down until @@rowcount = 0&lt;br /&gt;
SELECT @p = @p_save&lt;br /&gt;
SELECT @rs = [Name] + ' ' + PhoneNum + ' ' + Address FROM Parent WHERE ID_PK = @p&lt;br /&gt;
WHILE EXISTS (SELECT ID_PK FROM Child WHERE ParentID_FK = @p)&lt;br /&gt;
  BEGIN&lt;br /&gt;
 SELECT @rs = @rs + ' ' + COALESCE([Name],'') FROM Parent WHERE ID_PK = @p&lt;br /&gt;
 SELECT @p = ID_PK FROM Child WHERE ParentID_FK = @p&lt;br /&gt;
  END&lt;br /&gt;
SELECT @rs AS rs&lt;br /&gt;
SET NOCOUNT OFF&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;EXEC usp_FindTree 'Cathy'&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="3"&gt;DROP PROC usp_FindTree&lt;br /&gt;
DROP Function udf_FindTree&lt;br /&gt;
DROP TABLE Parent, Child&lt;br /&gt;
GO&lt;br /&gt;
&lt;/font&gt;&lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/60272.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2007/07/26/60272.aspx</guid>
            <pubDate>Thu, 26 Jul 2007 19:45:36 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2007/07/26/60272.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/60272.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Alias to be or not to be</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2007/03/27/60141.aspx</link>
            <description>&lt;p&gt; &lt;/p&gt;
&lt;p&gt;EDIT:  This is bizzare..I ran multiple table joins, and reran it ovr and over, and the times are always different and one time one is faster than the othe and other times it's the other wway around.&lt;/p&gt;
&lt;p&gt;We were having a &lt;a href="http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=81222"&gt;discussion &lt;/a&gt;over at &lt;a href="http://www.sqlteam.com/default.asp"&gt;SQLTeam &lt;/a&gt;on whether to use full table name aliases or short aliases to label columns.  It always seemed to be a mattter of preference and debate on how self docuenting the code.  For m I will always use short aliases and make sure I lable every column, even if it's unique, just so when I come back to the code I don't have to guess or go to the data model.  Some suggest that that's not good enough and fully qualify the columns with the name.  I think that is overkill, but hey, to each his or her own. &lt;/p&gt;
&lt;p&gt;Then we got into a discussion about performance and if there was any.  My first thought was, no way...then someone asked if anyone had ever tested it...so I got to thinking...ys, yes, I know, a dangerous proposition.  And while this is not diffinitive by any means, and I've seen varying results, but the table without the aliases at all took longer.  I have to run some more complicated tests, but this is what we get from the following code.&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;ShortLabelTime &lt;br /&gt;
-------------- &lt;br /&gt;
93&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;FullLabelTime &lt;br /&gt;
------------- &lt;br /&gt;
93&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;NoLableTime &lt;br /&gt;
----------- &lt;br /&gt;
126&lt;br /&gt;
&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;&lt;font face="Arial"&gt;USE Northwind&lt;br /&gt;
GO&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;SET NOCOUNT ON&lt;br /&gt;
CREATE TABLE myTable99 (Col1 int IDENTITY(1,1), Col2 char(1), Col3 datetime DEFAULT(GetDate()))&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;DECLARE @x int&lt;br /&gt;
SELECT  @x = 1&lt;br /&gt;
WHILE @x &amp;lt; 10000&lt;br /&gt;
  BEGIN&lt;br /&gt;
 INSERT INTO myTable99(Col2) SELECT 'x'&lt;br /&gt;
 SELECT @x = @x + 1&lt;br /&gt;
  END&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;DECLARE @s datetime&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;DBCC DROPCLEANBUFFERS&lt;br /&gt;
DBCC FREEPROCCACHE&lt;br /&gt;
SELECT @s = GetDate()&lt;br /&gt;
SELECT a.Col1, a.Col2, a.Col3 FROM myTable99 a WHERE Col1 = 5000&lt;br /&gt;
SELECT DATEDIFF(ms,@s,GetDate()) AS ShortLabelTime&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;DBCC DROPCLEANBUFFERS&lt;br /&gt;
DBCC FREEPROCCACHE&lt;br /&gt;
SELECT @s = GetDate()&lt;br /&gt;
SELECT myTable99.Col1, myTable99.Col2, myTable99.Col3 FROM myTable99 WHERE Col1 = 5000&lt;br /&gt;
SELECT DATEDIFF(ms,@s,GetDate()) AS FullLabelTime&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;DBCC DROPCLEANBUFFERS&lt;br /&gt;
DBCC FREEPROCCACHE&lt;br /&gt;
SELECT @s = GetDate()&lt;br /&gt;
SELECT Col1, Col2, Col3 FROM myTable99 WHERE Col1 = 5000&lt;br /&gt;
SELECT DATEDIFF(ms,@s,GetDate()) AS NoLableTime&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;SET NOCOUNT OFF&lt;br /&gt;
DROP TABLE myTable99&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;&lt;/font&gt; &lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/60141.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2007/03/27/60141.aspx</guid>
            <pubDate>Tue, 27 Mar 2007 18:59:43 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2007/03/27/60141.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/60141.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Add Foreign Keys Back to the Database</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2007/03/01/60124.aspx</link>
            <description>&lt;div&gt;&lt;strong&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;"OK Brett, Now that I &lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;a href="http://weblogs.sqlteam.com/brettk/archive/2007/02/20/60110.aspx"&gt;&lt;strong&gt;&lt;em&gt;&lt;font color="#0000ff"&gt;Removed all my Foreign Keys to Truncate the Data&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;&lt;font color="#0000ff"&gt;,&lt;/font&gt; Now What?  I'm Hosed!  Thanks a bunch"&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;p&gt;OK, Well....sorry to keep you hangng out there.  But, if you followed the code in the above link you will have all of the RI saved to the work table, so now all you need to do is replay it.  The following is the code that will do this for you.  Again, sorry for the delay.&lt;/p&gt;
&lt;font face="Arial"&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;CREATE procedure isp_exec_FK_code&lt;br /&gt;
 &lt;br /&gt;
AS&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;DECLARE @FKcode nvarchar(3000)&lt;br /&gt;
DECLARE @error_out int, @Result_Count int, @Error_Message varchar(255), @Error_Type int, @Error_Loc int, @rc int&lt;br /&gt;
SET NOCOUNT ON&lt;br /&gt;
SELECT @rc = 0&lt;br /&gt;
DECLARE FKcode cursor fast_forward read_only for&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt; SELECT * FROM FK_Create_code&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;OPEN FKcode&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;FETCH NEXT FROM FKcode&lt;br /&gt;
INTO @FKcode&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;WHILE @@fetch_status = 0&lt;br /&gt;
BEGIN&lt;br /&gt;
 execute sp_executesql @FKcode   &lt;br /&gt;
Select @error_out = @@error&lt;br /&gt;
If @error_out &amp;lt;&amp;gt; 0&lt;br /&gt;
  BEGIN&lt;br /&gt;
   SELECT @Error_Loc = 1, @Error_Type = 50001, @rc = -1&lt;br /&gt;
   GOTO isp_exec_FK_code_Error&lt;br /&gt;
  END &lt;br /&gt;
FETCH NEXT FROM FKcode&lt;br /&gt;
INTO @FKcode&lt;br /&gt;
END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;isp_exec_FK_code_Exit:&lt;br /&gt;
CLOSE FKcode&lt;br /&gt;
DEALLOCATE FKcode&lt;br /&gt;
SET NOCOUNT OFF&lt;br /&gt;
RETURN @rc&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;isp_exec_FK_code_Error:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;If @Error_Type = 50001&lt;br /&gt;
 BEGIN&lt;br /&gt;
  Select @error_message = (Select 'Location: ' + ',"' + RTrim(Convert(char(3),@Error_Loc))  &lt;br /&gt;
          + ',"' + '  @@ERROR: ' + ',"' + RTrim(Convert(char(6),error))&lt;br /&gt;
          + ',"' + ' Severity: ' + ',"' + RTrim(Convert(char(3),severity))&lt;br /&gt;
          + ',"' + '  Message: ' + ',"' + RTrim(description)&lt;br /&gt;
          From master..sysmessages&lt;br /&gt;
        Where error = @error_out)&lt;br /&gt;
 END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;RAISERROR @Error_Type @Error_Message&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;GOTO isp_exec_FK_code_Exit&lt;/font&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
GO&lt;br /&gt;
SET QUOTED_IDENTIFIER OFF &lt;br /&gt;
GO&lt;br /&gt;
SET ANSI_NULLS ON &lt;br /&gt;
GO&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;/font&gt; &lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/60124.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2007/03/01/60124.aspx</guid>
            <pubDate>Thu, 01 Mar 2007 14:49:24 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2007/03/01/60124.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/60124.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Collecting Requirements For Key Information</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2007/02/22/60118.aspx</link>
            <description>&lt;p&gt;I've been asked to assist (this time BEFORE Project initiation for a change) in the developmennt of a new application.  The Business Liason/Tech group that is doing this has been collecting requirements (basically reviewing an EXCEL Spreadsheet on steriods) and is coming up with a data model.  We will be doing a model review, but I was able to guide them in how to record the information so I can leverage the data to generate the tables.  I've done this several times already, and they are still fine tuning the table defintion.  I then take that document (Excel, again) and generate the DDL and drop it into ERWin (I'll post that code later).&lt;/p&gt;
&lt;p&gt;Now they are curious on how to define relationships, Primary Keys and Alternate keys.  I decided to figure out the best way to guide them in documenting this so I could leverage that as well.  So I came up with the following.  Just ask your Business Liason group to record the information in the following form, then just use the code below and generate all of your code.&lt;/p&gt;
&lt;p&gt;Basically, you need a spreadsheet with the follwoing information&lt;/p&gt;
&lt;p&gt;Parent Table, Key Column, Child Table, Key Type, Key Order and  Key Sequence.&lt;/p&gt;
&lt;p&gt;Parent Table as it implies is the Parent in a relationship.  For Alterante Keys, Primary Keys it is the table that key info is being generated for.  Key Column is the Column that will be used in the key.  Child Table as is implied the child of a relationship.  It is only used for a Foreign Key type.  Key Type is P for Primary, F for Foreign Key amd A for an Alternate Key.  Key Order defines the Order of Columns in a key, and finally Key Sequence defines the Order in which Foreign or Alternate keys are created.  It is also used as part of the index or constraint.&lt;/p&gt;
&lt;p&gt;I have been on the wrong end of documentation gone bad too many times, and there is immense push back when you tell them you can't use it...OK, you can use, you have to read it, then retype everything that they already typed.  &lt;/p&gt;
&lt;p&gt;I hope you find this useful.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;CREATE TABLE myTable99 (&lt;br /&gt;
   Parent  sysname&lt;br /&gt;
 , keyColumn  sysname&lt;br /&gt;
 , Child  sysname&lt;br /&gt;
 , keyType  char(1)&lt;br /&gt;
 , keyOrder  int&lt;br /&gt;
 , keySequence  int)&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO myTable99(Parent, keyColumn, Child, keyType, keyOrder, keySequence)&lt;br /&gt;
SELECT 'myEmployee',  'EMPL_ID', 'myDirectory', 'F', 1, 1 UNION ALL&lt;br /&gt;
SELECT 'myEmployee',  'EMPL_ID', ''           , 'P', 1, 1 UNION ALL&lt;br /&gt;
SELECT 'myEmployee',  'SSN'    , ''           , 'A', 1, 1 UNION ALL&lt;br /&gt;
SELECT 'myDirectory', 'PHONE'  , ''           , 'P', 1, 1 UNION ALL&lt;br /&gt;
SELECT 'myDirectory', 'EMPL_ID', ''           , 'P', 2, 1&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT * FROM myTable99&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;CREATE TABLE myEmployee(EMPL_ID char(12) NOT NULL, SSN char(9), EMP_NAME varchar(50))&lt;br /&gt;
CREATE TABLE myDirectory(PHONE char(10) NOT NULL, EMPL_ID char(12) NOT NULL)&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT SQL FROM (&lt;br /&gt;
SELECT DISTINCT 'ALTER TABLE ' + Parent&lt;br /&gt;
 + ' WITH NOCHECK ADD CONSTRAINT ' &lt;br /&gt;
 + Parent + '_PK PRIMARY KEY (' AS SQL&lt;br /&gt;
 , Parent, 1 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'P'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT '   '+keyColumn AS SQL&lt;br /&gt;
 , Parent, 2 AS SQL_GROUP, keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyOrder = 1&lt;br /&gt;
   AND keyType = 'P'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT ' , '+keyColumn AS SQL&lt;br /&gt;
 , Parent, 3 AS SQL_GROUP, keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyOrder &amp;lt;&amp;gt; 1&lt;br /&gt;
   AND keyType = 'P'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT DISTINCT ' )' AS SQL&lt;br /&gt;
 , Parent, 4 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'P'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT DISTINCT 'GO' AS SQL&lt;br /&gt;
 , Parent, 5 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'P') AS XXX&lt;br /&gt;
ORDER BY Parent, SQL_GROUP, keyOrder&lt;/font&gt;&lt;/p&gt;
&lt;font face="Arial"&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;/* Produces&lt;br /&gt;
 &lt;br /&gt;
ALTER TABLE myDirectory WITH NOCHECK ADD CONSTRAINT myDirectory_PK PRIMARY KEY (&lt;br /&gt;
   PHONE&lt;br /&gt;
 , EMPL_ID&lt;br /&gt;
 )&lt;br /&gt;
GO&lt;br /&gt;
ALTER TABLE myEmployee WITH NOCHECK ADD CONSTRAINT myEmployee_PK PRIMARY KEY (&lt;br /&gt;
   EMPL_ID&lt;br /&gt;
 )&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;*/&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT SQL FROM (&lt;br /&gt;
SELECT DISTINCT 'CREATE UNIQUE INDEX ' &lt;br /&gt;
 + Parent + '_AK'+CONVERT(varchar(3),keySequence)+' ON ' + Parent + ' ( ' AS SQL&lt;br /&gt;
 , Parent, 1 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'A'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT '   '+keyColumn AS SQL&lt;br /&gt;
 , Parent, 2 AS SQL_GROUP, keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyOrder = 1&lt;br /&gt;
   AND keyType = 'A'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT ' , '+keyColumn AS SQL&lt;br /&gt;
 , Parent, 3 AS SQL_GROUP, keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyOrder &amp;lt;&amp;gt; 1&lt;br /&gt;
   AND keyType = 'A'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT DISTINCT ' )' AS SQL&lt;br /&gt;
 , Parent, 4 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'A'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT DISTINCT 'GO' AS SQL&lt;br /&gt;
 , Parent, 5 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'A') AS XXX&lt;br /&gt;
ORDER BY Parent, SQL_GROUP, keyOrder&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;/* Produces &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;CREATE UNIQUE INDEX myEmployee_AK1 ON myEmployee ( &lt;br /&gt;
   SSN&lt;br /&gt;
 )&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;*/&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT SQL FROM (&lt;br /&gt;
SELECT DISTINCT 'ALTER TABLE ' + Child + ' ADD FOREIGN KEY (' AS SQL&lt;br /&gt;
 , Parent, 1 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'F'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT '   '+keyColumn AS SQL&lt;br /&gt;
 , Parent,  2 AS SQL_GROUP, keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyOrder = 1&lt;br /&gt;
   AND keyType = 'F'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT ' , '+keyColumn AS SQL&lt;br /&gt;
 , Parent,  3 AS SQL_GROUP, keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyOrder &amp;lt;&amp;gt; 1&lt;br /&gt;
   AND keyType = 'F'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT DISTINCT ' )' AS SQL&lt;br /&gt;
 , Parent,  4 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'F'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT DISTINCT 'REFERENCES ' + Parent + ' (' AS SQL&lt;br /&gt;
 , Parent, 5 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'F'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT '   '+keyColumn AS SQL&lt;br /&gt;
 , Parent,  6 AS SQL_GROUP, keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyOrder = 1&lt;br /&gt;
   AND keyType = 'F'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT ' , '+keyColumn AS SQL&lt;br /&gt;
 , Parent,  7 AS SQL_GROUP, keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyOrder &amp;lt;&amp;gt; 1&lt;br /&gt;
   AND keyType = 'F'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT DISTINCT ' )' AS SQL&lt;br /&gt;
 , Parent,  8 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'F'&lt;br /&gt;
UNION ALL&lt;br /&gt;
SELECT DISTINCT 'GO' AS SQL&lt;br /&gt;
 , Parent,  9 AS SQL_GROUP, 1 AS keyOrder&lt;br /&gt;
  FROM myTable99&lt;br /&gt;
 WHERE keyType = 'F') AS XXX&lt;br /&gt;
ORDER BY Parent,  SQL_GROUP, keyOrder&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;/*&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;ALTER TABLE myDirectory ADD FOREIGN KEY (&lt;br /&gt;
   EMPL_ID&lt;br /&gt;
 )&lt;br /&gt;
REFERENCES myEmployee (&lt;br /&gt;
   EMPL_ID&lt;br /&gt;
 )&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;*/&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;DROP TABLE myTable99&lt;br /&gt;
DROP TABLE myEmployee, myDirectory&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; &lt;/font&gt;&lt;/p&gt;
&lt;/font&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/60118.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2007/02/22/60118.aspx</guid>
            <pubDate>Thu, 22 Feb 2007 18:05:05 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2007/02/22/60118.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/60118.aspx</wfw:commentRss>
        </item>
        <item>
            <title>What'dya mean I can't TRUNCATE Tables that have RI?</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2007/02/20/60110.aspx</link>
            <description>&lt;p&gt;So, we've gotten into the business of sanitizing or scrambling sensitive production data for development environments.  This is, for the most part, was the direction to do this for mainframe flat files.  Now comes along distributed environments, mostly 3rd party vendor applications on sql server.  You should see some of the twisted things these apps do.  Using reserved words as column names, creating tables with the same name but different owners..the list is long.&lt;/p&gt;
&lt;p&gt;In any case, when we told the people who support this mess that we would need fixed width flat files,  they were.."&lt;em&gt;but...but...we have over 1,000 tables&lt;/em&gt;".  Long story short, I wrote a bunch of sprocs to automate alot of the steps needed to get the data out and put it back so they could have a sanitized environment.&lt;/p&gt;
&lt;p&gt;One of the issues we ran across was how to handle all of this with RI.  Now I guess I could have had them set up a data dictionary that show the relationships, but I choose a lazy way out.  I used the catalogs to copy all the RI to a Work table, DROP All of the RI (This is done with another sproc I have yet o post) so that it could be "replayed" after I was done with the TRUNCATES and the bcp in's.  Here's a sproc that will log all the RI for any database.  Be forewarned...it takes dynamic sql to a whole other level.  If anyone has anything simpler, I'd like to see it, but this works fine.&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SET QUOTED_IDENTIFIER ON &lt;br /&gt;
GO&lt;br /&gt;
SET ANSI_NULLS ON &lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[isp_Gen_FK_code]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)&lt;br /&gt;
drop procedure [dbo].[isp_Gen_FK_code]&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;CREATE procedure isp_Gen_FK_code&lt;br /&gt;
  @dbname varchar(255) &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;AS&lt;br /&gt;
/*&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;EXEC isp_Gen_FK_code&lt;br /&gt;
  @dbname = 'OHM_Prod'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT * FROM FK_create_code&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;*/&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SET NOCOUNT ON&lt;br /&gt;
DECLARE @tablename nvarchar(128), @column nvarchar(128), @schema nvarchar(128), @constraint nvarchar(128) &lt;br /&gt;
DECLARE @fktable nvarchar(128), @fkconstraint nvarchar(128), @onupdate varchar(9), @ondelete varchar(9) &lt;br /&gt;
DECLARE @comma char(1), @createsql nvarchar(4000), @dropsql nvarchar(4000), @truncatesql nvarchar(4000)&lt;br /&gt;
DECLARE @DYSQL nvarchar(4000),@ColList sysname, @ColList2 sysname&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;DECLARE @error_out int, @Result_Count int, @Error_Message varchar(255), @Error_Type int, @Error_Loc int, @rc int&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT @rc = 0&lt;br /&gt;
CREATE TABLE ##Key_Column_usage(Constraint_catalog sysname,CONSTRAINT_SCHEMA sysname, CONSTRAINT_NAME varchar(300)&lt;br /&gt;
    ,TABLE_CATALOG sysname, TABLE_SCHEMA sysname, TABLE_NAME sysname, COLUMN_NAME sysname&lt;br /&gt;
    ,ORDINAL_POSITION int)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SET @DYSQL = 'use '+@dbname+'&lt;br /&gt;
insert into ##Key_Column_usage&lt;br /&gt;
select '''+@dbname+'''    as CONSTRAINT_CATALOG&lt;br /&gt;
 ,user_name(c_obj.uid) as CONSTRAINT_SCHEMA&lt;br /&gt;
 ,c_obj.name    as CONSTRAINT_NAME&lt;br /&gt;
 ,'''+@dbname+'''    as TABLE_CATALOG&lt;br /&gt;
 ,user_name(t_obj.uid) as TABLE_SCHEMA&lt;br /&gt;
 ,t_obj.name    as TABLE_NAME&lt;br /&gt;
 ,col.name    as COLUMN_NAME&lt;br /&gt;
 ,case col.colid &lt;br /&gt;
  when ref.fkey1 then 1   &lt;br /&gt;
  when ref.fkey2 then 2   &lt;br /&gt;
  when ref.fkey3 then 3   &lt;br /&gt;
  when ref.fkey4 then 4   &lt;br /&gt;
  when ref.fkey5 then 5   &lt;br /&gt;
  when ref.fkey6 then 6   &lt;br /&gt;
  when ref.fkey7 then 7   &lt;br /&gt;
  when ref.fkey8 then 8   &lt;br /&gt;
  when ref.fkey9 then 9   &lt;br /&gt;
  when ref.fkey10 then 10   &lt;br /&gt;
  when ref.fkey11 then 11   &lt;br /&gt;
  when ref.fkey12 then 12   &lt;br /&gt;
  when ref.fkey13 then 13   &lt;br /&gt;
  when ref.fkey14 then 14   &lt;br /&gt;
  when ref.fkey15 then 15   &lt;br /&gt;
  when ref.fkey16 then 16&lt;br /&gt;
 end      as ORDINAL_POSITION&lt;br /&gt;
from&lt;br /&gt;
 '+@dbname+'.dbo.sysobjects c_obj&lt;br /&gt;
 ,'+@dbname+'.dbo.sysobjects t_obj&lt;br /&gt;
 ,'+@dbname+'.dbo.syscolumns col&lt;br /&gt;
 ,'+@dbname+'.dbo.sysreferences  ref&lt;br /&gt;
where&lt;br /&gt;
 permissions(t_obj.id) != 0&lt;br /&gt;
 and c_obj.xtype in ('+'''F'''+ ')&lt;br /&gt;
 and t_obj.id = c_obj.parent_obj&lt;br /&gt;
 and t_obj.id = col.id&lt;br /&gt;
 and col.colid   in &lt;br /&gt;
 (ref.fkey1,ref.fkey2,ref.fkey3,ref.fkey4,ref.fkey5,ref.fkey6,&lt;br /&gt;
 ref.fkey7,ref.fkey8,ref.fkey9,ref.fkey10,ref.fkey11,ref.fkey12,&lt;br /&gt;
 ref.fkey13,ref.fkey14,ref.fkey15,ref.fkey16)&lt;br /&gt;
 and c_obj.id = ref.constid&lt;br /&gt;
union&lt;br /&gt;
 select&lt;br /&gt;
 '''+@dbname+'''    as CONSTRAINT_CATALOG&lt;br /&gt;
 ,user_name(c_obj.uid) as CONSTRAINT_SCHEMA&lt;br /&gt;
 ,i.name     as CONSTRAINT_NAME&lt;br /&gt;
 ,'''+@dbname+'''    as TABLE_CATALOG&lt;br /&gt;
 ,user_name(t_obj.uid) as TABLE_SCHEMA&lt;br /&gt;
 ,t_obj.name    as TABLE_NAME&lt;br /&gt;
 ,col.name    as COLUMN_NAME&lt;br /&gt;
 ,v.number    as ORDINAL_POSITION&lt;br /&gt;
from&lt;br /&gt;
 '+@dbname+'.dbo.sysobjects  c_obj&lt;br /&gt;
 ,'+@dbname+'.dbo.sysobjects  t_obj&lt;br /&gt;
 ,'+@dbname+'.dbo.syscolumns  col&lt;br /&gt;
 ,master.dbo.spt_values  v&lt;br /&gt;
 ,'+@dbname+'.dbo.sysindexes  i&lt;br /&gt;
where&lt;br /&gt;
 permissions(t_obj.id) != 0&lt;br /&gt;
 and c_obj.xtype in ('+'''UQ'''+' ,'+'''PK'''+')&lt;br /&gt;
 and t_obj.id = c_obj.parent_obj&lt;br /&gt;
 and t_obj.xtype  = '+'''U'''+'&lt;br /&gt;
 and t_obj.id = col.id&lt;br /&gt;
 and col.name = index_col(user_name(t_obj.uid)+'+'''.'''+'+t_obj.name,i.indid,v.number)&lt;br /&gt;
 and t_obj.id = i.id&lt;br /&gt;
 and c_obj.name  = i.name&lt;br /&gt;
 and v.number  &amp;gt; 0 &lt;br /&gt;
  and v.number  &amp;lt;= i.keycnt &lt;br /&gt;
  and v.type  = '+'''P'''+''&lt;br /&gt;
execute sp_executesql @DYSQL&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;TRUNCATE TABLE FK_create_code&lt;br /&gt;
SET @DYSQL = 'declare cstrts cursor fast_forward read_only for&lt;br /&gt;
 SELECT DISTINCT&lt;br /&gt;
   c.[TABLE_SCHEMA]&lt;br /&gt;
 , c.[TABLE_NAME]&lt;br /&gt;
 , u.CONSTRAINT_NAME&lt;br /&gt;
  FROM   ' +@dbname+'.[INFORMATION_SCHEMA].[COLUMNS] c&lt;br /&gt;
  JOIN   ##Key_Column_usage u&lt;br /&gt;
    ON    c.[TABLE_NAME]      = u.[TABLE_NAME]&lt;br /&gt;
   AND   c.[TABlE_SCHEMA]    = u.[TABLE_SCHEMA]&lt;br /&gt;
   AND    c.[COLUMN_NAME]     = u.[COLUMN_NAME]&lt;br /&gt;
  JOIN   ' +@dbname+'.[INFORMATION_SCHEMA].[table_constraints] t&lt;br /&gt;
    ON    u.[CONSTRAINT_NAME] = t.[CONSTRAINT_NAME]&lt;br /&gt;
 WHERE    t.[CONSTRAINT_TYPE] = ' + '''FOREIGN KEY'''&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;execute sp_executesql @DYSQL&lt;br /&gt;
Select @error_out = @@error&lt;br /&gt;
If @error_out &amp;lt;&amp;gt; 0&lt;br /&gt;
  BEGIN&lt;br /&gt;
   SELECT @Error_Loc = 1, @Error_Type = 50001, @rc = -1&lt;br /&gt;
   GOTO isp_Gen_FK_code_Error&lt;br /&gt;
  END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;OPEN cstrts&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;fetch next from cstrts&lt;br /&gt;
into @schema, @tablename, @constraint&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;while @@fetch_status = 0&lt;br /&gt;
begin&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SET @DYSQL = 'DECLARE @cr nchar(2), @go nvarchar(8)&lt;br /&gt;
SET @cr = nchar(13)+nchar(10)&lt;br /&gt;
SET @go = @cr + '+'''GO'''+' + @cr&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT DISTINCT&lt;br /&gt;
   @fktable = u2.[TABLE_NAME]&lt;br /&gt;
 , @fkconstraint = r.[UNIQUE_CONSTRAINT_NAME]&lt;br /&gt;
 , @onupdate = r.[UPDATE_RULE]&lt;br /&gt;
 , @ondelete = r.[DELETE_RULE] &lt;br /&gt;
 --, @column = u.[COLUMN_NAME]&lt;br /&gt;
  FROM ' +@dbname+'.[INFORMATION_SCHEMA].[REFERENTIAL_CONSTRAINTS] r&lt;br /&gt;
  JOIN ##Key_Column_usage u2&lt;br /&gt;
    ON r.[UNIQUE_CONSTRAINT_NAME] = u2.[CONSTRAINT_NAME]&lt;br /&gt;
  JOIN ##Key_Column_usage u&lt;br /&gt;
    ON u.[CONSTRAINT_NAME] = r.[CONSTRAINT_NAME]&lt;br /&gt;
 WHERE r.[CONSTRAINT_NAME] = @constraint&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;SELECT @ColList = Null&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;select @ColList = COALESCE(@ColList + '+ ''','''+ ', '+'''''' +') + ' &lt;br /&gt;
     +'''['''+' +CAST(COLUMN_NAME AS sysname)+'+''']'''+'&lt;br /&gt;
FROM (SELECT DISTINCT TOP 100 u.COLUMN_NAME, u.[ORDINAL_POSITION]&lt;br /&gt;
        FROM ' +@dbname+'.[INFORMATION_SCHEMA].[REFERENTIAL_CONSTRAINTS] r&lt;br /&gt;
        JOIN ##Key_Column_usage u2&lt;br /&gt;
          ON r.[UNIQUE_CONSTRAINT_NAME] = u2.[CONSTRAINT_NAME]&lt;br /&gt;
        JOIN ##Key_Column_usage u&lt;br /&gt;
          ON u.[CONSTRAINT_NAME] = r.[CONSTRAINT_NAME]&lt;br /&gt;
       WHERE r.[CONSTRAINT_NAME] = @constraint&lt;br /&gt;
    ORDER BY u.[ORDINAL_POSITION]&lt;br /&gt;
) AS XXX&lt;br /&gt;
set @createsql = &lt;br /&gt;
'+ '''ALTER TABLE ['+@dbname+'].[''' +' &lt;br /&gt;
+ @schema &lt;br /&gt;
+ '+'''].['''+' &lt;br /&gt;
+ @tablename &lt;br /&gt;
+ '+'''] ADD CONSTRAINT ['''+' &lt;br /&gt;
+ @constraint &lt;br /&gt;
+ '+'''] '''+'&lt;br /&gt;
+ @cr &lt;br /&gt;
+ '+'''FOREIGN KEY ('''+' &lt;br /&gt;
+ @colList &lt;br /&gt;
+ '+''') REFERENCES ['+@dbname+'].[''' +' &lt;br /&gt;
+ @schema &lt;br /&gt;
+ '+'''].['''+' &lt;br /&gt;
+ @fktable &lt;br /&gt;
+ '+'''] ('''+'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;CREATE TABLE #Ver(Dbversion varchar(2000))&lt;br /&gt;
INSERT INTO #Ver&lt;br /&gt;
SELECT @@Version&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; SELECT @ColList2 = Null&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;  select @ColList2 = COALESCE(@ColList2 + '+ ''','''+ ', '+'''''' +') + ' &lt;br /&gt;
     +'''['''+' +CAST(c.COLUMN_NAME AS sysname)+'+''']'''+'&lt;br /&gt;
    FROM ' +@dbname+'.[INFORMATION_SCHEMA].[COLUMNS] c&lt;br /&gt;
    JOIN ##Key_Column_usage u&lt;br /&gt;
      ON c.[TABLE_NAME] = u.[TABLE_NAME]&lt;br /&gt;
     AND c.[COLUMN_NAME] = u.[COLUMN_NAME]&lt;br /&gt;
   WHERE u.[CONSTRAINT_NAME] = @fkconstraint&lt;br /&gt;
     AND u.[CONSTRAINT_SCHEMA] = c.[TABLE_SCHEMA]&lt;br /&gt;
ORDER BY u.[ORDINAL_POSITION]&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;set @createsql = @createsql + @colList2&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;IF EXISTS(SELECT * FROM #Ver where dbversion like '+ '''%8.00%'''+')&lt;br /&gt;
BEGIN&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;set @createsql = @createsql + '+''') ON DELETE '''+' &lt;br /&gt;
+ @ondelete &lt;br /&gt;
+ '+''' ON UPDATE '''+' &lt;br /&gt;
+ @onupdate&lt;br /&gt;
END&lt;br /&gt;
ELSE&lt;br /&gt;
BEGIN&lt;br /&gt;
set @createsql = @createsql + '+''')'''+'&lt;br /&gt;
END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO FK_Create_code (FK_Code)&lt;br /&gt;
VALUES (@createsql)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;--print @createsql'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;execute sp_executesql @DYSQL,N' @tablename nvarchar(128), @column nvarchar(128), @schema nvarchar(128), @constraint nvarchar(128) &lt;br /&gt;
 ,@fktable nvarchar(128), @fkconstraint nvarchar(128), @onupdate varchar(9), @ondelete varchar(9) &lt;br /&gt;
, @comma char(1), @createsql nvarchar(4000), @dropsql nvarchar(4000), @truncatesql nvarchar(4000),@ColList nvarchar(300)&lt;br /&gt;
, @colList2 nvarchar(300)'&lt;br /&gt;
,@tablename,@column,@schema, @constraint, @fktable, @fkconstraint , @onupdate, @ondelete, @comma, @createsql&lt;br /&gt;
, @dropsql, @truncatesql, @ColList, @colList2&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;Select @error_out = @@error&lt;br /&gt;
If @error_out &amp;lt;&amp;gt; 0&lt;br /&gt;
  BEGIN&lt;br /&gt;
   SELECT @Error_Loc = 1, @Error_Type = 50001, @rc = -1&lt;br /&gt;
   GOTO isp_Gen_FK_code_Error&lt;br /&gt;
  END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;fetch next from cstrts&lt;br /&gt;
into @schema, @tablename, @constraint&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;end&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;isp_Gen_FK_code_Exit:&lt;br /&gt;
close cstrts&lt;br /&gt;
deallocate cstrts&lt;br /&gt;
DROP TABLE ##KEY_column_usage&lt;br /&gt;
RETURN @rc&lt;br /&gt;
SET NOCOUNT OFF&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;isp_Gen_FK_code_Error:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;If @Error_Type = 50001&lt;br /&gt;
 BEGIN&lt;br /&gt;
  Select @error_message = (Select 'Location: ' + ',"' + RTrim(Convert(char(3),@Error_Loc))  &lt;br /&gt;
          + ',"' + '  @@ERROR: ' + ',"' + RTrim(Convert(char(6),error))&lt;br /&gt;
          + ',"' + ' Severity: ' + ',"' + RTrim(Convert(char(3),severity))&lt;br /&gt;
          + ',"' + '  Message: ' + ',"' + RTrim(description)&lt;br /&gt;
          From master..sysmessages&lt;br /&gt;
        Where error = @error_out)&lt;br /&gt;
 END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;RAISERROR @Error_Type @Error_Message&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;GOTO isp_Gen_FK_code_Exit&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;GO&lt;br /&gt;
SET QUOTED_IDENTIFIER OFF &lt;br /&gt;
GO&lt;br /&gt;
SET ANSI_NULLS ON &lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; &lt;/font&gt;&lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/60110.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2007/02/20/60110.aspx</guid>
            <pubDate>Tue, 20 Feb 2007 16:58:20 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2007/02/20/60110.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/60110.aspx</wfw:commentRss>
        </item>
        <item>
            <title>SET Versus SELECT (Or, Who Really Cares Anyway)</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2007/02/12/60090.aspx</link>
            <description>&lt;p class="Date"&gt;&lt;font size="2"&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;EDIT:  As Tara points out:&lt;/strong&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="Date"&gt;&lt;font size="2"&gt;&lt;strong&gt;&lt;em&gt;Vyas did this test quite some t&lt;/em&gt;&lt;/strong&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;strong&gt;&lt;em&gt;ime ago: &lt;a href="http://vyaskn.tripod.com/differences_between_set_and_select.htm"&gt;http://vyaskn.tripod.com/differences_between_set_and_select.htm&lt;/a&gt;&lt;/em&gt; &lt;/strong&gt;&lt;/font&gt;&lt;strong&gt;&lt;font size="2"&gt;Either I never read it, or I forgot I read it.  Well hopefully I pulled some different points together differently here than Vyas did, and at the very least, I hope I made my feeling clear about a program that has to loop over 2 million times.  Thanks for the heads up Tara...&lt;/font&gt;                                      &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;OK, this always comes up from time to time, and it always seem that people are both sides of the fence. "SET is faster because....", "No, SELECT is faster because".  Well there should be no debate about it, yet I've failed to find a definitive explanation of what the true story behind this is.  In any case I've wanted to look into this.&lt;/p&gt;
&lt;p&gt;In this &lt;a href="http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=79005"&gt;thread&lt;/a&gt; the question comes up again.  In that thread, &lt;a href="http://www.sqlteam.com/forums/pop_profile.asp?mode=display&amp;amp;id=22680"&gt;Peter&lt;/a&gt; posts a link to a &lt;a href="http://www.sqlmag.com/Articles/ArticleID/94555/94555.html"&gt;SQL Server Magazinee Article&lt;/a&gt; that discusses this topic.  While it was a good read, I had a hard time buying it.  The author (who is listed as "Reader") posted that in using SET, it is optimized and when a single value is set that this is more effecient.  They then go on to say that after 1 million iterations with multiple value stes, SELECT was 59% more effecient for each operation.  Now the fact that they are doing checks between each assignment seems to cause a potential unexpected interference by SQL server to the outcome of the results.  Now, in above article, the first line states "&lt;em&gt;&lt;strong&gt;Loops are fairly common in SQL Server stored procedures. &lt;/strong&gt;&lt;/em&gt;", which in itself is sort of a red herring, since if you are coding that way, I would sugest that you step back and rethink your process.  If you can't find a set based solution for 99% for what you have to do, then drop me a line,  or head on over to &lt;a href="http://www.sqlteam.com/default.asp"&gt;SQL Team&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So I set forth for my own test.  I did my tests with an undisturbed loop where dattime values were grabbed before and after the loops of pure sets.  I did for 1,000, 10,000, 1,000,000 and 10,000,000.  Looking &lt;a href="http://www.insidesqlserver.com/author.html"&gt;Kalen's&lt;/a&gt; book (&lt;a href="http://www.amazon.com/Inside-Microsoft-Server-2000-CD-ROM/dp/0735609985/sr=8-6/qid=1171306957/ref=pd_bbs_sr_6/002-4643397-5408858?ie=UTF8&amp;amp;s=books"&gt;Inside SQL Server 2000&lt;/a&gt;), she has a chapter th differences between the two, but nothing about performance.  I'll need to google around some more, however,  there must be an explanation about the internals.  I did the test for Multiple variable assignments, and another set for single variable assignments.  For the 1 million iteration (and it's really 2 million assignments)  I got the following:&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;SELECT_MS_Multiple  SET_MS_Multiple &lt;br /&gt;
------------------                  --------------- &lt;br /&gt;
43470                              202963&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;SELECT_MS_Single   SET_MS_Single &lt;br /&gt;
----------------                    ------------- &lt;br /&gt;
42453                             45746&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Now in both Cases, SELECT wins, in the case of Multiple assignments, SELECT seems to blow SET's doors off.  Now, I need to reiterate this again.  If you are finding that you have a process that needs to loop 1 million times, you either are backed into a corner due to previous developement that can't be changed, you've run into the 1% of the time that you have to, or you have a flawed application design. &lt;/p&gt;
&lt;p&gt;If Anyone sees anyuthing wrong with this test, or  if anyone has any comments I would look forward to it.  With all that said, I use SELECT almost exclusively.  Here's the code:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;DECLARE   @SET1 int,      @SELECT1 int,      @SET2 int,           @SELECT2 int&lt;br /&gt;
DECLARE   @SET3 int,      @SELECT3 int,      @SET4 char,          @SELECT4 char&lt;br /&gt;
DECLARE   @SET5 char,     @SELECT5 char,     @SET6 char,          @SELECT6 char&lt;br /&gt;
DECLARE   @SET7 datetime, @SELECT7 datetime, @SET8 datetime,      @SELECT8 datetime&lt;br /&gt;
DECLARE   @SET9 datetime, @SELECT9 datetime, @SETA varchar(8000), @SELECTA varchar(8000)&lt;br /&gt;
&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;DECLARE @x int, @s1 datetime, @s2 datetime, @e1 datetime, @e2 datetime, @c int&lt;br /&gt;
DECLARE @s3 datetime, @s4 datetime, @e3 datetime, @e4 datetime&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT @x = 1, @s1 = getDate(), @c = 1000000&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;WHILE @x &amp;lt; @c&lt;br /&gt;
  BEGIN&lt;br /&gt;
 SELECT    @SELECT1 = 1&lt;br /&gt;
  , @SELECT2 = 2&lt;br /&gt;
  , @SELECT3 = 3&lt;br /&gt;
  , @SELECT4 = 'a'&lt;br /&gt;
  , @SELECT5 = 'b'&lt;br /&gt;
  , @SELECT6 = 'c'&lt;br /&gt;
  , @SELECT7 = '2001-09-11'&lt;br /&gt;
  , @SELECT8 = GetDate()&lt;br /&gt;
  , @SELECT9 = '1999-12-31'&lt;br /&gt;
  , @SELECTA = 'This is a test of the emergency Broadcationg System.  This is only a test'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; SELECT    @SELECT1 = 0&lt;br /&gt;
  , @SELECT2 = 0&lt;br /&gt;
  , @SELECT3 = 0&lt;br /&gt;
  , @SELECT4 = ''&lt;br /&gt;
  , @SELECT5 = ''&lt;br /&gt;
  , @SELECT6 = ''&lt;br /&gt;
  , @SELECT7 = ''&lt;br /&gt;
  , @SELECT8 = 0&lt;br /&gt;
  , @SELECT9 = 0&lt;br /&gt;
  , @SELECTA = ''&lt;br /&gt;
 &lt;br /&gt;
 SET @x = @x + 1&lt;br /&gt;
  END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT @x = 1, @s2 = getDate(), @e1 = getDate()&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;WHILE @x &amp;lt; @c&lt;br /&gt;
  BEGIN&lt;br /&gt;
 SET       @SELECT1 = 1&lt;br /&gt;
 SET   @SELECT2 = 2&lt;br /&gt;
 SET    @SELECT3 = 3&lt;br /&gt;
 SET   @SELECT4 = 'a'&lt;br /&gt;
 SET   @SELECT5 = 'b'&lt;br /&gt;
 SET   @SELECT6 = 'c'&lt;br /&gt;
 SET   @SELECT7 = '2001-09-11'&lt;br /&gt;
 SET   @SELECT8 = GetDate()&lt;br /&gt;
 SET   @SELECT9 = '1999-12-31'&lt;br /&gt;
 SET    @SELECTA = 'This is a test of the emergency Broadcationg System.  This is only a test'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; SET       @SELECT1 = 0&lt;br /&gt;
 SET   @SELECT2 = 0&lt;br /&gt;
 SET    @SELECT3 = 0&lt;br /&gt;
 SET   @SELECT4 = ''&lt;br /&gt;
 SET   @SELECT5 = ''&lt;br /&gt;
 SET   @SELECT6 = ''&lt;br /&gt;
 SET   @SELECT7 = 0&lt;br /&gt;
 SET   @SELECT8 = 0&lt;br /&gt;
 SET   @SELECT9 = 0&lt;br /&gt;
 SET    @SELECTA = ''&lt;br /&gt;
 &lt;br /&gt;
 SET @x = @x + 1&lt;br /&gt;
  END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT @e2 = getDate()&lt;/font&gt;&lt;/p&gt;
&lt;font face="Arial"&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;SELECT @x = 1, @s3 = getDate()&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;WHILE @x &amp;lt; @c&lt;br /&gt;
  BEGIN&lt;br /&gt;
 SELECT    @SELECT1 = 1&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; SELECT    @SELECT1 = 0&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; SET @x = @x + 1&lt;br /&gt;
  END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT @x = 1, @s4 = getDate(), @e3 = getDate()&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;WHILE @x &amp;lt; @c&lt;br /&gt;
  BEGIN&lt;br /&gt;
 SET       @SELECT1 = 1&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt; SET       @SELECT1 = 0&lt;br /&gt;
 &lt;br /&gt;
 SET @x = @x + 1&lt;br /&gt;
  END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT @e4 = getDate()&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;SELECT DATEDIFF(ms,@s1,@e1) AS SELECT_MS_Multiple, DATEDIFF(ms,@s2,@e2) AS SET_MS_Multiple&lt;br /&gt;
SELECT DATEDIFF(ms,@s3,@e3) AS SELECT_MS_Single, DATEDIFF(ms,@s4,@e4) AS SET_MS_Single&lt;br /&gt;
&lt;/font&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;/font&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/60090.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2007/02/12/60090.aspx</guid>
            <pubDate>Mon, 12 Feb 2007 19:36:02 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2007/02/12/60090.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/60090.aspx</wfw:commentRss>
        </item>
        <item>
            <title>3rd and 45?  Drop back and Punt?  Nah, Generate INSERTS</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2007/02/08/60082.aspx</link>
            <description>&lt;p&gt;&lt;font color="#ff0000" size="4"&gt;EDIT 2007/09/06:  I've modified the sproc to change the dates to be formatted to 121 and stripped out all trailing spaces for char's&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;So, we don't have DBArtisan, but I am very happy for my copy of ERWin.  Don't know what I'd do with out it.&lt;/p&gt;
&lt;p&gt;So we have some requirements where they want to create insert statements to load a production table.  I said, why not just bcp the data out in native format and create an osql script for the production DBA's to insert the data, or a sproc perhaps.&lt;/p&gt;
&lt;p&gt;There are many better ways in my opinion, but I do like a challenge, so I wrote the following.  It's not a very mature sproc...no error handling, doesn't handle images or text (how would you anyway for inserts?), ect&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Just supply the table_name to the sproc&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[isp_Generate_Inserts]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)&lt;br /&gt;
drop procedure [dbo].[isp_Generate_Inserts]&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;CREATE PROC isp_Generate_Inserts&lt;br /&gt;
 @TABLE_NAME sysname&lt;br /&gt;
AS&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;SET NOCOUNT ON&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;/*&lt;br /&gt;
EXEC isp_Generate_Inserts 'BusinessGroup'&lt;br /&gt;
EXEC isp_Generate_Inserts 'MEPType'&lt;br /&gt;
EXEC isp_Generate_Inserts 'Person'&lt;br /&gt;
EXEC isp_Generate_Inserts 'Profile'&lt;br /&gt;
EXEC isp_Generate_Inserts 'Status'&lt;br /&gt;
EXEC isp_Generate_Inserts 'SubBusinessGroup'&lt;br /&gt;
EXEC isp_Generate_Inserts 'XREF'&lt;br /&gt;
EXEC isp_Generate_Inserts 'Operator'&lt;br /&gt;
EXEC isp_Generate_Inserts 'FORMREF'&lt;br /&gt;
EXEC isp_Generate_Inserts 'MEPTERRITORY'&lt;br /&gt;
EXEC isp_Generate_Inserts 'MEPTICKLERSTATUS'&lt;br /&gt;
*/&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;DECLARE @INSERT varchar(8000), @COLLIST varchar(8000)&lt;br /&gt;
--, @TABLE_NAME sysname&lt;br /&gt;
, @SELECT varchar(8000), @cmd varchar(8000), @x int&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;  SELECT @COLLIST = COALESCE(@COLLIST + ', ','') + COLUMN_NAME&lt;br /&gt;
    FROM INFORMATION_SCHEMA.Columns&lt;br /&gt;
   WHERE TABLE_NAME = @TABLE_NAME&lt;br /&gt;
ORDER BY ORDINAL_POSITION&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;SELECT @INSERT = 'INSERT INTO ' + @TABLE_NAME + '('+ @COLLIST + ')'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;-- SELECT @INSERT&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;SELECT @SELECT = COALESCE(@SELECT + '+'',''+ ','') +&lt;br /&gt;
           CASE WHEN DATA_TYPE &lt;br /&gt;
  IN ('datetime','smalldatetime') &lt;br /&gt;
  THEN + ''''+ +''''+''''+''''+'+' + 'COALESCE(CONVERT(varchar(25),' + COLUMN_NAME + ',121),'''')' + '+' + ''''+''''+''''+''''  &lt;br /&gt;
  WHEN DATA_TYPE &lt;br /&gt;
  NOT IN ('int','bigint','smallint','tinyint','deciaml','numeric','money') &lt;br /&gt;
  THEN + ''''+ ''''+''''+''''+'+COALESCE(REPLACE(RTRIM(' + COLUMN_NAME + ')' + ','''''''','''''''''''')' + ','''')+' + ''''+''''+''''+'''' &lt;br /&gt;
  ELSE + 'COALESCE(RTRIM(CONVERT(varchar(25),' + COLUMN_NAME + ')),'''''''''''')'&lt;br /&gt;
    END&lt;br /&gt;
    FROM INFORMATION_SCHEMA.Columns&lt;br /&gt;
   WHERE TABLE_NAME = @TABLE_NAME&lt;br /&gt;
ORDER BY ORDINAL_POSITION&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;SELECT @SELECT = 'SELECT ' + @SELECT + ' AS DATA FROM ' + @TABLE_NAME&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;-- SELECT @SELECT&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;SET @cmd = 'CREATE VIEW XXX AS ' + @SELECT &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;EXEC(@cmd)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;CREATE TABLE myTable99(RowId int IDENTITY(1,1), Data varchar(8000))&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;INSERT INTO myTable99(Data) SELECT DATA FROM XXX&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;SELECT 0 AS RowId, @INSERT AS DATA INTO myTemp99&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;SET @cmd = 'CREATE VIEW YYY AS '&lt;br /&gt;
+'SELECT RowId, DATA FROM myTemp99 '&lt;br /&gt;
+'UNION ALL '&lt;br /&gt;
+'SELECT RowId, '+ '''' + 'SELECT ' + '''' + ' + DATA+ ' + '''' + ' UNION ALL ' + '''' + ' AS DATA FROM myTable99 WHERE RowId &amp;lt; (SELECT COUNT(*) FROM myTable99)'&lt;br /&gt;
+'UNION ALL '&lt;br /&gt;
+'SELECT RowId, '+ '''' + 'SELECT ' + '''' + ' + DATA AS DATA FROM myTable99 WHERE RowId = (SELECT COUNT(*) FROM myTable99) '&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;-- SELECT @cmd&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;EXEC(@cmd)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;SET @cmd = 'bcp "SELECT DATA FROM MEP.dbo.YYY ORDER BY RowId" QUERYOUT D:\MEP\Scripts\INS_'+@TABLE_NAME+'.Dat -T -c -S&amp;lt;servername&amp;gt;'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;-- SELECT @cmd&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;EXEC master..xp_cmdshell @cmd&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt; DROP VIEW XXX, YYY&lt;br /&gt;
 DROP TABLE myTable99, myTemp99&lt;br /&gt;
 SET NOCOUNT OFF&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;EXEC master..xp_cmdshell 'Dir D:\MEP\Scripts\*.*'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt; &lt;/font&gt;&lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/60082.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2007/02/08/60082.aspx</guid>
            <pubDate>Thu, 08 Feb 2007 19:39:31 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2007/02/08/60082.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/60082.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Deconstruct Text, word by word, into a single column</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2006/12/20/54496.aspx</link>
            <description>&lt;div align="left"&gt;
&lt;pre&gt;&lt;font size="2"&gt;Why, I still didn't get an answer from the &lt;a href="http://www.dbforums.com/member.php?u=140813"&gt;poster&lt;/a&gt; in this &lt;a href="http://www.dbforums.com/showthread.php?p=6248759&amp;amp;posted=1#post6248759"&gt;post&lt;/a&gt;.  &lt;/font&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;font size="2"&gt;But with &lt;a href="http://www.dbforums.com/member.php?u=7592"&gt;Rudy&lt;/a&gt; laying the ground work I came up with the following.  &lt;/font&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;font size="2"&gt;Why anyone would need to do thids, I have no idea.  I added a twist to this version &lt;/font&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;font size="2"&gt;where it counts the occurances.  The end goal here though was to find the text&lt;/font&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;font size="2"&gt;row with the most occurances of any 1 word, and order the rows in that order.&lt;/font&gt;&lt;/pre&gt;
&lt;pre&gt;Why?  I have no idea.&lt;/pre&gt;
&lt;/div&gt;
&lt;div align="left"&gt;
&lt;pre&gt;&lt;font size="2"&gt;  &lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div align="left"&gt;
&lt;pre&gt;&lt;font size="2"&gt;&lt;p&gt;&lt;font face="Arial"&gt;&lt;/font&gt; &lt;/p&gt;&lt;p&gt;create table somewords&lt;br /&gt;( id integer not null primary key identity&lt;br /&gt;, blah text not null&lt;br /&gt;);&lt;br /&gt;insert into somewords (blah) &lt;br /&gt;values ('a word that appears maximum number of times in a column')&lt;br /&gt;insert into somewords (blah) &lt;br /&gt;values ('Is it possible to get words from text columns in a sql server database')&lt;br /&gt;insert into somewords (blah) &lt;br /&gt;values ('This could solve my problem if reffered column contain only single word')&lt;br /&gt;insert into somewords (blah) &lt;br /&gt;values ('that''s going to require that you split out every word in the column individually')&lt;br /&gt;insert into somewords (blah) &lt;br /&gt;values ('the query will definitely not be easy to write')&lt;br /&gt;insert into somewords (blah) &lt;br /&gt;values ('Please read the sticky at the top of the board')&lt;br /&gt;insert into somewords (blah) &lt;br /&gt;values ('The physical order of data in a database has no meaning')&lt;br /&gt;GO&lt;/p&gt;&lt;p&gt;CREATE TABLE UniqueWords (&lt;br /&gt;   Word varchar(256)&lt;br /&gt; , WordId int IDENTITY(1,1)&lt;br /&gt; , WordCount int DEFAULT(1)&lt;br /&gt; , Add_Dt datetime DEFAULT (GetDate()))&lt;br /&gt; GO&lt;/p&gt;&lt;p&gt;CREATE UNIQUE INDEX UnqueWords_PK ON UniqueWords(Word)&lt;br /&gt;GO&lt;/p&gt;&lt;p&gt;CREATE PROC isp_INS_UNIQUE_WORDS&lt;br /&gt;AS&lt;br /&gt;BEGIN&lt;br /&gt; SET NOCOUNT ON&lt;br /&gt; DECLARE @Words INT, @Pos INT, @x Int, @str varchar(256)&lt;br /&gt;    , @word varchar(256), @start int, @end int, @exitstart int&lt;br /&gt; SELECT @Words = 0, @Pos = 1, @x = -1, @Word = '', @start = 1&lt;/p&gt;&lt;p&gt; DECLARE myCursor CURSOR FOR SELECT Blah FROM SomeWords&lt;br /&gt; OPEN myCursor&lt;br /&gt; FETCH NEXT FROM myCursor INTO @str&lt;/p&gt;&lt;p&gt; WHILE @@FETCH_STATUS = 0&lt;br /&gt;   BEGIN&lt;br /&gt;  WHILE (@x &amp;lt;&amp;gt; 0)&lt;br /&gt;   BEGIN&lt;br /&gt;    SET @x     = CHARINDEX(' ', @str, @Pos)&lt;br /&gt;    IF @x &amp;lt;&amp;gt; 0&lt;br /&gt;      BEGIN &lt;br /&gt;     SET @end   = @x - @start&lt;br /&gt;     SET @word  = SUBSTRING(@str,@start,@end)&lt;br /&gt;     IF NOT EXISTS (SELECT * FROM UniqueWords WHERE Word = @Word)&lt;br /&gt;      INSERT INTO UniqueWords(Word) SELECT @word&lt;br /&gt;       ELSE&lt;br /&gt;      UPDATE UniqueWords SET WordCount = WordCount + 1 WHERE Word = @Word&lt;br /&gt;     -- SELECT @Word, @@ROWCOUNT,@@ERROR&lt;br /&gt;     -- SELECT @x, @Word, @start, @end, @str&lt;br /&gt;     SET @exitstart = @start + @end + 1&lt;br /&gt;     SET @Pos   = @x + 1&lt;br /&gt;     SET @start = @x + 1&lt;br /&gt;     SET @Words = @Words + 1&lt;br /&gt;      END&lt;br /&gt;    IF @x = 0&lt;br /&gt;      BEGIN&lt;br /&gt;     SET @word  = SUBSTRING(@str,@exitstart,LEN(@str)-@exitstart+1)&lt;br /&gt;     IF NOT EXISTS (SELECT * FROM UniqueWords WHERE Word = @Word)&lt;br /&gt;      INSERT INTO UniqueWords(Word) SELECT @word&lt;br /&gt;       ELSE&lt;br /&gt;      UPDATE UniqueWords SET WordCount = WordCount + 1 WHERE Word = @Word&lt;br /&gt;     -- SELECT @Word, @@ROWCOUNT,@@ERROR&lt;br /&gt;     -- SELECT @x, @Word, @exitstart, LEN(@str)-@exitstart, @str&lt;br /&gt;      END&lt;br /&gt;   END&lt;br /&gt;  FETCH NEXT FROM myCursor INTO @str&lt;br /&gt;  SELECT @Words = 0, @Pos = 1, @x = -1, @Word = '', @start = 1&lt;br /&gt;   END &lt;/p&gt;&lt;p&gt;   CLOSE myCursor&lt;br /&gt;   DEALLOCATE myCursor&lt;br /&gt;   SET NOCOUNT OFF&lt;br /&gt; RETURN @Words&lt;br /&gt;END&lt;br /&gt;GO&lt;/p&gt;&lt;p&gt;EXEC isp_INS_UNIQUE_WORDS&lt;br /&gt;GO&lt;/p&gt;&lt;p&gt;SELECT * FROM UniqueWords ORDER BY Word&lt;br /&gt;GO&lt;/p&gt;&lt;p&gt;DROP PROC isp_INS_UNIQUE_WORDS&lt;br /&gt;DROP TABLE UniqueWords, somewords&lt;br /&gt;GO&lt;br /&gt;&lt;/p&gt;&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/54496.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2006/12/20/54496.aspx</guid>
            <pubDate>Wed, 20 Dec 2006 20:27:13 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2006/12/20/54496.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/54496.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Generate Triggers for all Tables</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2006/11/29/35816.aspx</link>
            <description>&lt;p&gt;Well, I did this originally to generate triggers for all tables in a database to audit data changes, and that is simple enough, just move the entire row from the deleted table to a mirrored audit table.&lt;/p&gt;
&lt;p&gt;But someone wanted to track activity on tables, so it's a little more simple.  Here we create one log table, and any time a dml operation occurs, it is written there.&lt;/p&gt;
&lt;p&gt;Enjoy&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;USE Northwind&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;CREATE TABLE LOG_TABLE (Add_dttm datetime DEFAULT (GetDate()), TABLE_NAME sysname, Activity char(6))&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;DECLARE @sql varchar(8000), @TABLE_NAME sysname&lt;br /&gt;
SET NOCOUNT ON&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT @TABLE_NAME = MIN(TABLE_NAME) FROM INFORMATION_SCHEMA.Tables&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;WHILE @TABLE_NAME IS NOT NULL&lt;br /&gt;
  BEGIN&lt;br /&gt;
 SELECT @sql = 'CREATE TRIGGER [' + @TABLE_NAME + '_Usage_TR] ON [' + @TABLE_NAME +'] '&lt;br /&gt;
  + 'FOR INSERT, UPDATE, DELETE AS '&lt;br /&gt;
  + 'IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted) '&lt;br /&gt;
  + 'INSERT INTO LOG_TABLE (TABLE_NAME,Activity) SELECT ''' + @TABLE_NAME + ''', ''INSERT''' + ' '&lt;br /&gt;
  + 'IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted) '&lt;br /&gt;
  + 'INSERT INTO LOG_TABLE (TABLE_NAME,Activity) SELECT ''' + @TABLE_NAME + ''', ''UPDATE''' + ' '&lt;br /&gt;
  + 'IF NOT EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted) '&lt;br /&gt;
  + 'INSERT INTO LOG_TABLE (TABLE_NAME,Activity) SELECT ''' + @TABLE_NAME + ''', ''DELETE''' + ' GO'&lt;br /&gt;
 SELECT @sql&lt;br /&gt;
 EXEC(@sql)&lt;br /&gt;
 SELECT @TABLE_NAME = MIN(TABLE_NAME) FROM INFORMATION_SCHEMA.Tables WHERE TABLE_NAME &amp;gt; @TABLE_NAME &lt;br /&gt;
  END&lt;br /&gt;
SET NOCOUNT OFF&lt;br /&gt;
&lt;/font&gt;&lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/35816.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2006/11/29/35816.aspx</guid>
            <pubDate>Wed, 29 Nov 2006 14:49:22 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2006/11/29/35816.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/35816.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Hierarchies with a twist...rocks, no salt</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2006/11/13/23995.aspx</link>
            <description>&lt;p&gt;EDIT:  The script has been repaired and paired down.&lt;/p&gt;
&lt;p&gt;Basically this "solution" assigns a derived value to each entity...which I called codex for lack of better term.  Each Child inherits their Parents Codex node signature.  In the code below I show how to add a new position in the tree and how to move an entire branch...not sure what else you would want to do, but if you let me know, I'll take a crack at.  It also shows how to "mine" different element of meta data about the tree.&lt;/p&gt;
&lt;p&gt;This is a &lt;a href="http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=74844"&gt;link that launched this discussion&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ever wanted to do set based &lt;font face="Arial"&gt;Hierarchical SQL?  We came up with a twist, but you need to create a derived column AND it needs to be maintained, but  this is something we implemented in a production system and seems to work very nicely.  That was in DB2 and requires more effort, but the SQL Server version allows you to use more complex contructs than DB2.  DB2 requires more "leg work" to do the same thing.  So it is a "dumbed down" version of SQL.  I'm sure the multiple host variable assignments can be consolidated, but I need this as a spec for now.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;I offer this...now if someone has thought of this before, please let me know.  In any case I built this without any refernce to anything else.&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SET NOCOUNT ON&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Create a table to hold a Position Tree&lt;br /&gt;
CREATE TABLE myPositions99 (Manager varchar(50), Employee varchar(50), codex varchar(800))&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Create Work Tables for all the potential levels&lt;br /&gt;
CREATE TABLE Level1 (Level1Code int IDENTITY(1,1), Manager varchar(50), Employee varchar(50), codex varchar(800))&lt;br /&gt;
CREATE TABLE Level2 (Level2Code int IDENTITY(1,1), Manager varchar(50), Employee varchar(50), codex varchar(800))&lt;br /&gt;
CREATE TABLE Level3 (Level3Code int IDENTITY(1,1), Manager varchar(50), Employee varchar(50), codex varchar(800))&lt;br /&gt;
CREATE TABLE Level4 (Level4Code int IDENTITY(1,1), Manager varchar(50), Employee varchar(50), codex varchar(800))&lt;br /&gt;
CREATE TABLE Level5 (Level5Code int IDENTITY(1,1), Manager varchar(50), Employee varchar(50), codex varchar(800))&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Create a view of all the work tables&lt;br /&gt;
CREATE VIEW myView99 AS&lt;br /&gt;
SELECT * FROM Level1 UNION ALL&lt;br /&gt;
SELECT * FROM Level2 UNION ALL&lt;br /&gt;
SELECT * FROM Level3 UNION ALL&lt;br /&gt;
SELECT * FROM Level4 UNION ALL&lt;br /&gt;
SELECT * FROM Level5&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO myPositions99(Manager, Employee) &lt;br /&gt;
SELECT  null  , 'Gerard' UNION ALL&lt;br /&gt;
SELECT 'Gerard'  , 'Mike' UNION ALL&lt;br /&gt;
SELECT 'Gerard'  , 'Pat'  UNION ALL&lt;br /&gt;
SELECT 'Gerard'  , 'Dan'  UNION ALL&lt;br /&gt;
SELECT 'Mike'  , 'Nick'  UNION ALL&lt;br /&gt;
SELECT 'Mike'  , 'Erinn'  UNION ALL&lt;br /&gt;
SELECT 'Mike'  , 'Jeanne'  UNION ALL&lt;br /&gt;
SELECT 'Pat'  , 'Elene'  UNION ALL&lt;br /&gt;
SELECT 'Pat'  , 'Claudette'  UNION ALL&lt;br /&gt;
SELECT 'Nick'  , 'Algene'  UNION ALL&lt;br /&gt;
SELECT 'Nick'  , 'Brett'  UNION ALL&lt;br /&gt;
SELECT 'Nick'  , 'Lana'  UNION ALL&lt;br /&gt;
SELECT 'Claudette' , 'Susan'  UNION ALL&lt;br /&gt;
SELECT 'Claudette' , 'Tom'  UNION ALL&lt;br /&gt;
SELECT 'Dan'  , 'Bob'  UNION ALL&lt;br /&gt;
SELECT 'Bob'  , 'Ellen'  UNION ALL&lt;br /&gt;
SELECT 'Erinn'  , 'Nar'  UNION ALL&lt;br /&gt;
SELECT 'Erinn'  , 'Gary'  UNION ALL&lt;br /&gt;
SELECT 'Erinn'  , 'Pete'&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT * FROM myPositions99&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Populate all of the work tables with the employees at their particular levels&lt;br /&gt;
-- and assign the codex values&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO Level1 (Manager, Employee)&lt;br /&gt;
    SELECT l.Manager, l.Employee&lt;br /&gt;
      FROM myPositions99 l &lt;br /&gt;
     WHERE l.Manager IS NULL&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;UPDATE Level1 SET Codex = RIGHT(REPLICATE('0',5) + CONVERT(varchar(5),Level1Code),5) FROM Level1&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO Level2 (Manager, Employee, Codex)&lt;br /&gt;
    SELECT r.Manager, r.Employee, l.Codex  &lt;br /&gt;
      FROM Level1 l &lt;br /&gt;
 LEFT JOIN myPositions99 r &lt;br /&gt;
 ON l.Employee = r.Manager &lt;br /&gt;
     WHERE l.Manager IS NULL&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;UPDATE Level2 SET Codex = COALESCE(Codex,'') + RIGHT(REPLICATE('0',5) + CONVERT(varchar(5),Level2Code),5) FROM Level2&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO Level3 (Manager, Employee, Codex)&lt;br /&gt;
    SELECT r.Manager, r.Employee, l.Codex  &lt;br /&gt;
      FROM Level2 l &lt;br /&gt;
 LEFT JOIN myPositions99 r &lt;br /&gt;
 ON l.Employee = r.Manager &lt;br /&gt;
     WHERE r.Manager IS NOT NULL&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;UPDATE Level3 SET Codex = COALESCE(Codex,'') + RIGHT(REPLICATE('0',5) + CONVERT(varchar(5),Level3Code),5) FROM Level3&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO Level4 (Manager, Employee, Codex)&lt;br /&gt;
    SELECT r.Manager, r.Employee, l.Codex  &lt;br /&gt;
      FROM Level3 l &lt;br /&gt;
 LEFT JOIN myPositions99 r &lt;br /&gt;
 ON l.Employee = r.Manager &lt;br /&gt;
     WHERE r.Manager IS NOT NULL&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;UPDATE Level4 SET Codex = COALESCE(Codex,'') + RIGHT(REPLICATE('0',5) + CONVERT(varchar(5),Level4Code),5) FROM Level4&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- We do the final level and check @@ROWCOUNT to show that there are no more levels&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO Level5 (Manager, Employee, Codex)&lt;br /&gt;
    SELECT r.Manager, r.Employee, l.Codex  &lt;br /&gt;
      FROM Level4 l &lt;br /&gt;
 LEFT JOIN myPositions99 r &lt;br /&gt;
 ON l.Employee = r.Manager &lt;br /&gt;
     WHERE r.Manager IS NOT NULL&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;UPDATE Level5 SET Codex = COALESCE(Codex,'') + RIGHT(REPLICATE('0',5) + CONVERT(varchar(5),Level5Code),5) FROM Level5&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Using the Viewe (essentially all the work tables) update the position tree&lt;br /&gt;
UPDATE P SET CODEX = v.CODEX &lt;br /&gt;
FROM myPositions99 P JOIN myView99 v ON p.Employee = v.Employee &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Show Me Pat's group&lt;br /&gt;
    SELECT * &lt;br /&gt;
      FROM myPositions99  l&lt;br /&gt;
 LEFT JOIN myPositions99  r&lt;br /&gt;
 ON r.Codex LIKE l.codex + '%'&lt;br /&gt;
       AND l.Codex &amp;lt;&amp;gt; r.Codex&lt;br /&gt;
     WHERE l.Employee = 'Pat'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New" size="2"&gt;-- Show me 2 levels down from the top&lt;br /&gt;
    SELECT * &lt;br /&gt;
      FROM myPositions99 l&lt;br /&gt;
 LEFT JOIN myPositions99 r&lt;br /&gt;
 ON r.Codex LIKE l.codex + '%'&lt;br /&gt;
       AND l.Codex &amp;lt;&amp;gt; r.Codex&lt;br /&gt;
       AND LEN(r.codex)/5 &amp;lt; 4&lt;br /&gt;
     WHERE LEN(l.codex)/5 = 1&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Show me everyones level&lt;br /&gt;
    SELECT Employee, LEN(codex)/5, Codex AS LevelCode &lt;br /&gt;
      FROM myPositions99&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Add a new employee that reports to the top&lt;br /&gt;
DECLARE @MNGR_CODEX varchar(800), @NEW_CODEX varchar(800), @CHNG_CODEX varchar(800)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT @MNGR_CODEX = RTRIM(CODEX) FROM myPositions99 &lt;br /&gt;
 WHERE Employee = 'Gerard'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;SELECT @NEW_CODEX = @MNGR_CODEX+RIGHT(RTRIM('00000'+CONVERT(varchar(800),(MAX(NEW_CODEX)+1))),5)                            &lt;br /&gt;
  FROM (SELECT CONVERT(int,SUBSTRING(CODEX,LEN(@MNGR_CODEX)+1,5)) AS NEW_CODEX                                                          &lt;br /&gt;
          FROM myPositions99&lt;br /&gt;
         WHERE CODEX LIKE @MNGR_CODEX+'%'                                                                          &lt;br /&gt;
           AND LEN(RTRIM(CODEX)) =  LEN(@MNGR_CODEX)+5) AS XXX&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;INSERT INTO myPositions99(Manager, Employee, codex)&lt;br /&gt;
SELECT    'Gerard' AS Manager&lt;br /&gt;
 , 'Mickey' AS Employee&lt;br /&gt;
 , @NEW_CODEX&lt;br /&gt;
 &lt;br /&gt;
-- Show me Gerard's direct reports&lt;br /&gt;
SELECT * FROM myPositions99 WHERE Manager = 'Gerard'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Now let's move a branch....move Nicky Under Pat&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- What's the tree look like now?&lt;br /&gt;
SELECT codex, SPACE(LEN(codex)-5)+Employee FROM myPositions99 ORDER BY codex&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Get a new codex using Pat's codex info (The Manger) and Nicky's (The Employee)&lt;br /&gt;
DECLARE @MNGR_CODEX varchar(800), @NEW_CODEX varchar(800), @CHNG_CODEX varchar(800)&lt;br /&gt;
SELECT @MNGR_CODEX = RTRIM(CODEX) FROM myPositions99 WHERE Employee = 'Pat'&lt;br /&gt;
SELECT @CHNG_CODEX = RTRIM(CODEX) FROM myPositions99 WHERE Employee = 'Nick'&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Find the New codex For Nicky, using Pat's Codex Node&lt;br /&gt;
SELECT @NEW_CODEX = @MNGR_CODEX+RIGHT(RTRIM('00000'+CONVERT(varchar(800),(MAX(NEW_CODEX)+1))),5)  &lt;br /&gt;
  FROM (SELECT CONVERT(int,SUBSTRING(CODEX,LEN(@MNGR_CODEX)+1,5)) AS NEW_CODEX&lt;br /&gt;
          FROM myPositions99                  &lt;br /&gt;
         WHERE CODEX LIKE @MNGR_CODEX+'%'                                                &lt;br /&gt;
           AND LEN(RTRIM(CODEX)) =  LEN(@MNGR_CODEX)+5) AS XXX&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- Now take the New Codex and change Nicky, and change every underlying Codex Node for the rest of the employees&lt;br /&gt;
UPDATE P&lt;br /&gt;
   SET CODEX = @NEW_CODEX + SUBSTRING(CODEX,LEN(RTRIM(@CHNG_CODEX))+1,800-LEN(RTRIM(@CHNG_CODEX)))&lt;br /&gt;
  FROM myPositions99 P&lt;br /&gt;
 WHERE CODEX LIKE @CHNG_CODEX + '%'&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;-- What's the tree look like now?&lt;br /&gt;
SELECT codex, SPACE(LEN(codex)-5)+Employee FROM myPositions99 ORDER BY codex&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New" size="2"&gt;DROP VIEW myView99&lt;br /&gt;
DROP TABLE Level1&lt;br /&gt;
DROP TABLE Level2&lt;br /&gt;
DROP TABLE Level3&lt;br /&gt;
DROP TABLE Level4&lt;br /&gt;
DROP TABLE Level5&lt;br /&gt;
DROP TABLE myPositions99&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/23995.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2006/11/13/23995.aspx</guid>
            <pubDate>Mon, 13 Nov 2006 21:36:59 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2006/11/13/23995.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/23995.aspx</wfw:commentRss>
        </item>
        <item>
            <title>How do I find all the tables referenced by Stored Procedures or Functions</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2006/09/22/12454.aspx</link>
            <description>&lt;p&gt;Like this&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;SELECT o.name, t.TABLE_NAME, c.text &lt;br /&gt;
  FROM syscomments c &lt;br /&gt;
  JOIN sysobjects o &lt;br /&gt;
    ON c.id = o.id&lt;br /&gt;
  JOIN INFORMATION_SCHEMA.Tables t&lt;br /&gt;
    ON  c.text LIKE '%'+t.TABLE_NAME+'%' &lt;br /&gt;
&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/12454.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2006/09/22/12454.aspx</guid>
            <pubDate>Fri, 22 Sep 2006 16:32:54 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2006/09/22/12454.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/12454.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Stored Procedure Logging</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2006/09/21/12391.aspx</link>
            <description>&lt;p&gt;Every so often, someone asks, "How do I know who executed a SQL Statement against my database".&lt;/p&gt;
&lt;p&gt;Well you can either have SQL Profiler running all the time (which can be very expensive), or you can use Lumingent's Log Explorer.&lt;/p&gt;
&lt;p&gt;I have taken a different tack lately.&lt;/p&gt;
&lt;p&gt;Any Access to a database I am supporting will be done &lt;strong&gt;ONLY&lt;/strong&gt; Through stored procedures.  OK, that's not "lately", but the part I've added is that the developers MUST call the sproc below.  What this does is to log every stored procedure call.  I now have statistics as to what's being called when, and how long the operation takes.  There are several benefits, but the best being that I can see which developers don't have their thinking cap on in dev, and we can proactiveley review these sprocs.&lt;/p&gt;
&lt;p&gt;OK, now you say, how do you know that developer is callin the logging sproc, and the short answer is, that in dev, I don't.  However, No sprocs get moved to QA without a reivew by me or someone on the DBA team.  Once it's in QA, they can't touch the code.  After QA Sign off, the that code gets moved to UAT, then up to PROD.&lt;/p&gt;
&lt;p&gt;In any case I find it useful, and the execution of the logging is in the microseconds.  I guess the downside of a app that gets slammed with millions of hits is that this could add up and affect performance, but shy of that, we have not noticed any impact.  In any case, for what it's worth here's the sproc and the table DDL.  One other note, I do this on other platforms as well, for example DB2 OS/390...only problem there is the need to monitor the tablespace for this table, since you coul blow out on extents...which is not really a problem on SQL Server...except that you potentially could run out of disk space...In either case, you need to monitor that, and archive the data.  Any comments are appreciated.&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[usp_LogProcCalls]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)&lt;br /&gt;
drop procedure [dbo].[usp_LogProcCalls]&lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;SET QUOTED_IDENTIFIER OFF &lt;br /&gt;
GO&lt;br /&gt;
SET ANSI_NULLS ON &lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;font face="Arial"&gt;
&lt;p&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;CREATE PROCEDURE [dbo].[usp_LogProcCalls] (&lt;br /&gt;
   @SprocName  sysname&lt;br /&gt;
 , @TranStart  datetime&lt;br /&gt;
 , @TranEnd  datetime&lt;br /&gt;
 , @Rows  int&lt;br /&gt;
 , @Err   int&lt;br /&gt;
 , @Paramters varchar(255)&lt;br /&gt;
 , @rc   int OUTPUT)&lt;br /&gt;
AS&lt;br /&gt;
SET NOCOUNT ON&lt;br /&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;Declare @error int, @RowCount int, @Error_Message varchar(255), @Error_Type int, @Error_Loc int&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;BEGIN TRAN&lt;br /&gt;
 DECLARE @LogStart datetime&lt;br /&gt;
 SELECT @rc = 0, @LogStart = GetDate()&lt;br /&gt;
  IF (SELECT @@TRANCOUNT) &amp;lt;&amp;gt; 1&lt;br /&gt;
   BEGIN &lt;br /&gt;
    SELECT @Error_Loc = 1&lt;br /&gt;
         , @Error_Message =  'The logging procedure must be executed outside of any transaction.  @@TRANSCOUNT='&lt;br /&gt;
   + CONVERT(varchar(5),@@TRANCOUNT)&lt;br /&gt;
         , @Error_Type = 50002, @rc = -6661&lt;br /&gt;
    GOTO usp_LogProcCalls_Error&lt;br /&gt;
   END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt; INSERT INTO Sproc_Log (&lt;br /&gt;
   [SprocName]&lt;br /&gt;
 , [TranStart]&lt;br /&gt;
 , [TranEnd]&lt;br /&gt;
 , [LogStart]&lt;br /&gt;
 , [LogEnd]&lt;br /&gt;
 , [Rows]&lt;br /&gt;
 , [Err]&lt;br /&gt;
 , [Paramters])&lt;br /&gt;
 SELECT &lt;br /&gt;
   @SprocName&lt;br /&gt;
 , @TranStart&lt;br /&gt;
 , @TranEnd&lt;br /&gt;
 , @LogStart&lt;br /&gt;
 , GetDate()&lt;br /&gt;
 , @Rows&lt;br /&gt;
 , @Err&lt;br /&gt;
 , @Paramters&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;  Select @RowCount = @@ROWCOUNT, @error = @@error&lt;br /&gt;
 &lt;br /&gt;
  IF @error &amp;lt;&amp;gt; 0&lt;br /&gt;
   BEGIN&lt;br /&gt;
    SELECT @Error_Loc = 2, @Error_Type = 50001, @rc = -6662&lt;br /&gt;
    GOTO usp_LogProcCalls_Error&lt;br /&gt;
   END&lt;br /&gt;
 &lt;br /&gt;
  IF @RowCount &amp;lt;&amp;gt; 1&lt;br /&gt;
   BEGIN &lt;br /&gt;
    SELECT @Error_Loc = 3&lt;br /&gt;
         , @Error_Message =  'Expected 1 row to be inserted in to the sproc log.  Actual Number inserted = '&lt;br /&gt;
   + CONVERT(varchar(5),@RowCount)&lt;br /&gt;
         , @Error_Type = 50002, @rc = -6663&lt;br /&gt;
    GOTO usp_LogProcCalls_Error&lt;br /&gt;
   END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;COMMIT TRAN&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;usp_LogProcCalls_Exit:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;RETURN &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;usp_LogProcCalls_Error:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;Rollback TRAN&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;If @Error_Type = 50001&lt;br /&gt;
 BEGIN&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;  Select @error_message = (Select 'Location: ' + ',"' + RTrim(Convert(char(3),@Error_Loc))  &lt;br /&gt;
          + ',"' + '  @@ERROR: ' + ',"' + RTrim(Convert(char(6),error))&lt;br /&gt;
          + ',"' + ' Severity: ' + ',"' + RTrim(Convert(char(3),severity))&lt;br /&gt;
          From master..sysmessages&lt;br /&gt;
        Where error = @error)&lt;br /&gt;
 END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;If @Error_Type = 50002&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt; BEGIN&lt;br /&gt;
  Select @Error_Message = 'Location: ' + ',"' + RTrim(Convert(char(3),@Error_Loc)) &lt;br /&gt;
                   + ',"' + ' Severity:  UserLevel ' &lt;br /&gt;
              + ',"' + ' Message: ' + ',"' + RTrim(@Error_Message)&lt;br /&gt;
 END&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;RAISERROR @Error_Type @Error_Message&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;GOTO usp_LogProcCalls_Exit&lt;br /&gt;
GO&lt;br /&gt;
SET QUOTED_IDENTIFIER OFF &lt;br /&gt;
GO&lt;br /&gt;
SET ANSI_NULLS ON &lt;br /&gt;
GO&lt;/font&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Sproc_Log]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)&lt;br /&gt;
drop table [dbo].[Sproc_Log]&lt;br /&gt;
GO&lt;/p&gt;
&lt;p&gt;CREATE TABLE [dbo].[Sproc_Log] (&lt;br /&gt;
 [SprocName] [sysname] NOT NULL ,&lt;br /&gt;
 [TranStart] [datetime] NOT NULL ,&lt;br /&gt;
 [TranEnd] [datetime] NOT NULL ,&lt;br /&gt;
 [SYSTEM_USER] [char] (30) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,&lt;br /&gt;
 [LogStart] [datetime] NOT NULL ,&lt;br /&gt;
 [LogEnd] [datetime] NOT NULL ,&lt;br /&gt;
 [Rows] [int] NOT NULL ,&lt;br /&gt;
 [Err] [int] NOT NULL ,&lt;br /&gt;
 [Paramters] [varchar] (255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL &lt;br /&gt;
) ON [PRIMARY]&lt;br /&gt;
GO&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;&lt;/font&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/12391.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2006/09/21/12391.aspx</guid>
            <pubDate>Thu, 21 Sep 2006 13:38:09 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2006/09/21/12391.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/12391.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Finding Trade and Receipt fallout</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2006/09/20/12368.aspx</link>
            <description>&lt;p&gt;A director came to me asking if a set based approach could be used to find the fallout for trades and receipts.  Even though they handed the work off already.  The developer  used COBOL to compare the 2 file and did "spin-up" processing to match a trade to a receipt.  Only probalem is that is totally arbitrary since the "key" was basicall generic and did not exactly marry the receipt to the trade.  So their "fallout" was based on LILO.  They considered everything else as a match.&lt;/p&gt;
&lt;p&gt;What they really needed to do was identify target population that have "fallout" and address those populations as a whole.  Which they have not I don't think..mostly because they believe they have their solutiion.  In any case, this, in my own opinion (MOO) is what should have been done.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;USE Northwind&lt;br /&gt;
GO&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;CREATE TABLE myTrades99   (myKey int, myDate datetime)&lt;br /&gt;
CREATE TABLE myReceipts99 (myKey int, myDate datetime)&lt;br /&gt;
GO&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;INSERT INTO myTrades99(myKey, myDate)&lt;br /&gt;
SELECT 1, '1/1/2006' UNION ALL&lt;br /&gt;
SELECT 1, '2/1/2006' UNION ALL&lt;br /&gt;
SELECT 1, '3/1/2006' UNION ALL&lt;br /&gt;
SELECT 2, '1/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '1/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '2/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '3/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '4/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '5/1/2006'&lt;br /&gt;
GO&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;INSERT INTO myReceipts99(myKey, myDate)&lt;br /&gt;
SELECT 2, '1/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '1/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '2/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '3/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '4/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '5/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '1/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '2/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '3/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '4/1/2006' UNION ALL&lt;br /&gt;
SELECT 3, '4/1/2006' UNION ALL&lt;br /&gt;
SELECT 4, '5/1/2006'&lt;br /&gt;
GO&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;   SELECT COALESCE(XXX.myKey, YYY.myKey) as myKey, TradeCount, ReceiptCount &lt;br /&gt;
     FROM (&lt;br /&gt;
     SELECT 'Trade' AS Source, myKey, COUNT(*) AS TradeCount&lt;br /&gt;
       FROM myTrades99&lt;br /&gt;
   GROUP BY myKey) AS XXX&lt;br /&gt;
FULL JOIN (&lt;br /&gt;
     SELECT 'Receipt' AS Source, myKey, COUNT(*) AS ReceiptCount&lt;br /&gt;
       FROM myReceipts99&lt;br /&gt;
   GROUP BY myKey) AS YYY&lt;br /&gt;
       ON XXX.myKey = YYY.myKey&lt;br /&gt;
    WHERE COALESCE(ReceiptCount,0) &amp;lt;&amp;gt; COALESCE(TradeCount,0)&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;-- Returns the fallout population with Set based processing&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;-- myKey       TradeCount  ReceiptCount &lt;br /&gt;
-- ----------- ----------- ------------ &lt;br /&gt;
-- 1           3           NULL&lt;br /&gt;
-- 3           5           10&lt;br /&gt;
-- 4           NULL        1&lt;br /&gt;
-- &lt;br /&gt;
-- (3 row(s) affected)&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;Go &lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;strong&gt;SET NOCOUNT OFF&lt;br /&gt;
DROP TABLE myTrades99, myReceipts99&lt;br /&gt;
GO&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/12368.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2006/09/20/12368.aspx</guid>
            <pubDate>Wed, 20 Sep 2006 17:31:21 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2006/09/20/12368.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/12368.aspx</wfw:commentRss>
        </item>
        <item>
            <title>sp_depends for DB2</title>
            <link>http://weblogs.sqlteam.com/brettk/archive/2006/09/20/12361.aspx</link>
            <description>&lt;p&gt;Well, there really isn't anything that I know of that is like sp_depends for DB2 z/OS Version 7.2.  Hopefully V8 will alot more features...but for Now you have to interogate the catalog.  So this is how you do it....&lt;/p&gt;
&lt;p&gt;&lt;font style="BACKGROUND-COLOR: #000000" face="Courier New"&gt;&lt;font color="#00ff00"&gt;&lt;strong&gt;    SELECT DISTINCT NAME,DNAME,BNAME                 &lt;br /&gt;
      FROM SYSIBM.SYSPACKDEP D                       &lt;br /&gt;
INNER JOIN SYSIBM.SYSPACKSTMT S                      &lt;br /&gt;
        ON D.DCOLLID = S.COLLID AND D.DNAME = S.NAME &lt;br /&gt;
       AND D.DCONTOKEN = S.CONTOKEN                  &lt;br /&gt;
     WHERE BQUALIFIER = 'AXHRSPDA'                   &lt;br /&gt;
       AND BNAME IN('POSITION_TREE')                 &lt;br /&gt;
  ORDER BY NAME,DNAME,BNAME                          &lt;br /&gt;
;&lt;/strong&gt;&lt;/font&gt;                                                    &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="BACKGROUND-COLOR: #000000" face="Courier New"&gt;&lt;font style="BACKGROUND-COLOR: #ffffff" color="#000000"&gt;And this new editor for posting is pretty neat...lots of features...like background color...and for anyone not familiar with the mainframe...that's what I get to look at all day..until I get another SQL Server project&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="BACKGROUND-COLOR: #000000" face="Courier New"&gt;&lt;font style="BACKGROUND-COLOR: #ffffff"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font style="BACKGROUND-COLOR: #000000" face="Courier New"&gt;&lt;font style="BACKGROUND-COLOR: #ffffff"&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://weblogs.sqlteam.com/brettk/aggbug/12361.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Brett Kaiser (x002548)</dc:creator>
            <guid>http://weblogs.sqlteam.com/brettk/archive/2006/09/20/12361.aspx</guid>
            <pubDate>Wed, 20 Sep 2006 15:21:55 GMT</pubDate>
            <comments>http://weblogs.sqlteam.com/brettk/archive/2006/09/20/12361.aspx#feedback</comments>
            <wfw:commentRss>http://weblogs.sqlteam.com/brettk/comments/commentRss/12361.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>