Advertisement
Guest User

MSSQL procedure: generate Create Table SQL

a guest
Nov 1st, 2013
2,590
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
SQL 61.87 KB | None | 0 0
  1. -- USAGE: exec sp_GetDDL YourTableName
  2. --   or   exec sp_GetDDL 'bob.example'
  3. --   or   exec sp_GetDDL '[schemaname].[tablename]'
  4. --#############################################################################
  5. -- copyright 2004-2013 by Lowell Izaguirre scripts*at*stormrage.com all rights reserved.
  6. -- http://www.stormrage.com/SQLStuff/sp_GetDDL_Latest.txt
  7. --
  8. -- see the thread here for lots of details: http://www.sqlservercentral.com/Forums/Topic751783-566-7.aspx
  9. --
  10. -- V300  uses String concatination and sys.tables instead of a cursor
  11. -- V301  enhanced 07/31/2009 to include extended properties definitions
  12. -- V302  fixes an issue where the schema is created , ie 'bob', but no user named 'bob' owns the schema, so the table is not found
  13. -- V303  fixes an issue where all rules are appearing, instead of jsut the rule related to a column
  14. -- V304  testing whether vbCrLf is better than just CHAR(13), some formatting cleanup with GO statements
  15. --       also fixed an issue with the conversion from syscolumns to sys.columns, max-length is only field we need, not [precision]
  16. -- V305  user feedback helped me find that the type_name function should call user_type_id instead of system_type_id
  17. --       also fixed issue where identity definition missing from numeric/decimal definition
  18. -- V306  fixes the computed columns definition that got broken/removed somehow in V300
  19. --       also formatting when decimal is not an identity
  20. -- V307  fixes bug identified by David Griffiths-491597 from SSC where the  @TABLE_ID
  21. --       is reselected, but without it's schema  , potentially selecting the wrong table
  22. --       also fixed is the missing size definition for varbinary, also found by David Griffith
  23. -- V308  abtracted all SQLs to use Table Alaises
  24. --       added logic to script a temp table.
  25. --       added warning about possibly not being marked as system object.
  26. -- V309  added logic based on feedback from Vincent Wylenzek @SSC to return the definition from sys.sql_modules for
  27. --       any object like procedure/view/function/trigger, and not just a table.
  28. --       note previously, if you pointed sp_GetDDL at a view, it returned the view definition as a table...
  29. --       now it will return the view definition instead.
  30. -- V309a returns multi row recordset, one line per record
  31. -- V310a fixed the commented out code related to collation identified by moadh.bs @SSC
  32. --       changed the DEFAULT definitions to not include the default name.
  33. -- V310b Added PERSISTED to calculated columns where applicable
  34. -- V310b fixed COLLATE statement for temp tables
  35. -- V310c fixed NVARCHAR size misreported as doubled.
  36. -- V311  fixed issue where indexes did not identify if the column was ASC or DESC found by nikus @ SSC
  37. -- V311a fixed issue where indexes did not identify if the index was CLSITERED or NONCLUSTERED found by nikus @ SSC 02/22/2013
  38. -- You can use this however you like...this script is not rocket science, but it took a bit of work to create.
  39. -- the only thing that I ask
  40. -- is that if you adapt my procedure or make it better, to simply send me a copy of it,
  41. -- so I can learn from the things you've enhanced.The feedback you give will be what makes
  42. -- it worthwhile to me, and will be fed back to the SQL community.
  43. -- add this to your toolbox of helpful scripts.
  44. -- DROP PROCEDURE [dbo].[sp_GetDDL]
  45. --#############################################################################
  46. --if you are going to put this in MASTER, and want it to be able to query
  47. --each database's sys.indexes, you MUST mark it as a system procedure:
  48. --EXECUTE sp_ms_marksystemobject 'sp_GetDDL'
  49. --#############################################################################
  50.  
  51. USE master
  52. GO
  53. ALTER PROCEDURE [dbo].[sp_GetDDL]
  54.   @TBL                VARCHAR(255)
  55. AS
  56. BEGIN
  57.   SET NOCOUNT ON
  58.   DECLARE     @TBLNAME                VARCHAR(200),
  59.               @SCHEMANAME             VARCHAR(255),
  60.               @STRINGLEN              INT,
  61.               @TABLE_ID               INT,
  62.               @FINALSQL               VARCHAR(MAX),
  63.               @CONSTRAINTSQLS         VARCHAR(MAX),
  64.               @CHECKCONSTSQLS         VARCHAR(MAX),
  65.               @RULESCONSTSQLS         VARCHAR(MAX),
  66.               @FKSQLS                 VARCHAR(MAX),
  67.               @TRIGGERSTATEMENT       VARCHAR(MAX),
  68.               @EXTENDEDPROPERTIES     VARCHAR(MAX),
  69.               @INDEXSQLS              VARCHAR(MAX),
  70.               @vbCrLf                 CHAR(2),
  71.               @ISSYSTEMOBJECT         INT,
  72.               @PROCNAME               VARCHAR(256),
  73.               @INPUT                  VARCHAR(MAX)
  74.  
  75. --##############################################################################
  76. -- INITIALIZE
  77. --##############################################################################
  78.   SET @INPUT = ''
  79.   --new code: determine whether this proc is marked as a system proc with sp_ms_marksystemobject,
  80.   --which flips the is_ms_shipped bit in sys.objects
  81.     SELECT @ISSYSTEMOBJECT = ISNULL(is_ms_shipped,0),@PROCNAME = ISNULL(name,'pr_GetDDL') FROM sys.objects WHERE object_id = @@PROCID
  82.   IF @ISSYSTEMOBJECT IS NULL
  83.     SELECT @ISSYSTEMOBJECT = ISNULL(is_ms_shipped,0),@PROCNAME = ISNULL(name,'pp_GetDDL') FROM master.sys.objects WHERE object_id = @@PROCID
  84.   IF @ISSYSTEMOBJECT IS NULL
  85.     SET @ISSYSTEMOBJECT = 0  
  86.   IF @PROCNAME IS NULL
  87.     SET @PROCNAME = 'sp_GetDDL'
  88.   --SET @TBL =  '[DBO].[WHATEVER1]'
  89.   --does the tablename contain a schema?
  90.   SET @vbCrLf = CHAR(13) + CHAR(10)
  91.   SELECT @SCHEMANAME = ISNULL(PARSENAME(@TBL,2),'dbo') ,
  92.          @TBLNAME    = PARSENAME(@TBL,1)
  93.   SELECT
  94.     @TABLE_ID   = [object_id]
  95.   FROM sys.objects OBJS
  96.   WHERE [TYPE]          IN ('S','U')
  97.     AND [name]          <>  'dtproperties'
  98.     AND [name]           =  @TBLNAME
  99.     AND [schema_id] =  schema_id(@SCHEMANAME) ;
  100.  
  101. --##############################################################################
  102. -- Check If TEMP TableName is Valid
  103. --##############################################################################
  104.   IF LEFT(@TBLNAME,1) = '#'
  105.     BEGIN
  106.       PRINT '--TEMP TABLE  [' + @TBLNAME + ']  FOUND'
  107.       IF OBJECT_ID('tempdb..' + @TBLNAME) IS NOT NULL
  108.         BEGIN
  109.           PRINT '--GOIN TO TEMP PROCESSING'
  110.           GOTO TEMPPROCESS
  111.         END
  112.     END
  113.   ELSE
  114.     BEGIN
  115.       PRINT '--Non-Temp Table, [' + @TBLNAME + '] continue Processing'
  116.     END
  117. --##############################################################################
  118. -- Check If TableName is Valid
  119. --##############################################################################
  120.   IF ISNULL(@TABLE_ID,0) = 0
  121.     BEGIN
  122.       --V309 code: see if it is an object and not a table.
  123.       SELECT
  124.         @TABLE_ID   = [object_id]
  125.       FROM sys.objects OBJS
  126.       --WHERE [type_desc]     IN('SQL_STORED_PROCEDURE','VIEW','SQL_TRIGGER','AGGREGATE_FUNCTION','SQL_INLINE_TABLE_VALUED_FUNCTION','SQL_TABLE_VALUED_FUNCTION','SQL_SCALAR_FUNCTION')
  127.       WHERE [TYPE]          IN ('P','V','TR','AF','IF','FN','TF')
  128.         AND [name]          <>  'dtproperties'
  129.         AND [name]           =  @TBLNAME
  130.         AND [schema_id] =  schema_id(@SCHEMANAME) ;
  131.       IF ISNULL(@TABLE_ID,0) <> 0  
  132.         BEGIN
  133.           SELECT
  134.             @FINALSQL = def.definition
  135.           FROM sys.objects OBJS
  136.             INNER JOIN sys.sql_modules def
  137.               ON OBJS.object_id = def.object_id
  138.           WHERE OBJS.[TYPE]          IN ('P','V','TR','AF','IF','FN','TF')
  139.             AND OBJS.[name]          <>  'dtproperties'
  140.             AND OBJS.[name]           =  @TBLNAME
  141.             AND OBJS.[schema_id] =  schema_id(@SCHEMANAME) ;
  142.           SET @INPUT = @FINALSQL  
  143.          SELECT @INPUT;
  144.          RETURN 0
  145.         END
  146.       ELSE
  147.         BEGIN
  148.         SET @FINALSQL = 'Table object [' + @SCHEMANAME + '].[' + UPPER(@TBLNAME) + '] does not exist in Database [' + db_name()   + '] '
  149.                       + CASE
  150.                           WHEN @ISSYSTEMOBJECT = 0 THEN @vbCrLf + ' (also note that ' + @PROCNAME + ' is not marked as a system proc and cross db access to sys.tables will fail.)'
  151.                           ELSE ''
  152.                         END
  153.       IF LEFT(@TBLNAME,1) = '#'
  154.         SET @FINALSQL = @FINALSQL + ' OR in The tempdb database.'
  155.       SELECT @FINALSQL AS Item;
  156.       RETURN 0
  157.         END  
  158.      
  159.     END
  160. --##############################################################################
  161. -- Valid Table, Continue Processing
  162. --##############################################################################
  163.   SELECT @FINALSQL = 'CREATE TABLE [' + @SCHEMANAME + '].[' + UPPER(@TBLNAME) + '] ( '
  164.   --removed invalid code here which potentially selected wrong table--thanks David Grifiths @SSC!
  165.   SELECT
  166.     @STRINGLEN = MAX(LEN(COLS.[name])) + 1
  167.   FROM sys.objects OBJS
  168.     INNER JOIN sys.COLUMNS COLS
  169.       ON  OBJS.[object_id] = COLS.[object_id]
  170.       AND OBJS.[object_id] = @TABLE_ID;
  171. --##############################################################################
  172. --Get the columns, their definitions and defaults.
  173. --##############################################################################
  174.   SELECT
  175.     @FINALSQL = @FINALSQL
  176.     + CASE
  177.         WHEN COLS.[is_computed] = 1
  178.         THEN @vbCrLf
  179.              + '['
  180.              + UPPER(COLS.[name])
  181.              + '] '
  182.              + SPACE(@STRINGLEN - LEN(COLS.[name]))
  183.              + 'AS ' + ISNULL(CALC.definition,'')
  184.              + CASE
  185.                  WHEN CALC.is_persisted = 1
  186.                  THEN ' PERSISTED'
  187.                  ELSE ''
  188.                END
  189.         ELSE @vbCrLf
  190.              + '['
  191.              + UPPER(COLS.[name])
  192.              + '] '
  193.              + SPACE(@STRINGLEN - LEN(COLS.[name]))
  194.              + UPPER(TYPE_NAME(COLS.[user_type_id]))
  195.              + CASE
  196. --IE NUMERIC(10,2)
  197.                WHEN TYPE_NAME(COLS.[user_type_id]) IN ('decimal','numeric')
  198.                THEN '('
  199.                     + CONVERT(VARCHAR,COLS.[PRECISION])
  200.                     + ','
  201.                     + CONVERT(VARCHAR,COLS.[scale])
  202.                     + ') '
  203.                     + SPACE(6 - LEN(CONVERT(VARCHAR,COLS.[PRECISION])
  204.                     + ','
  205.                     + CONVERT(VARCHAR,COLS.[scale])))
  206.                     + SPACE(7)
  207.                     + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  208.                     + CASE
  209.                         WHEN COLUMNPROPERTY ( @TABLE_ID , COLS.[name] , 'IsIdentity' ) = 0
  210.                         THEN ''
  211.                         ELSE ' IDENTITY('
  212.                                + CONVERT(VARCHAR,ISNULL(IDENT_SEED(@TBLNAME),1) )
  213.                                + ','
  214.                                + CONVERT(VARCHAR,ISNULL(IDENT_INCR(@TBLNAME),1) )
  215.                                + ')'
  216.                         END
  217.  
  218.                     + CASE
  219.                         WHEN COLS.[is_nullable] = 0
  220.                         THEN ' NOT NULL'
  221.                         ELSE '     NULL'
  222.                       END
  223. --IE FLOAT(53)
  224.                WHEN  TYPE_NAME(COLS.[user_type_id]) IN ('float','real')
  225.                THEN
  226.                --addition: if 53, no need to specifically say (53), otherwise display it
  227.                     CASE
  228.                       WHEN COLS.[PRECISION] = 53
  229.                       THEN SPACE(11 - LEN(CONVERT(VARCHAR,COLS.[PRECISION])))
  230.                            + SPACE(7)
  231.                            + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  232.                            + CASE
  233.                                WHEN COLS.[is_nullable] = 0
  234.                                THEN ' NOT NULL'
  235.                                ELSE '     NULL'
  236.                              END
  237.                       ELSE '('
  238.                            + CONVERT(VARCHAR,COLS.[PRECISION])
  239.                            + ') '
  240.                            + SPACE(6 - LEN(CONVERT(VARCHAR,COLS.[PRECISION])))
  241.                            + SPACE(7) + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  242.                            + CASE
  243.                                WHEN COLS.[is_nullable] = 0
  244.                                THEN ' NOT NULL'
  245.                                ELSE '     NULL'
  246.                              END
  247.                       END
  248. --ie VARCHAR(40)
  249. --##############################################################################
  250. -- COLLATE STATEMENTS
  251. -- personally i do not like collation statements,
  252. -- but included here to make it easy on those who do
  253. --##############################################################################
  254.                WHEN  TYPE_NAME(COLS.[user_type_id]) IN ('char','varchar')
  255.                THEN CASE
  256.                       WHEN  COLS.[max_length] = -1
  257.                       THEN  '(max)'
  258.                             + SPACE(6 - LEN(CONVERT(VARCHAR,COLS.[max_length])))
  259.                             + SPACE(7) + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  260.                             ----collate to comment out when not desired
  261.                             --+ CASE
  262.                             --    WHEN COLS.collation_name IS NULL
  263.                             --    THEN ''
  264.                             --    ELSE ' COLLATE ' + COLS.collation_name
  265.                             --  END
  266.                             + CASE
  267.                                 WHEN COLS.[is_nullable] = 0
  268.                                 THEN ' NOT NULL'
  269.                                 ELSE '     NULL'
  270.                               END
  271.                       ELSE '('
  272.                            + CONVERT(VARCHAR,COLS.[max_length])
  273.                            + ') '
  274.                            + SPACE(6 - LEN(CONVERT(VARCHAR,COLS.[max_length])))
  275.                            + SPACE(7) + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  276.                            ----collate to comment out when not desired
  277.                            --+ CASE
  278.                            --     WHEN COLS.collation_name IS NULL
  279.                            --     THEN ''
  280.                            --     ELSE ' COLLATE ' + COLS.collation_name
  281.                            --   END
  282.                            + CASE
  283.                                WHEN COLS.[is_nullable] = 0
  284.                                THEN ' NOT NULL'
  285.                                ELSE '     NULL'
  286.                              END
  287.                     END
  288. --ie NVARCHAR(40)
  289.                WHEN TYPE_NAME(COLS.[user_type_id]) IN ('nchar','nvarchar')
  290.                THEN CASE
  291.                       WHEN  COLS.[max_length] = -1
  292.                       THEN '(max)'
  293.                            + SPACE(6 - LEN(CONVERT(VARCHAR,(COLS.[max_length] / 2))))
  294.                            + SPACE(7)
  295.                            + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  296.                            ----collate to comment out when not desired
  297.                            --+ CASE
  298.                            --     WHEN COLS.collation_name IS NULL
  299.                            --     THEN ''
  300.                            --     ELSE ' COLLATE ' + COLS.collation_name
  301.                            --   END
  302.                            + CASE
  303.                                WHEN COLS.[is_nullable] = 0
  304.                                THEN  ' NOT NULL'
  305.                                ELSE '     NULL'
  306.                              END
  307.                       ELSE '('
  308.                            + CONVERT(VARCHAR,(COLS.[max_length] / 2))
  309.                            + ') '
  310.                            + SPACE(6 - LEN(CONVERT(VARCHAR,(COLS.[max_length] / 2))))
  311.                            + SPACE(7)
  312.                            + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  313.                            ----collate to comment out when not desired
  314.                            --+ CASE
  315.                            --     WHEN COLS.collation_name IS NULL
  316.                            --     THEN ''
  317.                            --     ELSE ' COLLATE ' + COLS.collation_name
  318.                            --   END
  319.                            + CASE
  320.                                WHEN COLS.[is_nullable] = 0
  321.                                THEN ' NOT NULL'
  322.                                ELSE '     NULL'
  323.                              END
  324.                     END
  325. --ie datetime
  326.                WHEN TYPE_NAME(COLS.[user_type_id]) IN ('datetime','money','text','image')
  327.                THEN SPACE(18 - LEN(TYPE_NAME(COLS.[user_type_id])))
  328.                     + '              '
  329.                     + CASE
  330.                         WHEN COLS.[is_nullable] = 0
  331.                         THEN ' NOT NULL'
  332.                         ELSE '     NULL'
  333.                       END
  334. --IE VARBINARY(500)
  335.               WHEN TYPE_NAME(COLS.[user_type_id]) = 'varbinary'
  336.               THEN
  337.                 CASE
  338.                   WHEN COLS.[max_length] = -1
  339.                   THEN '(max)'
  340.                        + SPACE(6 - LEN(CONVERT(VARCHAR,(COLS.[max_length]))))
  341.                        + SPACE(7)
  342.                        + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  343.                        + CASE WHEN COLS.[is_nullable] = 0
  344.                            THEN ' NOT NULL'
  345.                            ELSE ' NULL'
  346.                          END
  347.                   ELSE '('
  348.                        + CONVERT(VARCHAR,(COLS.[max_length]))
  349.                        + ') '
  350.                        + SPACE(6 - LEN(CONVERT(VARCHAR,(COLS.[max_length]))))
  351.                        + SPACE(7)
  352.                        + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  353.                        + CASE
  354.                            WHEN COLS.[is_nullable] = 0
  355.                            THEN ' NOT NULL'
  356.                            ELSE ' NULL'
  357.                          END
  358.                 END
  359. --IE INT
  360.                ELSE SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  361.                             + CASE
  362.                                 WHEN COLUMNPROPERTY ( @TABLE_ID , COLS.[name] , 'IsIdentity' ) = 0
  363.                                 THEN '              '
  364.                                 ELSE ' IDENTITY('
  365.                                      + CONVERT(VARCHAR,ISNULL(IDENT_SEED(@TBLNAME),1) )
  366.                                      + ','
  367.                                      + CONVERT(VARCHAR,ISNULL(IDENT_INCR(@TBLNAME),1) )
  368.                                      + ')'
  369.                               END
  370.                             + SPACE(2)
  371.                             + CASE
  372.                                 WHEN COLS.[is_nullable] = 0
  373.                                 THEN ' NOT NULL'
  374.                                 ELSE '     NULL'
  375.                               END
  376.                END
  377.              + CASE
  378.                  WHEN COLS.[default_object_id] = 0
  379.                  THEN ''
  380.                  ELSE ' DEFAULT '  + ISNULL(def.[definition] ,'')
  381.                  --optional section in case NAMED default cosntraints are needed:
  382.                  --ELSE @vbCrLf + 'CONSTRAINT [' + def.name + '] DEFAULT ' + ISNULL(def.[definition] ,'')
  383.                         --i thought it needed to be handled differently! NOT!
  384.                END  --CASE cdefault
  385.       END --iscomputed
  386.     + ','
  387.     FROM sys.COLUMNS COLS
  388.       LEFT OUTER JOIN  sys.default_constraints  DEF
  389.         ON COLS.[default_object_id] = DEF.[object_id]
  390.       LEFT OUTER JOIN sys.computed_columns CALC
  391.          ON  COLS.[object_id] = CALC.[object_id]
  392.          AND COLS.[column_id] = CALC.[column_id]
  393.     WHERE COLS.[object_id]=@TABLE_ID
  394.     ORDER BY COLS.[column_id]
  395. --##############################################################################
  396. --used for formatting the rest of the constraints:
  397. --##############################################################################
  398.   SELECT
  399.     @STRINGLEN = MAX(LEN([name])) + 1
  400.   FROM sys.objects OBJS
  401. --##############################################################################
  402. --PK/Unique Constraints and Indexes, using the 2005/08 INCLUDE syntax
  403. --##############################################################################
  404.   DECLARE @Results  TABLE (
  405.                     [schema_id]             INT,
  406.                     [schema_name]           VARCHAR(255),
  407.                     [object_id]             INT,
  408.                     [object_name]           VARCHAR(255),
  409.                     [index_id]              INT,
  410.                     [index_name]            VARCHAR(255),
  411.                     [ROWS]                  INT,
  412.                     [SizeMB]                DECIMAL(19,3),
  413.                     [IndexDepth]            INT,
  414.                     [TYPE]                  INT,
  415.                     [type_desc]             VARCHAR(30),
  416.                     [fill_factor]           INT,
  417.                     [PAD_INDEX]             INT,
  418.                     [STATISTICS_NORECOMPUTE]    INT,                   
  419.                     [ignore_dup_key]        INT,
  420.                     [ALLOW_ROW_LOCKS]       INT,
  421.                     [ALLOW_PAGE_LOCKS]      INT,
  422.                     [is_unique]             INT,
  423.                     [is_primary_key]        INT,
  424.                     [is_unique_constraint]  INT,
  425.                     [index_columns_key]     VARCHAR(MAX),
  426.                     [index_columns_include] VARCHAR(MAX))
  427.   INSERT INTO @Results
  428.     SELECT
  429.       SCH.schema_id, SCH.[name] AS schema_name,
  430.       OBJS.[object_id], OBJS.[name] AS object_name,
  431.       IDX.index_id, ISNULL(IDX.[name], '---') AS index_name,
  432.       partitions.ROWS, partitions.SizeMB, IndexProperty(OBJS.[object_id], IDX.[name], 'IndexDepth') AS IndexDepth,
  433.       IDX.TYPE, IDX.type_desc, IDX.fill_factor, IDX.[is_padded] AS [PAD_INDEX], STATS.[no_recompute] AS [STATISTICS_NORECOMPUTE], IDX.[IGNORE_DUP_KEY], IDX.[ALLOW_ROW_LOCKS], IDX.[ALLOW_PAGE_LOCKS],
  434.       IDX.is_unique, IDX.is_primary_key, IDX.is_unique_constraint,
  435.       ISNULL(Index_Columns.index_columns_key, '---') AS index_columns_key,
  436.       ISNULL(Index_Columns.index_columns_include, '---') AS index_columns_include
  437.     FROM sys.objects OBJS
  438.       INNER JOIN sys.schemas SCH ON OBJS.schema_id=SCH.schema_id
  439.       INNER JOIN sys.indexes IDX ON OBJS.[object_id]=IDX.[object_id]
  440.       LEFT JOIN sys.stats STATS ON IDX.[object_id]=STATS.[object_id] AND IDX.name = STATS.name
  441.       INNER JOIN (
  442.                   SELECT
  443.                     [object_id], index_id, SUM(ROW_COUNT) AS ROWS,
  444.                     CONVERT(NUMERIC(19,3), CONVERT(NUMERIC(19,3), SUM(in_row_reserved_page_count+lob_reserved_page_count+row_overflow_reserved_page_count))/CONVERT(NUMERIC(19,3), 128)) AS SizeMB
  445.                   FROM sys.dm_db_partition_stats pSTATS
  446.                   GROUP BY [object_id], index_id
  447.                  ) AS partitions
  448.         ON  IDX.[object_id]=partitions.[object_id]
  449.         AND IDX.index_id=partitions.index_id
  450.     CROSS APPLY (
  451.                  SELECT
  452.                    LEFT(index_columns_key, LEN(index_columns_key)-1) AS index_columns_key,
  453.                   LEFT(index_columns_include, LEN(index_columns_include)-1) AS index_columns_include
  454.                  FROM
  455.                       (
  456.                        SELECT
  457.                               (
  458.                               SELECT COLS.[name] + CASE WHEN IXCOLS.is_descending_key = 0 THEN ' asc' ELSE ' desc' END + ',' + ' '
  459.                                FROM sys.index_columns IXCOLS
  460.                                  INNER JOIN sys.COLUMNS COLS
  461.                                    ON  IXCOLS.column_id   = COLS.column_id
  462.                                    AND IXCOLS.[object_id] = COLS.[object_id]
  463.                                WHERE IXCOLS.is_included_column = 0
  464.                                  AND IDX.[object_id] = IXCOLS.[object_id]
  465.                                  AND IDX.index_id = IXCOLS.index_id
  466.                                ORDER BY key_ordinal
  467.                                FOR XML PATH('')
  468.                               ) AS index_columns_key,
  469.                              (
  470.                              SELECT COLS.[name] + CASE WHEN IXCOLS.is_descending_key = 0 THEN ' asc' ELSE ' desc' END + ',' + ' '
  471.                               FROM sys.index_columns IXCOLS
  472.                                 INNER JOIN sys.COLUMNS COLS
  473.                                   ON  IXCOLS.column_id   = COLS.column_id
  474.                                   AND IXCOLS.[object_id] = COLS.[object_id]
  475.                               WHERE IXCOLS.is_included_column = 1
  476.                                 AND IDX.[object_id] = IXCOLS.[object_id]
  477.                                 AND IDX.index_id = IXCOLS.index_id
  478.                               ORDER BY index_column_id
  479.                               FOR XML PATH('')
  480.                              ) AS index_columns_include
  481.                       ) AS Index_Columns
  482.                 ) AS Index_Columns
  483.     WHERE SCH.[name]  LIKE CASE
  484.                                      WHEN @SCHEMANAME = ''
  485.                                      THEN SCH.[name]
  486.                                      ELSE @SCHEMANAME
  487.                                    END
  488.     AND OBJS.[name] LIKE CASE
  489.                                   WHEN @TBLNAME = ''  
  490.                                   THEN OBJS.[name]
  491.                                   ELSE @TBLNAME
  492.                                 END
  493.     ORDER BY
  494.       SCH.[name],
  495.       OBJS.[name],
  496.       IDX.[name]
  497. --@Results table has both PK,s Uniques and indexes in thme...pull them out for adding to funal results:
  498.   SET @CONSTRAINTSQLS = ''
  499.   SET @INDEXSQLS      = ''
  500.  
  501.   SELECT * FROM @Results
  502. --##############################################################################
  503. --constriants
  504. --##############################################################################
  505.   SELECT @CONSTRAINTSQLS = @CONSTRAINTSQLS
  506.          + CASE
  507.              WHEN is_primary_key = 1 OR is_unique = 1
  508.              THEN @vbCrLf
  509.                   + 'CONSTRAINT   [' + index_name + '] '
  510.                   + SPACE(@STRINGLEN - LEN(index_name))
  511.                   + CASE  
  512.                       WHEN is_primary_key = 1
  513.                       THEN ' PRIMARY KEY '
  514.                       ELSE CASE  
  515.                              WHEN is_unique = 1    
  516.                              THEN ' UNIQUE      '      
  517.                              ELSE ''
  518.                            END
  519.                     END
  520.                   + type_desc
  521.                   + CASE
  522.                       WHEN type_desc='NONCLUSTERED'
  523.                       THEN ''
  524.                       ELSE '   '
  525.                     END
  526.                   + ' (' + index_columns_key + ')'
  527.                   + CASE
  528.                       WHEN index_columns_include <> '---'
  529.                       THEN ' INCLUDE (' + index_columns_include + ')'
  530.                       ELSE ''
  531.                     END
  532.                   + ISNULL(CASE
  533.                       WHEN fill_factor <> 0 OR [ignore_dup_key] <> 0 OR [PAD_INDEX] <> 0 OR [STATISTICS_NORECOMPUTE] <> 0 OR [ALLOW_ROW_LOCKS] <> 1 OR [ALLOW_PAGE_LOCKS] <> 1
  534.                       THEN ' WITH ('
  535.                             +REPLACE(
  536.                                 CASE WHEN fill_factor <> 0 THEN ' FILLFACTOR = ' + ISNULL(CONVERT(VARCHAR(30),fill_factor),'0') + ' ,' ELSE '' END
  537.                                 +CASE WHEN [ignore_dup_key] <> 0 THEN ' IGNORE_DUP_KEY = ' + CASE WHEN [ignore_dup_key] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  538.                                 +CASE WHEN [PAD_INDEX] <> 0 THEN ' PAD_INDEX = ' + CASE WHEN [PAD_INDEX] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  539.                                 +CASE WHEN [STATISTICS_NORECOMPUTE] <> 0 THEN ' STATISTICS_NORECOMPUTE = ' + CASE WHEN [STATISTICS_NORECOMPUTE] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  540.                                 +CASE WHEN [ALLOW_ROW_LOCKS] <> 1 THEN ' ALLOW_ROW_LOCKS = ' + CASE WHEN [ALLOW_ROW_LOCKS] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  541.                                 +CASE WHEN [ALLOW_PAGE_LOCKS] <> 1 THEN ' ALLOW_PAGE_LOCKS = ' + CASE WHEN [ALLOW_PAGE_LOCKS] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  542.                                 -- PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON
  543.                                 +')'
  544.                                 ,',)',')'
  545.                             )
  546.                       ELSE ''
  547.                     END,'')
  548.              ELSE ''
  549.            END + ','
  550.   FROM @RESULTS
  551.   WHERE [type_desc] != 'HEAP'
  552.     AND is_primary_key = 1
  553.     OR  is_unique = 1
  554.   ORDER BY
  555.     is_primary_key DESC,
  556.     is_unique DESC
  557. --##############################################################################
  558. --indexes
  559. --##############################################################################
  560.   SELECT @INDEXSQLS = @INDEXSQLS
  561.          + CASE
  562.              WHEN is_primary_key = 0 OR is_unique = 0
  563.              THEN @vbCrLf
  564.                   + 'CREATE ' + type_desc + ' INDEX [' + index_name + '] '
  565.                   + SPACE(@STRINGLEN - LEN(index_name))
  566.                   + ' ON [' + [object_name] + ']'
  567.                   + ' (' + index_columns_key + ')'
  568.                   + CASE
  569.                      WHEN index_columns_include <> '---'
  570.                      THEN ' INCLUDE (' + index_columns_include + ')'
  571.                      ELSE ''
  572.                    END
  573.                   + CASE
  574.                       WHEN fill_factor <> 0 OR [ignore_dup_key] <> 0 OR [PAD_INDEX] <> 0 OR [STATISTICS_NORECOMPUTE] <> 0 OR [ALLOW_ROW_LOCKS] <> 1 OR [ALLOW_PAGE_LOCKS] <> 1
  575.                       THEN ' WITH ('
  576.                             +REPLACE(
  577.                                 CASE WHEN fill_factor <> 0 THEN ' FILLFACTOR = ' + CONVERT(VARCHAR(30),fill_factor) + ' ,' ELSE '' END
  578.                                 +CASE WHEN [ignore_dup_key] <> 0 THEN ' IGNORE_DUP_KEY = ' + CASE WHEN [ignore_dup_key] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  579.                                 +CASE WHEN [PAD_INDEX] <> 0 THEN ' PAD_INDEX = ' + CASE WHEN [PAD_INDEX] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  580.                                 +CASE WHEN [STATISTICS_NORECOMPUTE] <> 0 THEN ' STATISTICS_NORECOMPUTE = ' + CASE WHEN [STATISTICS_NORECOMPUTE] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  581.                                 +CASE WHEN [ALLOW_ROW_LOCKS] <> 1 THEN ' ALLOW_ROW_LOCKS = ' + CASE WHEN [ALLOW_ROW_LOCKS] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  582.                                 +CASE WHEN [ALLOW_PAGE_LOCKS] <> 1 THEN ' ALLOW_PAGE_LOCKS = ' + CASE WHEN [ALLOW_PAGE_LOCKS] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  583.                                 -- PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON
  584.                                 +')'
  585.                                 ,',)',')'
  586.                             )
  587.                       ELSE ''
  588.                     END
  589.            END
  590.   FROM @RESULTS
  591.   WHERE [type_desc] != 'HEAP'
  592.     AND is_primary_key = 0
  593.     AND is_unique = 0
  594.   ORDER BY
  595.     is_primary_key DESC,
  596.     is_unique DESC
  597.  
  598.   IF @INDEXSQLS <> ''
  599.     SET @INDEXSQLS = @vbCrLf + 'GO' + @vbCrLf + @INDEXSQLS
  600. --##############################################################################
  601. --CHECK Constraints
  602. --##############################################################################
  603.   SET @CHECKCONSTSQLS = ''
  604.   SELECT
  605.     @CHECKCONSTSQLS = @CHECKCONSTSQLS
  606.     + @vbCrLf
  607.     + ISNULL('CONSTRAINT   [' + OBJS.[name] + '] '
  608.     + SPACE(@STRINGLEN - LEN(OBJS.[name]))
  609.     + ' CHECK ' + ISNULL(CHECKS.definition,'')
  610.     + ',','')
  611.   FROM sys.objects OBJS
  612.     INNER JOIN sys.check_constraints CHECKS ON OBJS.[object_id] = CHECKS.[object_id]
  613.   WHERE OBJS.TYPE = 'C'
  614.     AND OBJS.parent_object_id = @TABLE_ID
  615. --##############################################################################
  616. --FOREIGN KEYS
  617. --##############################################################################
  618.   SET @FKSQLS = '' ;
  619.   SELECT
  620.     @FKSQLS=@FKSQLS
  621.     + @vbCrLf
  622.     + 'CONSTRAINT   [' + OBJECT_NAME(constid) +']'
  623.     + SPACE(@STRINGLEN - LEN(OBJECT_NAME(constid) ))
  624.     + '  FOREIGN KEY ('   + COL_NAME(fkeyid,fkey)
  625.     + ') REFERENCES '    + OBJECT_NAME(rkeyid)
  626.     +'(' + COL_NAME(rkeyid,rkey) + '),'
  627.   FROM sysforeignkeys FKEYS
  628.   WHERE fkeyid = @TABLE_ID
  629. --##############################################################################
  630. --RULES
  631. --##############################################################################
  632.   SET @RULESCONSTSQLS = ''
  633.   SELECT
  634.     @RULESCONSTSQLS = @RULESCONSTSQLS
  635.     + ISNULL(
  636.              @vbCrLf
  637.              + 'if not exists(SELECT [name] FROM sys.objects WHERE TYPE=''R'' AND schema_id = ' + CONVERT(VARCHAR(30),OBJS.schema_id) + ' AND [name] = ''[' + object_name(COLS.[rule_object_id]) + ']'')' + @vbCrLf
  638.              + MODS.definition  + @vbCrLf + 'GO' +  @vbCrLf
  639.              + 'EXEC sp_binderule  [' + OBJS.[name] + '], ''[' + OBJECT_NAME(COLS.[object_id]) + '].[' + COLS.[name] + ']''' + @vbCrLf + 'GO' ,'')
  640.   FROM sys.COLUMNS COLS
  641.     INNER JOIN sys.objects OBJS
  642.       ON OBJS.[object_id] = COLS.[object_id]
  643.     INNER JOIN sys.sql_modules MODS
  644.       ON COLS.[rule_object_id] = MODS.[object_id]
  645.   WHERE COLS.[rule_object_id] <> 0
  646.     AND COLS.[object_id] = @TABLE_ID
  647. --##############################################################################
  648. --TRIGGERS
  649. --##############################################################################
  650.   SET @TRIGGERSTATEMENT = ''
  651.   SELECT
  652.     @TRIGGERSTATEMENT = @TRIGGERSTATEMENT +  @vbCrLf + MODS.[definition] + @vbCrLf + 'GO'
  653.   FROM sys.sql_modules MODS
  654.   WHERE [object_id] IN(SELECT
  655.                          [object_id]
  656.                        FROM sys.objects OBJS
  657.                        WHERE TYPE = 'TR'
  658.                        AND [parent_object_id] = @TABLE_ID)
  659.   IF @TRIGGERSTATEMENT <> ''
  660.     SET @TRIGGERSTATEMENT = @vbCrLf + 'GO' + @vbCrLf + @TRIGGERSTATEMENT
  661. --##############################################################################
  662. --NEW SECTION QUERY ALL EXTENDED PROPERTIES
  663. --##############################################################################
  664.   SET @EXTENDEDPROPERTIES = ''
  665.   SELECT  @EXTENDEDPROPERTIES =
  666.           @EXTENDEDPROPERTIES + @vbCrLf +
  667.          'EXEC sys.sp_addextendedproperty
  668.          @name = N''' + [name] + ''', @value = N''' + REPLACE(CONVERT(VARCHAR(MAX),[VALUE]),'''','''''') + ''',
  669.          @level0type = N''SCHEMA'', @level0name = [' + @SCHEMANAME + '],
  670.          @level1type = N''TABLE'', @level1name = [' + @TBLNAME + '];'
  671.  --SELECT objtype, objname, name, value
  672.   FROM fn_listextendedproperty (NULL, 'schema', @SCHEMANAME, 'table', @TBLNAME, NULL, NULL);
  673.   IF @EXTENDEDPROPERTIES <> ''
  674.     SET @EXTENDEDPROPERTIES = @vbCrLf + 'GO' + @vbCrLf + @EXTENDEDPROPERTIES
  675. --##############################################################################
  676. --FINAL CLEANUP AND PRESENTATION
  677. --##############################################################################
  678. --at this point, there is a trailing comma, or it blank
  679.   SELECT
  680.     @FINALSQL = @FINALSQL
  681.                 + @CONSTRAINTSQLS
  682.                 + @CHECKCONSTSQLS
  683.                 + @FKSQLS
  684. --note that this trims the trailing comma from the end of the statements
  685.   SET @FINALSQL = SUBSTRING(@FINALSQL,1,LEN(@FINALSQL) -1) ;
  686.   SET @FINALSQL = @FINALSQL + ')' + @vbCrLf ;
  687.  
  688.   SET @INPUT = @vbCrLf
  689.        + @FINALSQL
  690.        + @INDEXSQLS
  691.        + @RULESCONSTSQLS
  692.        + @TRIGGERSTATEMENT
  693.        + @EXTENDEDPROPERTIES
  694.   SELECT  @INPUT    
  695.   RETURN;    
  696. --##############################################################################
  697. -- END Normal Table Processing
  698. --##############################################################################
  699.    
  700. --simple, primitive version to get the results of a TEMP table from the TEMP db.  
  701. --##############################################################################
  702. -- NEW Temp Table Logic
  703. --##############################################################################    
  704. TEMPPROCESS:
  705.   SELECT @TABLE_ID = OBJECT_ID('tempdb..' + @TBLNAME)
  706.  
  707. --##############################################################################
  708. -- Valid Table, Continue Processing
  709. --##############################################################################
  710.   SELECT @FINALSQL = 'CREATE TABLE [' + @SCHEMANAME + '].[' + UPPER(@TBLNAME) + '] ( '
  711.   --removed invalud cide here which potentially selected wrong table--thansk David Grifiths @SSC!
  712.   SELECT
  713.     @STRINGLEN = MAX(LEN(COLS.[name])) + 1
  714.   FROM tempdb.sys.objects OBJS
  715.     INNER JOIN tempdb.sys.COLUMNS COLS
  716.       ON  OBJS.[object_id] = COLS.[object_id]
  717.       AND OBJS.[object_id] = @TABLE_ID;
  718. --##############################################################################
  719. --Get the columns, their definitions and defaults.
  720. --##############################################################################
  721.   SELECT
  722.     @FINALSQL = @FINALSQL
  723.     + CASE
  724.         WHEN COLS.[is_computed] = 1
  725.         THEN @vbCrLf
  726.              + '['
  727.              + UPPER(COLS.[name])
  728.              + '] '
  729.              + SPACE(@STRINGLEN - LEN(COLS.[name]))
  730.              + 'AS ' + ISNULL(CALC.definition,'')
  731.               + CASE
  732.                  WHEN CALC.is_persisted = 1
  733.                  THEN ' PERSISTED'
  734.                  ELSE ''
  735.                END
  736.         ELSE @vbCrLf
  737.              + '['
  738.              + UPPER(COLS.[name])
  739.              + '] '
  740.              + SPACE(@STRINGLEN - LEN(COLS.[name]))
  741.              + UPPER(TYPE_NAME(COLS.[user_type_id]))
  742.              + CASE
  743. --IE NUMERIC(10,2)
  744.                WHEN TYPE_NAME(COLS.[user_type_id]) IN ('decimal','numeric')
  745.                THEN '('
  746.                     + CONVERT(VARCHAR,COLS.[PRECISION])
  747.                     + ','
  748.                     + CONVERT(VARCHAR,COLS.[scale])
  749.                     + ') '
  750.                     + SPACE(6 - LEN(CONVERT(VARCHAR,COLS.[PRECISION])
  751.                     + ','
  752.                     + CONVERT(VARCHAR,COLS.[scale])))
  753.                     + SPACE(7)
  754.                     + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  755.                     + CASE
  756.                         WHEN COLS.is_identity = 1
  757.                         THEN ' IDENTITY(1,1)'
  758.                         ELSE ''
  759.                         ----WHEN COLUMNPROPERTY ( @TABLE_ID , COLS.[name] , 'IsIdentity' ) = 1
  760.                         ----THEN ' IDENTITY('
  761.                         ----       + CONVERT(VARCHAR,ISNULL(IDENT_SEED('tempdb..' + @TBLNAME),1) )
  762.                         ----       + ','
  763.                         ----       + CONVERT(VARCHAR,ISNULL(IDENT_INCR('tempdb..' + @TBLNAME),1) )
  764.                         ----       + ')'
  765.                         ----ELSE ''
  766.                         END
  767.  
  768.                     + CASE
  769.                         WHEN COLS.[is_nullable] = 0
  770.                         THEN ' NOT NULL'
  771.                         ELSE '     NULL'
  772.                       END
  773. --IE FLOAT(53)
  774.                WHEN  TYPE_NAME(COLS.[user_type_id]) IN ('float','real')
  775.                THEN
  776.                --addition: if 53, no need to specifically say (53), otherwise display it
  777.                     CASE
  778.                       WHEN COLS.[PRECISION] = 53
  779.                       THEN SPACE(11 - LEN(CONVERT(VARCHAR,COLS.[PRECISION])))
  780.                            + SPACE(7)
  781.                            + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  782.                            + CASE
  783.                                WHEN COLS.[is_nullable] = 0
  784.                                THEN ' NOT NULL'
  785.                                ELSE '     NULL'
  786.                              END
  787.                       ELSE '('
  788.                            + CONVERT(VARCHAR,COLS.[PRECISION])
  789.                            + ') '
  790.                            + SPACE(6 - LEN(CONVERT(VARCHAR,COLS.[PRECISION])))
  791.                            + SPACE(7) + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  792.                            + CASE
  793.                                WHEN COLS.[is_nullable] = 0
  794.                                THEN ' NOT NULL'
  795.                                ELSE '     NULL'
  796.                              END
  797.                       END
  798. --ie VARCHAR(40)
  799. --##############################################################################
  800. -- COLLATE STATEMENTS in tempdb!
  801. -- personally i do not like collation statements,
  802. -- but included here to make it easy on those who do
  803. --##############################################################################
  804.  
  805.                WHEN  TYPE_NAME(COLS.[user_type_id]) IN ('char','varchar')
  806.                THEN CASE
  807.                       WHEN  COLS.[max_length] = -1
  808.                       THEN  '(max)'
  809.                             + SPACE(6 - LEN(CONVERT(VARCHAR,COLS.[max_length])))
  810.                             + SPACE(7) + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  811.                             ----collate to comment out when not desired
  812.                             --+ CASE
  813.                             --    WHEN COLS.collation_name IS NULL
  814.                             --    THEN ''
  815.                             --    ELSE ' COLLATE ' + COLS.collation_name
  816.                             --  END
  817.                             + CASE
  818.                                 WHEN COLS.[is_nullable] = 0
  819.                                 THEN ' NOT NULL'
  820.                                 ELSE '     NULL'
  821.                               END
  822.                       ELSE '('
  823.                            + CONVERT(VARCHAR,COLS.[max_length])
  824.                            + ') '
  825.                            + SPACE(6 - LEN(CONVERT(VARCHAR,COLS.[max_length])))
  826.                            + SPACE(7) + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  827.                            ----collate to comment out when not desired
  828.                            --+ CASE
  829.                            --     WHEN COLS.collation_name IS NULL
  830.                            --     THEN ''
  831.                            --     ELSE ' COLLATE ' + COLS.collation_name
  832.                            --   END
  833.                            + CASE
  834.                                WHEN COLS.[is_nullable] = 0
  835.                                THEN ' NOT NULL'
  836.                                ELSE '     NULL'
  837.                              END
  838.                     END
  839. --ie NVARCHAR(40)
  840.                WHEN TYPE_NAME(COLS.[user_type_id]) IN ('nchar','nvarchar')
  841.                THEN CASE
  842.                       WHEN  COLS.[max_length] = -1
  843.                       THEN '(max)'
  844.                            + SPACE(6 - LEN(CONVERT(VARCHAR,(COLS.[max_length] / 2))))
  845.                            + SPACE(7)
  846.                            + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  847.                            -- --collate to comment out when not desired
  848.                            --+ CASE
  849.                            --     WHEN COLS.collation_name IS NULL
  850.                            --     THEN ''
  851.                            --     ELSE ' COLLATE ' + COLS.collation_name
  852.                            --   END
  853.                            + CASE
  854.                                WHEN COLS.[is_nullable] = 0
  855.                                THEN  ' NOT NULL'
  856.                                ELSE '     NULL'
  857.                              END
  858.                       ELSE '('
  859.                            + CONVERT(VARCHAR,(COLS.[max_length] / 2))
  860.                            + ') '
  861.                            + SPACE(6 - LEN(CONVERT(VARCHAR,(COLS.[max_length] / 2))))
  862.                            + SPACE(7)
  863.                            + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  864.                            -- --collate to comment out when not desired
  865.                            --+ CASE
  866.                            --     WHEN COLS.collation_name IS NULL
  867.                            --     THEN ''
  868.                            --     ELSE ' COLLATE ' + COLS.collation_name
  869.                            --   END
  870.                            + CASE
  871.                                WHEN COLS.[is_nullable] = 0
  872.                                THEN ' NOT NULL'
  873.                                ELSE '     NULL'
  874.                              END
  875.                     END
  876. --ie datetime
  877.                WHEN TYPE_NAME(COLS.[user_type_id]) IN ('datetime','money','text','image')
  878.                THEN SPACE(18 - LEN(TYPE_NAME(COLS.[user_type_id])))
  879.                     + '              '
  880.                     + CASE
  881.                         WHEN COLS.[is_nullable] = 0
  882.                         THEN ' NOT NULL'
  883.                         ELSE '     NULL'
  884.                       END
  885. --IE VARBINARY(500)
  886.               WHEN TYPE_NAME(COLS.[user_type_id]) = 'varbinary'
  887.               THEN
  888.                 CASE
  889.                   WHEN COLS.[max_length] = -1
  890.                   THEN '(max)'
  891.                        + SPACE(6 - LEN(CONVERT(VARCHAR,(COLS.[max_length]))))
  892.                        + SPACE(7)
  893.                        + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  894.                        + CASE WHEN COLS.[is_nullable] = 0
  895.                            THEN ' NOT NULL'
  896.                            ELSE ' NULL'
  897.                          END
  898.                   ELSE '('
  899.                        + CONVERT(VARCHAR,(COLS.[max_length]))
  900.                        + ') '
  901.                        + SPACE(6 - LEN(CONVERT(VARCHAR,(COLS.[max_length]))))
  902.                        + SPACE(7)
  903.                        + SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  904.                        + CASE
  905.                            WHEN COLS.[is_nullable] = 0
  906.                            THEN ' NOT NULL'
  907.                            ELSE ' NULL'
  908.                          END
  909.                 END
  910. --IE INT
  911.                ELSE SPACE(16 - LEN(TYPE_NAME(COLS.[user_type_id])))
  912.                             + CASE
  913.                                 WHEN COLS.is_identity = 1
  914.                                 THEN ' IDENTITY(1,1)'
  915.                                 ELSE '              '
  916.                                 ----WHEN COLUMNPROPERTY ( @TABLE_ID , COLS.[name] , 'IsIdentity' ) = 1
  917.                                 ----THEN ' IDENTITY('
  918.                                 ----     + CONVERT(VARCHAR,ISNULL(IDENT_SEED('tempdb..' + @TBLNAME),1) )
  919.                                 ----     + ','
  920.                                 ----     + CONVERT(VARCHAR,ISNULL(IDENT_INCR('tempdb..' + @TBLNAME),1) )
  921.                                 ----     + ')'
  922.                                 ----ELSE '              '
  923.                               END
  924.                             + SPACE(2)
  925.                             + CASE
  926.                                 WHEN COLS.[is_nullable] = 0
  927.                                 THEN ' NOT NULL'
  928.                                 ELSE '     NULL'
  929.                               END
  930.                END
  931.              + CASE
  932.                  WHEN COLS.[default_object_id] = 0
  933.                  THEN ''
  934.                  ELSE ' DEFAULT '  + ISNULL(def.[definition] ,'')
  935.                  --optional section in case NAMED default cosntraints are needed:
  936.                  --ELSE @vbCrLf + 'CONSTRAINT [' + def.name + '] DEFAULT ' + ISNULL(def.[definition] ,'')
  937.                         --i thought it needed to be handled differently! NOT!
  938.                END  --CASE cdefault
  939.  
  940.  
  941.  
  942.       END --iscomputed
  943.     + ','
  944.     FROM tempdb.sys.COLUMNS COLS
  945.       LEFT OUTER JOIN  tempdb.sys.default_constraints  DEF
  946.         ON COLS.[default_object_id] = DEF.[object_id]
  947.       LEFT OUTER JOIN tempdb.sys.computed_columns CALC
  948.          ON  COLS.[object_id] = CALC.[object_id]
  949.          AND COLS.[column_id] = CALC.[column_id]
  950.     WHERE COLS.[object_id]=@TABLE_ID
  951.     ORDER BY COLS.[column_id]
  952. --##############################################################################
  953. --used for formatting the rest of the constraints:
  954. --##############################################################################
  955.   SELECT
  956.     @STRINGLEN = MAX(LEN([name])) + 1
  957.   FROM tempdb.sys.objects OBJS
  958. --##############################################################################
  959. --PK/Unique Constraints and Indexes, using the 2005/08 INCLUDE syntax
  960. --##############################################################################
  961.   DECLARE @Results2  TABLE (
  962.                     [schema_id]             INT,
  963.                     [schema_name]           VARCHAR(255),
  964.                     [object_id]             INT,
  965.                     [object_name]           VARCHAR(255),
  966.                     [index_id]              INT,
  967.                     [index_name]            VARCHAR(255),
  968.                     [ROWS]                  INT,
  969.                     [SizeMB]                DECIMAL(19,3),
  970.                     [IndexDepth]            INT,
  971.                     [TYPE]                  INT,
  972.                     [type_desc]             VARCHAR(30),
  973.                     [fill_factor]           INT,
  974.                     [PAD_INDEX]             INT,
  975.                     [STATISTICS_NORECOMPUTE]    INT,                   
  976.                     [ignore_dup_key]        INT,
  977.                     [ALLOW_ROW_LOCKS]       INT,
  978.                     [ALLOW_PAGE_LOCKS]      INT,
  979.                     [is_unique]             INT,
  980.                     [is_primary_key]        INT ,
  981.                     [is_unique_constraint]  INT,
  982.                     [index_columns_key]     VARCHAR(MAX),
  983.                     [index_columns_include] VARCHAR(MAX))
  984.   INSERT INTO @Results2
  985.     SELECT
  986.       SCH.schema_id, SCH.[name] AS schema_name,
  987.       OBJS.[object_id], OBJS.[name] AS object_name,
  988.       IDX.index_id, ISNULL(IDX.[name], '---') AS index_name,
  989.       partitions.ROWS, partitions.SizeMB, IndexProperty(OBJS.[object_id], IDX.[name], 'IndexDepth') AS IndexDepth,
  990.       IDX.TYPE, IDX.type_desc, IDX.fill_factor, IDX.[is_padded] AS [PAD_INDEX], STATS.[no_recompute] AS [STATISTICS_NORECOMPUTE], IDX.[IGNORE_DUP_KEY], IDX.[ALLOW_ROW_LOCKS], IDX.[ALLOW_PAGE_LOCKS],
  991.       IDX.is_unique, IDX.is_primary_key, IDX.is_unique_constraint,
  992.       ISNULL(Index_Columns.index_columns_key, '---') AS index_columns_key,
  993.       ISNULL(Index_Columns.index_columns_include, '---') AS index_columns_include
  994.     FROM tempdb.sys.objects OBJS
  995.       INNER JOIN tempdb.sys.schemas SCH ON OBJS.schema_id=SCH.schema_id
  996.       INNER JOIN tempdb.sys.indexes IDX ON OBJS.[object_id]=IDX.[object_id]
  997.       LEFT JOIN tempdb.sys.stats STATS ON IDX.[object_id]=STATS.[object_id] AND IDX.name = STATS.name
  998.       INNER JOIN (
  999.                   SELECT
  1000.                     [object_id], index_id, SUM(ROW_COUNT) AS ROWS,
  1001.                     CONVERT(NUMERIC(19,3), CONVERT(NUMERIC(19,3), SUM(in_row_reserved_page_count+lob_reserved_page_count+row_overflow_reserved_page_count))/CONVERT(NUMERIC(19,3), 128)) AS SizeMB
  1002.                   FROM tempdb.sys.dm_db_partition_stats pSTATS
  1003.                   GROUP BY [object_id], index_id
  1004.                  ) AS partitions
  1005.         ON  IDX.[object_id]=partitions.[object_id]
  1006.         AND IDX.index_id=partitions.index_id
  1007.     CROSS APPLY (
  1008.                  SELECT
  1009.                    LEFT(index_columns_key, LEN(index_columns_key)-1) AS index_columns_key,
  1010.                   LEFT(index_columns_include, LEN(index_columns_include)-1) AS index_columns_include
  1011.                  FROM
  1012.                       (
  1013.                        SELECT
  1014.                               (
  1015.                               SELECT COLS.[name] + CASE WHEN IXCOLS.is_descending_key = 0 THEN ' asc' ELSE ' desc' END + ',' + ' '
  1016.                                FROM tempdb.sys.index_columns IXCOLS
  1017.                                  INNER JOIN tempdb.sys.COLUMNS COLS
  1018.                                    ON  IXCOLS.column_id   = COLS.column_id
  1019.                                    AND IXCOLS.[object_id] = COLS.[object_id]
  1020.                                WHERE IXCOLS.is_included_column = 0
  1021.                                  AND IDX.[object_id] = IXCOLS.[object_id]
  1022.                                  AND IDX.index_id = IXCOLS.index_id
  1023.                                ORDER BY key_ordinal
  1024.                                FOR XML PATH('')
  1025.                               ) AS index_columns_key,
  1026.                              (
  1027.                              SELECT COLS.[name] + CASE WHEN IXCOLS.is_descending_key = 0 THEN ' asc' ELSE ' desc' END + ',' + ' '
  1028.                               FROM tempdb.sys.index_columns IXCOLS
  1029.                                 INNER JOIN tempdb.sys.COLUMNS COLS
  1030.                                   ON  IXCOLS.column_id   = COLS.column_id
  1031.                                   AND IXCOLS.[object_id] = COLS.[object_id]
  1032.                               WHERE IXCOLS.is_included_column = 1
  1033.                                 AND IDX.[object_id] = IXCOLS.[object_id]
  1034.                                 AND IDX.index_id = IXCOLS.index_id
  1035.                               ORDER BY index_column_id
  1036.                               FOR XML PATH('')
  1037.                              ) AS index_columns_include
  1038.                       ) AS Index_Columns
  1039.                 ) AS Index_Columns
  1040.     WHERE SCH.[name]  LIKE CASE
  1041.                                      WHEN @SCHEMANAME = ''
  1042.                                      THEN SCH.[name]
  1043.                                      ELSE @SCHEMANAME
  1044.                                    END
  1045.     AND OBJS.[name] LIKE CASE
  1046.                                   WHEN @TBLNAME = ''  
  1047.                                   THEN OBJS.[name]
  1048.                                   ELSE @TBLNAME
  1049.                                 END
  1050.     ORDER BY
  1051.       SCH.[name],
  1052.       OBJS.[name],
  1053.       IDX.[name]
  1054. --@Results2 table has both PK,s Uniques and indexes in thme...pull them out for adding to funal results:
  1055.   SET @CONSTRAINTSQLS = ''
  1056.   SET @INDEXSQLS      = ''
  1057.  
  1058.   SELECT * FROM @Results2
  1059. --##############################################################################
  1060. --constriants
  1061. --##############################################################################
  1062.   SELECT @CONSTRAINTSQLS = @CONSTRAINTSQLS
  1063.          + CASE
  1064.              WHEN is_primary_key = 1 OR is_unique = 1
  1065.              THEN @vbCrLf
  1066.                   + 'CONSTRAINT   [' + index_name + '] '
  1067.                   + SPACE(@STRINGLEN - LEN(index_name))
  1068.                   + CASE  
  1069.                       WHEN is_primary_key = 1
  1070.                       THEN ' PRIMARY KEY '
  1071.                       ELSE CASE  
  1072.                              WHEN is_unique = 1    
  1073.                              THEN ' UNIQUE      '      
  1074.                              ELSE ''
  1075.                            END
  1076.                     END
  1077.                   + type_desc
  1078.                   + CASE
  1079.                       WHEN type_desc='NONCLUSTERED'
  1080.                       THEN ''
  1081.                       ELSE '   '
  1082.                     END
  1083.                   + ' (' + index_columns_key + ')'
  1084.                   + CASE
  1085.                       WHEN index_columns_include <> '---'
  1086.                       THEN ' INCLUDE (' + index_columns_include + ')'
  1087.                       ELSE ''
  1088.                     END
  1089.                   + CASE
  1090.                       WHEN fill_factor <> 0 OR [ignore_dup_key] <> 0 OR [PAD_INDEX] <> 0 OR [STATISTICS_NORECOMPUTE] <> 0 OR [ALLOW_ROW_LOCKS] <> 1 OR [ALLOW_PAGE_LOCKS] <> 1
  1091.                       THEN ' WITH ('
  1092.                             +REPLACE(
  1093.                                 CASE WHEN fill_factor <> 0 THEN ' FILLFACTOR = ' + CONVERT(VARCHAR(30),fill_factor) + ',' ELSE '' END
  1094.                                 +CASE WHEN [ignore_dup_key] <> 0 THEN ' IGNORE_DUP_KEY = ' + CASE WHEN [ignore_dup_key] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1095.                                 +CASE WHEN [PAD_INDEX] <> 0 THEN ' PAD_INDEX = ' + CASE WHEN [PAD_INDEX] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1096.                                 +CASE WHEN [STATISTICS_NORECOMPUTE] <> 0 THEN ' STATISTICS_NORECOMPUTE = ' + CASE WHEN [STATISTICS_NORECOMPUTE] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1097.                                 +CASE WHEN [ALLOW_ROW_LOCKS] <> 1 THEN ' ALLOW_ROW_LOCKS = ' + CASE WHEN [ALLOW_ROW_LOCKS] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1098.                                 +CASE WHEN [ALLOW_PAGE_LOCKS] <> 1 THEN ' ALLOW_PAGE_LOCKS = ' + CASE WHEN [ALLOW_PAGE_LOCKS] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1099.                                 -- PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON
  1100.                                 +')'
  1101.                                 ,',)',')'
  1102.                             )
  1103.                       ELSE ''
  1104.                     END
  1105.              ELSE ''
  1106.            END + ','
  1107.   FROM @Results2
  1108.   WHERE [type_desc] != 'HEAP'
  1109.     AND is_primary_key = 1
  1110.     OR  is_unique = 1
  1111.   ORDER BY
  1112.     is_primary_key DESC,
  1113.     is_unique DESC
  1114. --##############################################################################
  1115. --indexes
  1116. --##############################################################################
  1117.   SELECT @INDEXSQLS = @INDEXSQLS
  1118.          + CASE
  1119.              WHEN is_primary_key = 0 OR is_unique = 0
  1120.              THEN @vbCrLf
  1121.                   + 'CREATE ' + type_desc + ' INDEX [' + index_name + '] '
  1122.                   + SPACE(@STRINGLEN - LEN(index_name))
  1123.                   + ' ON [' + [object_name] + ']'
  1124.                   + ' (' + index_columns_key + ')'
  1125.                   + CASE
  1126.                      WHEN index_columns_include <> '---'
  1127.                      THEN ' INCLUDE (' + index_columns_include + ')'
  1128.                      ELSE ''
  1129.                    END
  1130.                   + CASE
  1131.                       WHEN fill_factor <> 0 OR [ignore_dup_key] <> 0 OR [PAD_INDEX] <> 0 OR [STATISTICS_NORECOMPUTE] <> 0 OR [ALLOW_ROW_LOCKS] <> 1 OR [ALLOW_PAGE_LOCKS] <> 1
  1132.                       THEN ' WITH ('
  1133.                             +REPLACE(
  1134.                                 CASE WHEN fill_factor <> 0 THEN ' FILLFACTOR = ' + CONVERT(VARCHAR(30),fill_factor) + ',' ELSE '' END
  1135.                                 +CASE WHEN [ignore_dup_key] <> 0 THEN ' IGNORE_DUP_KEY = ' + CASE WHEN [ignore_dup_key] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1136.                                 +CASE WHEN [PAD_INDEX] <> 0 THEN ' PAD_INDEX = ' + CASE WHEN [PAD_INDEX] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1137.                                 +CASE WHEN [STATISTICS_NORECOMPUTE] <> 0 THEN ' STATISTICS_NORECOMPUTE = ' + CASE WHEN [STATISTICS_NORECOMPUTE] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1138.                                 +CASE WHEN [ALLOW_ROW_LOCKS] <> 1 THEN ' ALLOW_ROW_LOCKS = ' + CASE WHEN [ALLOW_ROW_LOCKS] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1139.                                 +CASE WHEN [ALLOW_PAGE_LOCKS] <> 1 THEN ' ALLOW_PAGE_LOCKS = ' + CASE WHEN [ALLOW_PAGE_LOCKS] <> 0 THEN 'ON' ELSE 'OFF' END + ' ,' ELSE '' END
  1140.                                 -- PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON
  1141.                                 +')'
  1142.                                 ,',)',')'
  1143.                             )
  1144.                       ELSE ''
  1145.                     END
  1146.            END
  1147.   FROM @Results2
  1148.   WHERE [type_desc] != 'HEAP'
  1149.     AND is_primary_key = 0
  1150.     AND is_unique = 0
  1151.   ORDER BY
  1152.     is_primary_key DESC,
  1153.     is_unique DESC
  1154.  
  1155.   IF @INDEXSQLS <> ''
  1156.     SET @INDEXSQLS = @vbCrLf + 'GO' + @vbCrLf + @INDEXSQLS
  1157. --##############################################################################
  1158. --CHECK Constraints
  1159. --##############################################################################
  1160.   SET @CHECKCONSTSQLS = ''
  1161.   SELECT
  1162.     @CHECKCONSTSQLS = @CHECKCONSTSQLS
  1163.     + @vbCrLf
  1164.     + ISNULL('CONSTRAINT   [' + OBJS.[name] + '] '
  1165.     + SPACE(@STRINGLEN - LEN(OBJS.[name]))
  1166.     + ' CHECK ' + ISNULL(CHECKS.definition,'')
  1167.     + ',','')
  1168.   FROM tempdb.sys.objects OBJS
  1169.     INNER JOIN tempdb.sys.check_constraints CHECKS ON OBJS.[object_id] = CHECKS.[object_id]
  1170.   WHERE OBJS.TYPE = 'C'
  1171.     AND OBJS.parent_object_id = @TABLE_ID
  1172. --##############################################################################
  1173. --FOREIGN KEYS
  1174. --##############################################################################
  1175.   SET @FKSQLS = '' ;
  1176.   SELECT
  1177.     @FKSQLS=@FKSQLS
  1178.     + @vbCrLf
  1179.     + 'CONSTRAINT   [' + OBJECT_NAME(constid) +']'
  1180.     + SPACE(@STRINGLEN - LEN(OBJECT_NAME(constid) ))
  1181.     + '  FOREIGN KEY ('   + COL_NAME(fkeyid,fkey)
  1182.     + ') REFERENCES '    + OBJECT_NAME(rkeyid)
  1183.     +'(' + COL_NAME(rkeyid,rkey) + '),'
  1184.   FROM sysforeignkeys FKEYS
  1185.   WHERE fkeyid = @TABLE_ID
  1186. --##############################################################################
  1187. --RULES
  1188. --##############################################################################
  1189.   SET @RULESCONSTSQLS = ''
  1190.   SELECT
  1191.     @RULESCONSTSQLS = @RULESCONSTSQLS
  1192.     + ISNULL(
  1193.              @vbCrLf
  1194.              + 'if not exists(SELECT [name] FROM tempdb.sys.objects WHERE TYPE=''R'' AND schema_id = ' + CONVERT(VARCHAR(30),OBJS.schema_id) + ' AND [name] = ''[' + object_name(COLS.[rule_object_id]) + ']'')' + @vbCrLf
  1195.              + MODS.definition  + @vbCrLf + 'GO' +  @vbCrLf
  1196.              + 'EXEC sp_binderule  [' + OBJS.[name] + '], ''[' + OBJECT_NAME(COLS.[object_id]) + '].[' + COLS.[name] + ']''' + @vbCrLf + 'GO' ,'')
  1197.   FROM tempdb.sys.COLUMNS COLS
  1198.     INNER JOIN tempdb.sys.objects OBJS
  1199.       ON OBJS.[object_id] = COLS.[object_id]
  1200.     INNER JOIN tempdb.sys.sql_modules MODS
  1201.       ON COLS.[rule_object_id] = MODS.[object_id]
  1202.   WHERE COLS.[rule_object_id] <> 0
  1203.     AND COLS.[object_id] = @TABLE_ID
  1204. --##############################################################################
  1205. --TRIGGERS
  1206. --##############################################################################
  1207.   SET @TRIGGERSTATEMENT = ''
  1208.   SELECT
  1209.     @TRIGGERSTATEMENT = @TRIGGERSTATEMENT +  @vbCrLf + MODS.[definition] + @vbCrLf + 'GO'
  1210.   FROM tempdb.sys.sql_modules MODS
  1211.   WHERE [object_id] IN(SELECT
  1212.                          [object_id]
  1213.                        FROM tempdb.sys.objects OBJS
  1214.                        WHERE TYPE = 'TR'
  1215.                        AND [parent_object_id] = @TABLE_ID)
  1216.   IF @TRIGGERSTATEMENT <> ''
  1217.     SET @TRIGGERSTATEMENT = @vbCrLf + 'GO' + @vbCrLf + @TRIGGERSTATEMENT
  1218. --##############################################################################
  1219. --NEW SECTION QUERY ALL EXTENDED PROPERTIES
  1220. --##############################################################################
  1221.   SET @EXTENDEDPROPERTIES = ''
  1222.   SELECT  @EXTENDEDPROPERTIES =
  1223.           @EXTENDEDPROPERTIES + @vbCrLf +
  1224.          'EXEC tempdb.sys.sp_addextendedproperty
  1225.          @name = N''' + [name] + ''', @value = N''' + REPLACE(CONVERT(VARCHAR(MAX),[VALUE]),'''','''''') + ''',
  1226.          @level0type = N''SCHEMA'', @level0name = [' + @SCHEMANAME + '],
  1227.          @level1type = N''TABLE'', @level1name = [' + @TBLNAME + '];'
  1228.  --SELECT objtype, objname, name, value
  1229.   FROM fn_listextendedproperty (NULL, 'schema', @SCHEMANAME, 'table', @TBLNAME, NULL, NULL);
  1230.   IF @EXTENDEDPROPERTIES <> ''
  1231.     SET @EXTENDEDPROPERTIES = @vbCrLf + 'GO' + @vbCrLf + @EXTENDEDPROPERTIES
  1232. --##############################################################################
  1233. --FINAL CLEANUP AND PRESENTATION
  1234. --##############################################################################
  1235. --at this point, there is a trailing comma, or it blank
  1236.   SELECT
  1237.     @FINALSQL = @FINALSQL
  1238.                 + @CONSTRAINTSQLS
  1239.                 + @CHECKCONSTSQLS
  1240.                 + @FKSQLS
  1241. --note that this trims the trailing comma from the end of the statements
  1242.   SET @FINALSQL = SUBSTRING(@FINALSQL,1,LEN(@FINALSQL) -1) ;
  1243.   SET @FINALSQL = @FINALSQL + ')' + @vbCrLf ;
  1244.  
  1245.   SET @INPUT = @vbCrLf
  1246.        + @FINALSQL
  1247.        + @INDEXSQLS
  1248.        + @RULESCONSTSQLS
  1249.        + @TRIGGERSTATEMENT
  1250.        + @EXTENDEDPROPERTIES
  1251.   SELECT @INPUT;  
  1252.   RETURN;    
  1253. END --PROC
  1254. GO
  1255.  
  1256. -- make sysobject in order to for sp to work across all db
  1257. EXECUTE sp_ms_marksystemobject 'sp_GetDDL'
  1258.  
  1259. -- test
  1260. EXECUTE [DATABASE].dbo.sp_GetDDL '[schema].[table]'
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement