home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Internet Business Development Kit / PRODUCT_CD.iso / sqlsvr / i386 / instcat.sql < prev    next >
Encoding:
Text File  |  1995-12-05  |  129.0 KB  |  4,569 lines

  1. /*
  2. **    INSTCAT.SQL
  3. **    Installs catalog stored procedures on the Microsoft SQL Server.
  4. **    Copyright 1992-1995, Microsoft Corp.    All rights reserved.
  5. */
  6.  
  7. /*
  8. NOTE:  you MUST change the last row inserted into spt_server_info
  9. to be version number of this file.    the convention is j.nn.bbb, where
  10. jj is the major version number ('6' now), nn is the minor version number
  11. ('50' now), and bbb is the build number.
  12. */
  13.  
  14. /****************************************************************************/
  15. /* This portion sets up the ability to perform all the functions in this    */
  16. /* script                                                                    */
  17. /****************************************************************************/
  18. use master
  19. go
  20. dump tran master with no_log
  21. go
  22.  
  23. set quoted_identifier on
  24. go
  25.  
  26. if exists (select * from sysobjects
  27.        where name = 'sp_configure' and sysstat & 0xf = 4)
  28. begin
  29.     execute sp_configure 'update',1
  30. end
  31. reconfigure with override
  32. go
  33.  
  34. /*
  35. ** If old versions of tables exist, drop them.
  36. */
  37. if (exists (select * from sysobjects
  38.         where name = 'MSdatatype_info' and sysstat & 0xf = 3))
  39.     drop table MSdatatype_info
  40. go
  41. if (exists (select * from sysobjects
  42.         where name = 'MSdatatype_info_ext' and sysstat & 0xf = 3))
  43.     drop table MSdatatype_info_ext
  44. go
  45. if (exists (select * from sysobjects
  46.         where name = 'MStable_types' and sysstat & 0xf = 3))
  47.     drop table MStable_types
  48. go
  49. if (exists (select * from sysobjects
  50.         where name = 'MSserver_info' and sysstat & 0xf = 3))
  51.     drop table MSserver_info
  52. go
  53. if (exists (select * from sysobjects
  54.         where name = 'spt_table_types' and sysstat & 0xf = 3))
  55.     drop table spt_table_types    /* no longer used */
  56. go
  57.  
  58. /*
  59. ** If tables or procs already exist, drop them.
  60. */
  61.  
  62. if (exists (select * from sysobjects
  63.         where name = 'spt_datatype_info' and sysstat & 0xf = 3))
  64.     drop table spt_datatype_info
  65. go
  66. if (exists (select * from sysobjects
  67.         where name = 'spt_datatype_info_ext' and sysstat & 0xf = 3))
  68.     drop table spt_datatype_info_ext
  69. go
  70. if (exists (select * from sysobjects
  71.         where name = 'spt_server_info' and sysstat & 0xf = 3))
  72.     drop table spt_server_info
  73. go
  74. if (exists (select * from sysobjects
  75.         where name = 'sp_tables' and sysstat & 0xf = 4))
  76.     drop proc sp_tables
  77. go
  78. if (exists (select * from sysobjects
  79.         where name = 'sp_statistics' and sysstat & 0xf = 4))
  80.     drop proc sp_statistics
  81. go
  82. if (exists (select * from sysobjects
  83.         where name = 'sp_columns' and sysstat & 0xf = 4))
  84.     drop proc sp_columns
  85. go
  86. if (exists (select * from sysobjects
  87.         where name = 'sp_fkeys' and sysstat & 0xf = 4))
  88.     drop proc sp_fkeys
  89. go
  90. if (exists (select * from sysobjects
  91.         where name = 'sp_pkeys' and sysstat & 0xf = 4))
  92.     drop proc sp_pkeys
  93. dump tran master with no_log
  94. go
  95.  
  96. go
  97. if (exists (select * from sysobjects
  98.         where name = 'sp_stored_procedures' and sysstat & 0xf = 4))
  99.     drop proc sp_stored_procedures
  100. go
  101. if (exists (select * from sysobjects
  102.         where name = 'sp_sproc_columns' and sysstat & 0xf = 4))
  103.     drop proc sp_sproc_columns
  104. go
  105. if (exists (select * from sysobjects
  106.         where name = 'sp_table_privileges' and sysstat & 0xf = 4))
  107.     drop proc sp_table_privileges
  108. go
  109. if (exists (select * from sysobjects
  110.         where name = 'sp_column_privileges' and sysstat & 0xf = 4))
  111.     drop proc sp_column_privileges
  112. go
  113. if (exists (select * from sysobjects
  114.         where name = 'sp_server_info' and sysstat & 0xf = 4))
  115.     drop proc sp_server_info
  116. go
  117. if (exists (select * from sysobjects
  118.         where name = 'sp_datatype_info' and sysstat & 0xf = 4))
  119.     drop proc sp_datatype_info
  120. go
  121. if (exists (select * from sysobjects
  122.         where name = 'sp_special_columns' and sysstat & 0xf = 4))
  123.     drop proc sp_special_columns
  124. go
  125. if (exists (select * from sysobjects
  126.         where name = 'sp_databases' and sysstat & 0xf = 4))
  127.     drop proc sp_databases
  128. go
  129. if (exists (select * from sysobjects
  130.         where name = 'sp_ddopen' and sysstat & 0xf = 4))
  131.     drop proc sp_ddopen
  132. go
  133.  
  134. dump tran master with no_log
  135. go
  136.  
  137. print 'creating table spt_datatype_info_ext'
  138. go
  139. create table spt_datatype_info_ext (
  140.                 user_type        smallint    not null,
  141.                 CREATE_PARAMS    varchar(32) null,
  142.                 AUTO_INCREMENT    smallint null)
  143. go
  144.  
  145. create unique clustered index datatypeinfoextclust on spt_datatype_info_ext(user_type,AUTO_INCREMENT)
  146. go
  147.  
  148. grant select on spt_datatype_info_ext to public
  149. go
  150.  
  151.  
  152. insert into spt_datatype_info_ext
  153.     /* CHAR      user_type, create_params, auto_increment */
  154.     values             (1,    'length' ,0)
  155.  
  156. insert into spt_datatype_info_ext
  157.     /* VARCHAR     user_type, create_params, auto_increment */
  158.     values             (2,    'max length' ,0)
  159.  
  160. insert into spt_datatype_info_ext
  161.     /* BINARY     user_type, create_params, auto_increment */
  162.     values             (3,    'length' ,0)
  163.  
  164. insert into spt_datatype_info_ext
  165.     /* VARBINARY user_type, create_params, auto_increment */
  166.     values             (4,    'max length' ,0)
  167.  
  168. if    (charindex('6.00', @@version) > 0 or
  169.      charindex('6.50', @@version) > 0)
  170. begin    /*    Add 6.0 data types */
  171.     insert into spt_datatype_info_ext
  172.         /* DECIMAL user_type, create_params, auto_increment */
  173.         values             (26,    'precision,scale' ,0)
  174.  
  175.     insert into spt_datatype_info_ext
  176.         /* NUMERIC user_type, create_params, auto_increment */
  177.         values             (25,    'precision,scale' ,0)
  178.  
  179.     insert into spt_datatype_info_ext
  180.         /* DECIMAL IDENTITY user_type, create_params, auto_increment */
  181.         values             (26,    'precision' ,1)
  182.  
  183.     insert into spt_datatype_info_ext
  184.         /* NUMERIC IDENTITY user_type, create_params, auto_increment */
  185.         values             (25,    'precision' ,1)
  186.  
  187. end
  188. else    /*    Pre 6.0 server, add SYSNAME create param */
  189.     begin
  190.         insert into spt_datatype_info_ext
  191.             /* SYSNAME     user_type, create_param, auto_increments */
  192.             values             (18,    'max length' ,0)
  193.  
  194.     end
  195. go
  196.  
  197. print 'creating table spt_datatype_info'
  198. go
  199. create table spt_datatype_info (
  200.     ss_dtype            tinyint     not null,
  201.     fixlen                int         null,        /* datatype len for variable, else null */
  202.     ODBCVer             tinyint     null,        /* version if needed, else null */
  203.     TYPE_NAME            varchar(30)    not null,
  204.     DATA_TYPE            smallint    not null,
  205.     data_precision        int         null,
  206.     numeric_scale        smallint    null,    /* min scale if 6.0 */
  207.     RADIX                smallint    null,
  208.     length                int         null,
  209.     LITERAL_PREFIX        varchar(32) null,
  210.     LITERAL_SUFFIX        varchar(32) null,
  211.     CREATE_PARAMS        varchar(32) null,
  212.     NULLABLE            smallint    not null,
  213.     CASE_SENSITIVE        smallint    not null,
  214.     SEARCHABLE            smallint    not null,
  215.     UNSIGNED_ATTRIBUTE    smallint    null,
  216.     MONEY                smallint    not null,
  217.     AUTO_INCREMENT        smallint    null,
  218.     LOCAL_TYPE_NAME     varchar(128)null,
  219.     charbin             tinyint     null, /* 0 for char/binary types, NULL for all others */
  220.     SQL_DATA_TYPE        smallint    not null,
  221.     SQL_DATETIME_SUB    smallint    null)
  222. go
  223.  
  224. create unique clustered index datatypeinfoclust on spt_datatype_info(ss_dtype,fixlen,ODBCVer,AUTO_INCREMENT)
  225. go
  226.  
  227. grant select on spt_datatype_info to public
  228. go
  229.  
  230. /* Get case sensitivity */
  231. if 'A' = 'A' /* create dummy begin block */
  232. begin
  233.     declare @case smallint
  234.  
  235.     begin tran
  236.     select @case = 0
  237.     select @case = 1 where 'a' <> 'A'
  238.  
  239.     /* Local Binary */
  240.     insert into spt_datatype_info values
  241.     (45,null,null,'binary',-2,null,null,null,null,'0x',null,'length',1,0,2,null,0,null,'binary',0,-2,null)
  242.  
  243.     /* Local Bit */
  244.     insert into spt_datatype_info values
  245.     (50,null,null,'bit',-7,1,0,2,null,null,null,null,0,0,2,null,0,null,'bit',null,-7,null)
  246.  
  247.     /* Local Char */
  248.     insert into spt_datatype_info values
  249.     (47,null,null,'char',1,null,null,null,null,'''','''','length',1,@case,3,null,0,null,'char',0,1,null)
  250.  
  251.     /* Local Datetime */
  252.     insert into spt_datatype_info values
  253.     (61,8,2,'datetime',11,23,3,10,16,'''','''',null,1,0,3,null,0,null,'datetime',null,9,3)
  254.     insert into spt_datatype_info values
  255.     (61,8,3,'datetime',93,23,3,10,16,'''','''',null,1,0,3,null,0,null,'datetime',null,9,3)
  256.  
  257.     /* Local Smalldatetime */
  258.     insert into spt_datatype_info values
  259.     (58,4,2,'smalldatetime',11,16,0,10,16,'''','''',null,1,0,3,null,0,null,'smalldatetime',null,9,3)
  260.     insert into spt_datatype_info values
  261.     (58,4,3,'smalldatetime',93,16,0,10,16,'''','''',null,1,0,3,null,0,null,'smalldatetime',null,9,3)
  262.  
  263.     /* Local Datetimn */
  264.     insert into spt_datatype_info values
  265.     (111,4,2,'smalldatetime',11,16,0,10,16,'''','''',null,1,0,3,null,0,null,'smalldatetime',null,9,3)
  266.     insert into spt_datatype_info values
  267.     (111,4,3,'smalldatetime',93,16,0,10,16,'''','''',null,1,0,3,null,0,null,'smalldatetime',null,9,3)
  268.     insert into spt_datatype_info values /* sql server type is 'datetimn' */
  269.     (111,8,2,'datetime',11,23,3,10,16,'''','''',null,1,0,3,null,0,null,'datetime',null,9,3)
  270.     insert into spt_datatype_info values
  271.     (111,8,3,'datetime',93,23,3,10,16,'''','''',null,1,0,3,null,0,null,'datetime',null,9,3)
  272.  
  273.     /* Local Float */
  274.     insert into spt_datatype_info values
  275.     (62,8,2,'float',6,15,null,10,8,null,null,null,1,0,2,0,0,0,'float',null,6,null)
  276.     insert into spt_datatype_info values
  277.     (62,8,3,'float',6,53,null, 2,8,null,null,null,1,0,2,0,0,0,'float',null,6,null)
  278.  
  279.     /* Local Floatn */
  280.     insert into spt_datatype_info values /* sql server type is 'floatn' */
  281.     (109,4,2,'real',7, 7,null,10,4,null,null,null,1,0,2,0,0,0,'real',null,7,null)
  282.     insert into spt_datatype_info values
  283.     (109,4,3,'real',7,24,null, 2,4,null,null,null,1,0,2,0,0,0,'real',null,7,null)
  284.     insert into spt_datatype_info values /* sql server type is 'floatn' */
  285.     (109,8,2,'float',6,15,null,10,8,null,null,null,1,0,2,0,0,0,'float',null,6,null)
  286.     insert into spt_datatype_info values
  287.     (109,8,3,'float',6,53,null, 2,8,null,null,null,1,0,2,0,0,0,'float',null,6,null)
  288.  
  289.     /* Local Real */
  290.     insert into spt_datatype_info values
  291.     (59,4,2,'real',7, 7,null,10,4,null,null,null,1,0,2,0,0,0,'real',null,7,null)
  292.     insert into spt_datatype_info values
  293.     (59,4,3,'real',7,24,null, 2,4,null,null,null,1,0,2,0,0,0,'real',null,7,null)
  294.  
  295.     /* Local Smallmoney */
  296.     insert into spt_datatype_info values
  297.     (122,4,null,'smallmoney',3,10,4,10,12,'$',null,null,1,0,2,0,1,0,'smallmoney',null,3,null)
  298.  
  299.     /* Local Money */
  300.     insert into spt_datatype_info values
  301.     (60,8,null,'money',3,19,4,10,21,'$',null,null,1,0,2,0,1,0,'money',null,3,null)
  302.  
  303.     /* Local Moneyn */
  304.     insert into spt_datatype_info values    /* sql server type is 'moneyn' */
  305.     (110,4,null,'smallmoney',3,10,4,10,12,'$',null,null,1,0,2,0,1,0,'smallmoney',null,3,null)
  306.     insert into spt_datatype_info values    /* sql server type is 'moneyn' */
  307.     (110,8,null,'money',3,19,4,10,21,'$',null,null,1,0,2,0,1,0,'money',null,3,null)
  308.  
  309.     /* Local Int */
  310.     insert into spt_datatype_info values
  311.     (56,4,null,'int',4,10,0,10,4,null,null,null,1,0,2,0,0,0,'int',null,4,null)
  312.  
  313.     /* Local Intn */
  314.     insert into spt_datatype_info values /* sql server type is 'intn' */
  315.     (38,4,null,'int',4,10,0,10,4,null,null,null,1,0,2,0,0,0,'int',null,4,null)
  316.     insert into spt_datatype_info values /* sql server type is 'intn' */
  317.     (38,2,null,'smallint',5,5,0,10,2,null,null,null,1,0,2,0,0,0,'smallint',null,5,null)
  318.     insert into spt_datatype_info values
  319.     (38,1,null,'tinyint',-6,3,0,10,1,null,null,null,1,0,2,1,0,0,'tinyint',null,-6,null)
  320.  
  321.     /* Local Smallint */
  322.     insert into spt_datatype_info values
  323.     (52,2,null,'smallint',5,5,0,10,2,null,null,null,1,0,2,0,0,0,'smallint',null,5,null)
  324.     insert into spt_datatype_info values
  325.     (52,2,1,'smallint',5,5,0,10,2,null,null,null,1,0,2,0,0,0,'smallint',null,5,null)
  326.  
  327.     /* Local Tinyint */
  328.     insert into spt_datatype_info values
  329.     (48,1,null,'tinyint',-6,3,0,10,1,null,null,null,1,0,2,1,0,0,'tinyint',null,-6,null)
  330.  
  331.     /* Local Text */
  332.     insert into spt_datatype_info values
  333.     (35,null,null,'text',-1,2147483647,null,null,2147483647,'''','''',null,1,@case,1,null,0,null,'text',0,-1,null)
  334.  
  335.     /* Local Varbinary */
  336.     insert into spt_datatype_info values
  337.     (37,null,null,'varbinary',-3,null,null,null,null,'0x',null,'max length',1,0,2,null,0,null,'varbinary',0,-3,null)
  338.  
  339.     /* Local Varchar */
  340.     insert into spt_datatype_info values
  341.     (39,null,null,'varchar',12,null,null,null,null,'''','''','max length',1,@case,3,null,0,null,'varchar',0,12,null)
  342.  
  343.     /* Local Image */
  344.     insert into spt_datatype_info values
  345.     (34,null,null,'image',-4,2147483647,null,null,2147483647,'0x',null,null,1,0,0,null,0,null,'image',0,-4,null)
  346.  
  347.     if    (charindex('6.00', @@version) > 0 or
  348.          charindex('6.50', @@version) > 0)
  349.     begin    /*    Add 6.0 data types */
  350.         /* Local Decimaln */
  351.         insert into spt_datatype_info values    /* sql server type is 'decimaln' */
  352.         (106,null,null,'decimal',3,38,0,10,null,null,null,'precision,scale',1,0,2,0,0,0,'decimal',null,3,null)
  353.  
  354.         /* Local Numericn */
  355.         insert into spt_datatype_info values    /* sql server type is 'numericn' */
  356.         (108,null,null,'numeric',2,38,0,10,null,null,null,'precision,scale',1,0,2,0,0,0,'numeric',null,2,null)
  357.  
  358.         /* Local Decimal */
  359.         insert into spt_datatype_info values    /* sql server type is 'decimaln' */
  360.         (55,null,null,'decimal',3,38,0,10,null,null,null,'precision,scale',1,0,2,0,0,0,'decimal',null,3,null)
  361.  
  362.         /* Local Numeric */
  363.         insert into spt_datatype_info values    /* sql server type is 'numericn' */
  364.         (63,null,null,'numeric',2    ,38,0,10,null,null,null,'precision,scale',1,0,2,0,0,0,'numeric',null,2,null)
  365.  
  366.         /* Identity attribute data types */
  367.  
  368.         /* Identity Int */
  369.         insert into spt_datatype_info values
  370.         (56,null,null,'int identity',4,10,0,10,null,null,null,null,0,0,2,0,0,1,'int identity',null,4,null)
  371.  
  372.         /* Identity Smallint */
  373.         insert into spt_datatype_info values
  374.         (52,null,null,'smallint identity',5,5,0,10,null,null,null,null,0,0,2,0,0,1,'smallint identity',null,5,null)
  375.  
  376.         /* Identity Tinyint */
  377.         insert into spt_datatype_info values
  378.         (48,null,null,'tinyint identity',-6,3,0,10,null,null,null,null,0,0,2,1,0,1,'tinyint identity',null,-6,null)
  379.  
  380.         /* Identity Numeric */
  381.         insert into spt_datatype_info values    /* sql server type is 'decmaln' */
  382.         (106,null,null,'decimal() identity',3,38,0,10,null,null,null,'precision,scale',0,0,2,0,0,1,'decimal() identity',null,3,null)
  383.         insert into spt_datatype_info values    /* sql server type is 'decmaln' */
  384.         (55,null,null,'decimal() identity',3,38,0,10,null,null,null,'precision,scale',0,0,2,0,0,1,'decimal() identity',null,3,null)
  385.  
  386.         /* Identity Numeric */
  387.         insert into spt_datatype_info values    /* sql server type is 'decmaln' */
  388.         (108,null,null,'numeric() identity',2,38,0,10,null,null,null,'precision,scale',0,0,2,0,0,1,'numeric() identity',null,2,null)
  389.         insert into spt_datatype_info values    /* sql server type is 'decmaln' */
  390.         (63,null,null,'numeric() identity',2,38,0,10,null,null,null,'precision,scale',0,0,2,0,0,1,'numeric() identity',null,2,null)
  391.  
  392.     end
  393.     commit tran
  394. end
  395. go
  396.  
  397. dump tran master with no_log
  398. go
  399.  
  400. print 'creating table spt_server_info'
  401. go
  402. create table spt_server_info (
  403.               attribute_id        int NOT NULL,
  404.               attribute_name    varchar(60) NOT NULL,
  405.               attribute_value    varchar(255) NOT NULL)
  406. go
  407.  
  408. create unique clustered index serverinfoclust on spt_server_info(attribute_id)
  409. go
  410.  
  411. insert into spt_server_info
  412.     values (1,'DBMS_NAME','Microsoft SQL Server')
  413. insert into spt_server_info
  414.     values (2,'DBMS_VER',@@version)
  415. insert into spt_server_info
  416.     values (10,'OWNER_TERM','owner')
  417. insert into spt_server_info
  418.     values (11,'TABLE_TERM','table')
  419. insert into spt_server_info
  420.     values (12,'MAX_OWNER_NAME_LENGTH','30')
  421. insert into spt_server_info
  422.     values (13,'TABLE_LENGTH','30')
  423. insert into spt_server_info
  424.     values (14,'MAX_QUAL_LENGTH','30')
  425. insert into spt_server_info
  426.     values (15,'COLUMN_LENGTH','30')
  427. if 'A' = 'a' /* If not case sensitive server */
  428. begin
  429.     insert into spt_server_info
  430.         values (16,'IDENTIFIER_CASE','MIXED')
  431. end
  432. else
  433. begin
  434.     insert into spt_server_info
  435.         values (16,'IDENTIFIER_CASE','SENSITIVE')
  436. end
  437. insert into spt_server_info
  438.     values (17,'TX_ISOLATION','2')
  439. if    (charindex('6.00', @@version) > 0 or
  440.      charindex('6.50', @@version) > 0)
  441. begin    /*    Add 6.0 collation sequence */
  442.     insert into spt_server_info
  443.         select 18,'COLLATION_SEQ',
  444.             'charset='+t2.name+' sort_order='+t1.name
  445.             +' charset_num='+rtrim(convert(char(4),t1.csid))+
  446.             ' sort_order_num='+rtrim(convert(char(4),t1.id))
  447.         from syscharsets t1, syscharsets t2, sysconfigures t3
  448.         where t1.csid=t2.id and t1.id=t3.value and t3.config=1123
  449. end
  450. else
  451. begin    /*    Add 4.2x collation sequence */
  452.     insert into spt_server_info
  453.         select 18,'COLLATION_SEQ',
  454.             'charset='+t2.name+' sort_order='+t1.name
  455.             +' charset_num='+rtrim(convert(char(4),t1.csid))+
  456.             ' sort_order_num='+rtrim(convert(char(4),t1.id))
  457.         from syscharsets t1, syscharsets t2, sysconfigures t3
  458.         where t1.csid=t2.id and t1.id=t3.value and t3.config=123
  459. end
  460. insert into spt_server_info
  461.     values (19,'SAVEPOINT_SUPPORT','Y')
  462. insert into spt_server_info
  463.     values (20,'MULTI_RESULT_SETS','Y')
  464. insert into spt_server_info
  465.     values (22,'ACCESSIBLE_TABLES','Y')
  466. insert into spt_server_info
  467.     values (100,'USERID_LENGTH','30')
  468. insert into spt_server_info
  469.     values (101,'QUALIFIER_TERM','database')
  470. insert into spt_server_info
  471.     values (102,'NAMED_TRANSACTIONS','Y')
  472. insert into spt_server_info
  473.     values (103,'SPROC_AS_LANGUAGE','Y')
  474. insert into spt_server_info
  475.     values (104,'ACCESSIBLE_SPROC','Y')
  476. insert into spt_server_info
  477.     values (105,'MAX_INDEX_COLS','16')
  478. insert into spt_server_info
  479.     values (106,'RENAME_TABLE','Y')
  480. insert into spt_server_info
  481.     values (107,'RENAME_COLUMN','Y')
  482. insert into spt_server_info
  483.     values (108,'DROP_COLUMN','N')
  484. insert into spt_server_info
  485.     values (109,'INCREASE_COLUMN_LENGTH','N')
  486. if    (charindex('6.50', @@version) = 0)
  487. begin
  488.     insert into spt_server_info
  489.         values (110,'DDL_IN_TRANSACTION','N')
  490. end
  491. else
  492. begin
  493.     insert into spt_server_info
  494.         values (110,'DDL_IN_TRANSACTION','Y')
  495. end
  496. insert into spt_server_info
  497.     values (111,'DESCENDING_INDEXES','N')
  498. insert into spt_server_info
  499.     values (112,'SP_RENAME','Y')
  500. insert into spt_server_info
  501.     values (113,'REMOTE_SPROC','Y')
  502. insert into spt_server_info
  503.     values (500,'SYS_SPROC_VERSION','6.50.156')
  504. go
  505.  
  506. grant select on spt_server_info to public
  507. go
  508.  
  509. print 'creating sp_column_privileges'
  510. go
  511.  
  512. /*    Procedure for pre 6.50 server */
  513. CREATE PROCEDURE sp_column_privileges (
  514.             @table_name         varchar(32),
  515.             @table_owner        varchar(32) = null,
  516.             @table_qualifier    varchar(32) = null,
  517.             @column_name        varchar(90) = null)
  518. as
  519.  
  520.     declare @table_id     int
  521.     DECLARE @full_table_name    char(70)
  522.     declare @low smallint                     /* range of userids to check */
  523.     declare @high smallint
  524.     declare @owner_uid smallint
  525.  
  526.     select @low = 0, @high = 32767
  527.  
  528.     if @column_name is null /*    If column name not supplied, match all */
  529.         select @column_name = '%'
  530.  
  531.     if @table_qualifier is not null
  532.     begin
  533.         if db_name() <> @table_qualifier
  534.         begin    /* If qualifier doesn't match current database */
  535.             raiserror 20001 'Table qualifier must be name of current database'
  536.             return
  537.         end
  538.     end
  539.     if @table_owner is null
  540.     begin    /* If unqualified table name */
  541.         SELECT @full_table_name = @table_name
  542.     end
  543.     else
  544.     begin    /* Qualified table name */
  545.         SELECT @full_table_name = @table_owner + '.' + @table_name
  546.     end
  547.     /*    Get Object ID */
  548.     select @table_id = object_id(@full_table_name)
  549.  
  550.     if (@@trancount <> 0)
  551.     begin    /* If inside a transaction */
  552.         raiserror 20003 'The procedure ''sp_column_privileges'' cannot be executed from within a transaction.'
  553.         return
  554.     end
  555.  
  556.     /*
  557.     ** We need to create a table which will contain a row for every row to
  558.     ** be returned to the client.
  559.     */
  560.  
  561.     create table #column_priv1(
  562.         COLUMN_NAME             varchar(32) NOT NULL,
  563.         grantor                 smallint NOT NULL,
  564.         grantee                 smallint NOT NULL,
  565.         select_privilege        bit,
  566.         select_grantable        bit,
  567.         insert_privilege        bit,
  568.         insert_grantable        bit,
  569.         update_privilege        bit,
  570.         update_grantable        bit,
  571.         references_privilege    bit,
  572.         references_grantable    bit,
  573.         uid                     smallint NOT NULL,
  574.         gid                     smallint NOT NULL)
  575.  
  576. /*
  577. ** insert a row for the table owner (who has all permissions)
  578. */
  579.     select @owner_uid = (
  580.         select uid
  581.         from sysobjects
  582.         where id = @table_id)
  583.  
  584.     insert into #column_priv1
  585.         select
  586.             c.name,
  587.             u.uid,
  588.             @owner_uid,
  589.             0,
  590.             1,
  591.             0,
  592.             1,
  593.             0,
  594.             1,
  595.             0,
  596.             1,
  597.             @owner_uid,
  598.             0
  599.         from syscolumns c, sysusers u
  600.         where id = @table_id
  601.             and c.number = 0
  602.             and u.suid = 1        /* grantor is dbo of database */
  603. /*
  604. ** now stick in a row for every column for every user in the database
  605. ** we will need to weed out those who have no permissions later
  606. ** (and yes this is a cartesion product: the uid field in sysprotects
  607. ** can also have a group id, in which case we need to extend those
  608. ** privileges to all group members).
  609. */
  610.  
  611.     insert into #column_priv1
  612.         select distinct
  613.             c.name,
  614.             o.uid,
  615.             u.uid,
  616.             0,
  617.             0,
  618.             0,
  619.             0,
  620.             0,
  621.             0,
  622.             0,
  623.             0,
  624.             u.uid,
  625.             u.gid
  626.         from sysusers u, syscolumns c, sysobjects o
  627.         where o.id = @table_id
  628.             and c.id = o.id
  629.             and c.number = 0
  630.             and u.gid <> u.uid
  631.             and u.uid <> @owner_uid
  632.  
  633.     /*
  634.     ** we need to create another temporary table to contain all the various
  635.     ** protection information for the table in question
  636.     */
  637.     create table #protects (
  638.                 uid         smallint NOT NULL,
  639.                 grantor        smallint NOT NULL,
  640.                 action        tinyint NOT NULL,
  641.                 protecttype tinyint NOT NULL,
  642.                 name        varchar(32) NOT NULL)
  643.  
  644.     insert into #protects
  645.         select
  646.             p.uid,
  647.             p.uid,
  648.             p.action,
  649.             p.protecttype,
  650.             isnull(col_name(id, c.number), '~All')
  651.             from
  652.                 sysprotects p,
  653.                 master.dbo.spt_values c,
  654.                 master.dbo.spt_values a,
  655.                 master.dbo.spt_values b
  656.             where
  657.                 convert(tinyint, substring(isnull(p.columns, 0x1), c.low, 1))
  658.                     & c.high <> 0
  659.                     and c.number <= (
  660.                         select count(*)
  661.                         from syscolumns
  662.                         where id = @table_id)
  663.                 and c.type = 'P'
  664.                 and a.type = 'T'
  665.                 and a.number = p.action
  666.                 and p.action in (193,195,197,26)
  667.                 and b.type = 'T'
  668.                 and b.number = p.protecttype
  669.                 and p.id = @table_id
  670.                 and p.uid between @low and @high
  671.  
  672.  
  673.     update #column_priv1
  674.     set select_privilege = 1
  675.         from #protects p
  676.     where
  677.         p.protecttype = 205
  678.         and p.action = 193
  679.         and (p.name = #column_priv1.COLUMN_NAME
  680.             or name = '~All')
  681.         and (p.uid = 0
  682.             or p.uid = #column_priv1.gid
  683.             or p.uid = #column_priv1.uid)
  684.         and not exists (
  685.             select * from #protects
  686.             where
  687.                 protecttype = 206
  688.                 and action = 193
  689.                 and (name = #column_priv1.COLUMN_NAME
  690.                     or name = '~All')
  691.                 and ( uid = 0
  692.                     or uid = #column_priv1.gid
  693.                     or uid = #column_priv1.uid))
  694.  
  695.     update #column_priv1
  696.     set insert_privilege = 1
  697.         from #protects p
  698.     where
  699.         p.protecttype = 205
  700.         and p.action = 195
  701.         and (p.name = #column_priv1.COLUMN_NAME
  702.             or name = '~All')
  703.         and (p.uid = 0
  704.             or p.uid = #column_priv1.gid
  705.             or p.uid = #column_priv1.uid)
  706.         and not exists (
  707.             select * from #protects
  708.             where
  709.                 protecttype = 206
  710.                 and action = 195
  711.                 and (name = #column_priv1.COLUMN_NAME
  712.                     or name = '~All')
  713.                 and (uid = 0
  714.                     or uid = #column_priv1.gid
  715.                     or uid = #column_priv1.uid))
  716.  
  717.     update #column_priv1
  718.     set update_privilege = 1
  719.         from #protects p
  720.     where
  721.         p.protecttype = 205
  722.         and p.action = 197
  723.         and (p.name = #column_priv1.COLUMN_NAME
  724.             or name = '~All')
  725.         and (p.uid = 0
  726.             or p.uid = #column_priv1.gid
  727.             or p.uid = #column_priv1.uid)
  728.         and not exists (
  729.             select * from #protects
  730.                 where protecttype = 206
  731.                 and action = 197
  732.                 and (name = #column_priv1.COLUMN_NAME
  733.                     or name = '~All')
  734.                 and (uid = 0
  735.                     or uid = #column_priv1.gid
  736.                     or uid = #column_priv1.uid))
  737.  
  738.     update #column_priv1
  739.     set references_privilege = 1
  740.         from #protects p
  741.     where
  742.         p.protecttype = 205
  743.         and p.action = 26
  744.         and (p.name = #column_priv1.COLUMN_NAME
  745.             or name = '~All')
  746.         and (p.uid = 0
  747.             or p.uid = #column_priv1.gid
  748.             or p.uid = #column_priv1.uid)
  749.         and not exists (
  750.             select * from #protects
  751.                 where protecttype = 206
  752.                 and action = 26
  753.                 and (name = #column_priv1.COLUMN_NAME
  754.                     or name = '~All')
  755.                 and (uid = 0
  756.                     or uid = #column_priv1.gid
  757.                     or uid = #column_priv1.uid))
  758.  
  759.     update #column_priv1
  760.     set select_grantable = 1
  761.         from #protects p
  762.     where
  763.         p.protecttype = 204
  764.         and p.action = 193
  765.         and (p.name = #column_priv1.COLUMN_NAME
  766.             or name = '~All')
  767.         and (p.uid = 0
  768.             or p.uid = #column_priv1.gid
  769.             or p.uid = #column_priv1.uid)
  770.         and not exists (
  771.             select * from #protects
  772.             where
  773.                 protecttype = 206
  774.                 and action = 193
  775.                 and (name = #column_priv1.COLUMN_NAME
  776.                     or name = '~All')
  777.                 and ( uid = 0
  778.                     or uid = #column_priv1.gid
  779.                     or uid = #column_priv1.uid))
  780.  
  781.     update #column_priv1
  782.     set insert_grantable = 1
  783.         from #protects p
  784.     where
  785.         p.protecttype = 204
  786.         and p.action = 195
  787.         and (p.name = #column_priv1.COLUMN_NAME
  788.             or name = '~All')
  789.         and (p.uid = 0
  790.             or p.uid = #column_priv1.gid
  791.             or p.uid = #column_priv1.uid)
  792.         and not exists (
  793.             select * from #protects
  794.             where
  795.                 protecttype = 206
  796.                 and action = 195
  797.                 and (name = #column_priv1.COLUMN_NAME
  798.                     or name = '~All')
  799.                 and ( uid = 0
  800.                     or uid = #column_priv1.gid
  801.                     or uid = #column_priv1.uid))
  802.  
  803.     update #column_priv1
  804.     set update_grantable = 1
  805.         from #protects p
  806.     where
  807.         p.protecttype = 204
  808.         and p.action = 197
  809.         and (p.name = #column_priv1.COLUMN_NAME
  810.             or name = '~All')
  811.         and (p.uid = 0
  812.             or p.uid = #column_priv1.gid
  813.             or p.uid = #column_priv1.uid)
  814.         and not exists (
  815.             select * from #protects
  816.             where
  817.                 protecttype = 206
  818.                 and action = 197
  819.                 and (name = #column_priv1.COLUMN_NAME
  820.                     or name = '~All')
  821.                 and ( uid = 0
  822.                     or uid = #column_priv1.gid
  823.                     or uid = #column_priv1.uid))
  824.  
  825.     update #column_priv1
  826.     set references_grantable = 1
  827.         from #protects p
  828.     where
  829.         p.protecttype = 204
  830.         and p.action = 26
  831.         and (p.name = #column_priv1.COLUMN_NAME
  832.             or name = '~All')
  833.         and (p.uid = 0
  834.             or p.uid = #column_priv1.gid
  835.             or p.uid = #column_priv1.uid)
  836.         and not exists (
  837.             select * from #protects
  838.             where
  839.                 protecttype = 206
  840.                 and action = 26
  841.                 and (name = #column_priv1.COLUMN_NAME
  842.                     or name = '~All')
  843.                 and ( uid = 0
  844.                     or uid = #column_priv1.gid
  845.                     or uid = #column_priv1.uid))
  846.  
  847.     create table #column_priv2(
  848.         COLUMN_NAME     varchar(32) NOT NULL,
  849.         grantor         smallint NULL,
  850.         grantee         smallint NOT NULL,
  851.         PRIVILEGE        varchar(32) NOT NULL,
  852.         IS_GRANTABLE    varchar(3) NULL)
  853.  
  854.     insert into #column_priv2
  855.         select
  856.             COLUMN_NAME,
  857.             grantor,
  858.             grantee,
  859.             'SELECT',
  860.             'NO'
  861.         from #column_priv1
  862.         where select_privilege = 1 and select_grantable    = 0
  863.  
  864.     insert into #column_priv2
  865.         select
  866.             COLUMN_NAME,
  867.             grantor,
  868.             grantee,
  869.             'INSERT',
  870.             'NO'
  871.         from #column_priv1
  872.         where insert_privilege = 1 and insert_grantable = 0
  873.  
  874.     insert into #column_priv2
  875.         select
  876.             COLUMN_NAME,
  877.             grantor,
  878.             grantee,
  879.             'UPDATE',
  880.             'NO'
  881.         from #column_priv1
  882.         where update_privilege = 1 and update_grantable = 0
  883.  
  884.     insert into #column_priv2
  885.         select
  886.             COLUMN_NAME,
  887.             grantor,
  888.             grantee,
  889.             'REFERENCES',
  890.             'NO'
  891.         from #column_priv1
  892.         where references_privilege = 1 and references_grantable = 0
  893.  
  894.     insert into #column_priv2
  895.         select
  896.             COLUMN_NAME,
  897.             grantor,
  898.             grantee,
  899.             'SELECT',
  900.             'YES'
  901.         from #column_priv1
  902.         where select_grantable = 1
  903.  
  904.     insert into #column_priv2
  905.         select
  906.             COLUMN_NAME,
  907.             grantor,
  908.             grantee,
  909.             'INSERT',
  910.             'YES'
  911.         from #column_priv1
  912.         where insert_grantable = 1
  913.  
  914.     insert into #column_priv2
  915.         select
  916.             COLUMN_NAME,
  917.             grantor,
  918.             grantee,
  919.             'UPDATE',
  920.             'YES'
  921.         from #column_priv1
  922.         where update_grantable = 1
  923.  
  924.     insert into #column_priv2
  925.         select
  926.             COLUMN_NAME,
  927.             grantor,
  928.             grantee,
  929.             'REFERENCES',
  930.             'YES'
  931.         from #column_priv1
  932.         where references_grantable = 1
  933.  
  934.     select
  935.         convert(varchar(32),db_name()) TABLE_QUALIFIER,
  936.         convert(varchar(32),user_name(@owner_uid)) TABLE_OWNER,
  937.         @table_name TABLE_NAME,
  938.         COLUMN_NAME,
  939.         convert(varchar(32),user_name(grantor)) GRANTOR,
  940.         convert(varchar(32),user_name(grantee)) GRANTEE,
  941.         PRIVILEGE,
  942.         IS_GRANTABLE
  943.     from #column_priv2
  944.     where COLUMN_NAME like @column_name
  945.     order by 4, 7
  946. go
  947.  
  948. if    (charindex('6.50', @@version) = 0)
  949. begin
  950.     print ''
  951.     print ''
  952.     print 'Warning:'
  953.     print 'you are installing the stored procedures '
  954.     print 'on a pre 6.50 SQL Server.'
  955.     print 'Ignore the following errors.'
  956. end
  957. else
  958.     drop proc sp_column_privileges
  959. go
  960.  
  961. /*    Procedure for 6.50 server */
  962. CREATE PROCEDURE sp_column_privileges (
  963.             @table_name         varchar(32),
  964.             @table_owner        varchar(32) = null,
  965.             @table_qualifier    varchar(32) = null,
  966.             @column_name        varchar(90) = null)
  967. as
  968.  
  969.     declare @table_id     int
  970.  
  971.     if @column_name is null /*    If column name not supplied, match all */
  972.         select @column_name = '%'
  973.  
  974.     if @table_qualifier is not null
  975.     begin
  976.         if db_name() <> @table_qualifier
  977.         begin    /* If qualifier doesn't match current database */
  978.             raiserror 20001 'Table qualifier must be name of current database'
  979.             return
  980.         end
  981.     end
  982.     if @table_owner is null
  983.     begin    /* If unqualified table name */
  984.         select @table_id = object_id(@table_name)
  985.     end
  986.     else
  987.     begin    /* Qualified table name */
  988.         select @table_id = object_id(@table_owner + '.' + @table_name)
  989.     end
  990.  
  991.     select
  992.         convert(varchar(32),db_name()) TABLE_QUALIFIER,
  993.         convert(varchar(32),user_name(o.uid)) TABLE_OWNER,
  994.         @table_name TABLE_NAME,
  995.         convert(varchar(32),c.name) COLUMN_NAME,
  996.         convert(varchar(32),user_name(p.grantor)) GRANTOR,
  997.         convert(varchar(32),user_name(u.uid)) GRANTEE,
  998.         case p.action
  999.              when 193 then 'SELECT'
  1000.              when 195 then 'INSERT'
  1001.              when 197 then 'UPDATE'
  1002.              else convert(varchar(32),'REFERENCES')
  1003.         end PRIVILEGE,
  1004.         case when p.protecttype = 205 then 'NO'
  1005.             else 'YES'
  1006.         end IS_GRANTABLE
  1007.     from sysprotects p, sysobjects o, sysusers u, master.dbo.spt_values v, syscolumns c
  1008.     where
  1009.         c.id = @table_id
  1010.         and c.name like @column_name
  1011.         and c.id = p.id
  1012.         and c.id = o.id
  1013.         and case substring(p.columns, 1, 1) & 1
  1014.                 when NULL then 255    /* all columns have permission */
  1015.                 when 0 then convert(tinyint, substring(p.columns, v.low, 1))
  1016.                 else (~convert(tinyint, isnull(substring(p.columns, v.low, 1),0)))
  1017.             end
  1018.             & v.high <> 0            /* permission applies to this column */
  1019.         and v.number <= (select count(*) from syscolumns
  1020.             where id = @table_id)    /* ranges from 1 to # of columns in table */
  1021.         and v.type = 'P'
  1022.         and v.number = c.colid
  1023.             /* expand groups */
  1024.         and ((p.uid = u.uid and u.uid <> u.gid) or
  1025.              (p.uid = u.gid and u.uid <> u.gid))
  1026.         and p.protecttype <> 206    /* only grant rows */
  1027.         and p.action in (26,193,195,197)
  1028.         and o.uid <> u.uid            /* no rows for owner */
  1029.         and not exists (            /* exclude revoke'd privileges */
  1030.             select *
  1031.             from sysprotects p1
  1032.             where
  1033.                 p1.protecttype = 206
  1034.                 and p1.action = p.action
  1035.                 and p1.id = p.id
  1036.                 and p1.uid = u.uid
  1037.                 and case substring(p1.columns, 1, 1) & 1
  1038.                         when NULL then 255    /* all columns have permission */
  1039.                         when 0 then convert(tinyint, substring(p1.columns, v.low, 1))
  1040.                         else (~convert(tinyint,isnull(substring(p.columns, v.low, 1),0)))
  1041.                     end
  1042.                     & v.high <> 0)            /* permission applies to this column */
  1043.     union all
  1044.     select    /*    Add rows for table owner */
  1045.         convert(varchar(32),db_name()) TABLE_QUALIFIER,
  1046.         convert(varchar(32),user_name(o.uid)) TABLE_OWNER,
  1047.         @table_name TABLE_NAME,
  1048.         convert(varchar(32),col_name(@table_id, c.colid)) COLUMN_NAME,
  1049.         convert(varchar(32),user_name(u.uid)) grantor,
  1050.         convert(varchar(32),user_name(o.uid)) grantee,
  1051.         case v.number
  1052.             when 193 then 'SELECT'
  1053.             when 195 then 'INSERT'
  1054.             when 197 then 'UPDATE'
  1055.             else convert(varchar(32),'REFERENCES')
  1056.         end PRIVILEGE,
  1057.         convert(varchar,'YES') IS_GRANTABLE
  1058.     from sysobjects o, spt_values v, sysusers u, syscolumns c
  1059.     where
  1060.         c.id = @table_id
  1061.         and c.name like @column_name
  1062.         and c.id = o.id
  1063.         and u.suid = 1        /* grantor is dbo of database */
  1064.         and v.type = 'P'    /* cross product to get all exposed privileges */
  1065.         and v.number in (26,193,195,197)
  1066.         and not exists (    /* exclude revoke'd privileges */
  1067.             select *
  1068.             from sysprotects p1
  1069.             where
  1070.                 p1.protecttype = 206
  1071.                 and p1.action = v.number
  1072.                 and p1.id = o.id
  1073.                 and p1.uid = o.uid)
  1074.     order by 4, 7
  1075. go
  1076.  
  1077. grant execute on sp_column_privileges to public
  1078. go
  1079.  
  1080. dump tran master with no_log
  1081. go
  1082.  
  1083. print 'creating sp_columns'
  1084. go
  1085.  
  1086. /*    Procedure for pre-6.0 server */
  1087. CREATE PROCEDURE sp_columns (
  1088.                  @table_name        varchar(90),
  1089.                  @table_owner        varchar(90) = null,
  1090.                  @table_qualifier    varchar(90) = null,
  1091.                  @column_name        varchar(90) = null,
  1092.                  @ODBCVer            int = 2)
  1093. AS
  1094.     DECLARE @full_table_name    char(181)
  1095.     DECLARE @table_id int
  1096.  
  1097.     if @ODBCVer <> 3
  1098.         select @ODBCVer = 2
  1099.     if @column_name is null /*    If column name not supplied, match all */
  1100.         select @column_name = '%'
  1101.     if @table_qualifier is not null
  1102.     begin
  1103.         if db_name() <> @table_qualifier
  1104.         begin    /* If qualifier doesn't match current database */
  1105.             raiserror 20001 'Table qualifier must be name of current database'
  1106.             return
  1107.         end
  1108.     end
  1109.     if @table_name is null
  1110.     begin    /*    If table name not supplied, match all */
  1111.         select @table_name = '%'
  1112.     end
  1113.     if @table_owner is null
  1114.     begin    /* If unqualified table name */
  1115.         SELECT @full_table_name = @table_name
  1116.     end
  1117.     else
  1118.     begin    /* Qualified table name */
  1119.         SELECT @full_table_name = @table_owner + '.' + @table_name
  1120.     end
  1121.  
  1122.     /*    Get Object ID */
  1123.     SELECT @table_id = object_id(@full_table_name)
  1124.     if ((charindex('%',@full_table_name) = 0) and
  1125.         (charindex('_',@full_table_name) = 0)  and
  1126.         @table_id <> 0)
  1127.     begin
  1128.         /* this block is for the case where there is no pattern
  1129.              matching required for the table name */
  1130.         SELECT
  1131.             TABLE_QUALIFIER = convert(varchar(32),DB_NAME()),
  1132.             TABLE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  1133.             TABLE_NAME = convert(varchar(32),o.name),
  1134.             COLUMN_NAME = convert(varchar(32),c.name),
  1135.             d.DATA_TYPE,
  1136.             TYPE_NAME = t.name,
  1137.             "PRECISION" = isnull(d.data_precision, convert(int,c.length)),
  1138.             LENGTH = isnull(d.length, convert(int,c.length)),
  1139.             SCALE = d.numeric_scale,
  1140.             d.RADIX,
  1141.             NULLABLE =    /* set nullability from status flag */
  1142.                 convert(smallint, convert(bit, c.status&8)),
  1143.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  1144.             COLUMN_DEF = convert(varchar(254),substring(text,2,datalength(text)-2)),
  1145.             DATETIME_CODE = convert(int,d.SQL_DATETIME_SUB),
  1146.             CHAR_OCTET_LENGTH = isnull(d.data_precision, convert(int,c.length))+d.charbin,
  1147.             ORDINAL_POSITION = convert(int,c.colid),
  1148.             IS_NULLABLE = convert(varchar(254),rtrim(substring('NO      YES',(c.status&8)+1,3))),
  1149.             SS_DATA_TYPE = c.type
  1150.         FROM
  1151.             syscolumns c,
  1152.             sysobjects o,
  1153.             syscomments m,
  1154.             master.dbo.spt_datatype_info d,
  1155.             systypes t
  1156.         WHERE
  1157.             o.id = @table_id
  1158.             AND c.id = o.id
  1159.             AND t.type = d.ss_dtype
  1160.             AND c.length = isnull(d.fixlen, c.length)
  1161.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  1162.             AND o.type <> 'P'
  1163.             AND c.usertype = t.usertype
  1164.             AND c.name like @column_name
  1165.             AND c.cdefault *= m.id
  1166.         ORDER BY 16
  1167.     end
  1168.     else
  1169.     begin
  1170.         /* this block is for the case where there IS pattern
  1171.              matching done on the table name */
  1172.         if @table_owner is null /*    If owner not supplied, match all */
  1173.             select @table_owner = '%'
  1174.         SELECT
  1175.             TABLE_QUALIFIER = convert(varchar(32),DB_NAME()),
  1176.             TABLE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  1177.             TABLE_NAME = convert(varchar(32),o.name),
  1178.             COLUMN_NAME = convert(varchar(32),c.name),
  1179.             d.DATA_TYPE,
  1180.             TYPE_NAME = t.name,
  1181.             "PRECISION" = isnull(d.data_precision, convert(int,c.length)),
  1182.             LENGTH = isnull(d.length, convert(int,c.length)),
  1183.             SCALE = d.numeric_scale,
  1184.             d.RADIX,
  1185.             NULLABLE =    /* set nullability from status flag */
  1186.                 convert(smallint, convert(bit, c.status&8)),
  1187.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  1188.             COLUMN_DEF = convert(varchar(254),substring(text,2,datalength(text)-2)),
  1189.             DATETIME_CODE = convert(int,d.SQL_DATETIME_SUB),
  1190.             CHAR_OCTET_LENGTH = isnull(d.data_precision, convert(int,c.length))+d.charbin,
  1191.             ORDINAL_POSITION = convert(int,c.colid),
  1192.             IS_NULLABLE = convert(varchar(254),rtrim(substring('NO      YES',(c.status&8)+1,3))),
  1193.             SS_DATA_TYPE = c.type
  1194.         FROM
  1195.             syscolumns c,
  1196.             sysobjects o,
  1197.             syscomments m,
  1198.             master.dbo.spt_datatype_info d,
  1199.             systypes t
  1200.         WHERE
  1201.             o.name like @table_name
  1202.             AND user_name(o.uid) like @table_owner
  1203.             AND o.id = c.id
  1204.             AND t.type = d.ss_dtype
  1205.             AND c.length = isnull(d.fixlen, c.length)
  1206.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  1207.             AND o.type <> 'P'
  1208.             AND c.usertype = t.usertype
  1209.             AND c.name like @column_name
  1210.             AND c.cdefault *= m.id
  1211.         ORDER BY 2, 3, 16
  1212.     end
  1213. go
  1214.  
  1215. if    (charindex('6.00', @@version) = 0 and
  1216.      charindex('6.50', @@version) = 0)
  1217. begin
  1218.     print ''
  1219.     print ''
  1220.     print 'Warning:'
  1221.     print 'you are installing the stored procedures '
  1222.     print 'on a pre 6.0 SQL Server.'
  1223.     print 'Ignore the following error.'
  1224. end
  1225. else
  1226.     drop proc sp_columns
  1227. go
  1228.  
  1229. /*    Procedure for 6.0 server */
  1230. CREATE PROCEDURE sp_columns (
  1231.                  @table_name        varchar(90),
  1232.                  @table_owner        varchar(90) = null,
  1233.                  @table_qualifier    varchar(90) = null,
  1234.                  @column_name        varchar(90) = null,
  1235.                  @ODBCVer            int = 2)
  1236. AS
  1237.     DECLARE @full_table_name    char(181)
  1238.     DECLARE @table_id int
  1239.  
  1240.     if @ODBCVer <> 3
  1241.         select @ODBCVer = 2
  1242.     if @column_name is null /*    If column name not supplied, match all */
  1243.         select @column_name = '%'
  1244.     if @table_qualifier is not null
  1245.     begin
  1246.         if db_name() <> @table_qualifier
  1247.         begin    /* If qualifier doesn't match current database */
  1248.             raiserror (15250, -1,-1,'Table')
  1249.             return
  1250.         end
  1251.     end
  1252.     if @table_name is null
  1253.     begin    /*    If table name not supplied, match all */
  1254.         select @table_name = '%'
  1255.     end
  1256.     if @table_owner is null
  1257.     begin    /* If unqualified table name */
  1258.         SELECT @full_table_name = @table_name
  1259.     end
  1260.     else
  1261.     begin    /* Qualified table name */
  1262.         SELECT @full_table_name = @table_owner + '.' + @table_name
  1263.     end
  1264.  
  1265.     /*    Get Object ID */
  1266.     SELECT @table_id = object_id(@full_table_name)
  1267.     if ((charindex('%',@full_table_name) = 0) and
  1268.         (charindex('_',@full_table_name) = 0)  and
  1269.         @table_id <> 0)
  1270.     begin
  1271.         /* this block is for the case where there is no pattern
  1272.             matching required for the table name */
  1273.         SELECT
  1274.             TABLE_QUALIFIER = convert(varchar(32),DB_NAME()),
  1275.             TABLE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  1276.             TABLE_NAME = convert(varchar(32),o.name),
  1277.             COLUMN_NAME = convert(varchar(32),c.name),
  1278.             d.DATA_TYPE,
  1279.             case
  1280.                 when t.usertype > 100 or t.usertype in (18,80) then convert(varchar(30),t.name)
  1281.                 else d.TYPE_NAME
  1282.             end TYPE_NAME,
  1283.             case
  1284.                 when d.DATA_TYPE in (6,7) then d.data_precision         /* FLOAT/REAL */
  1285.                 else isnull(convert(int,c.prec), 2147483647)
  1286.             end "PRECISION",
  1287.             case
  1288.                 when d.ss_dtype IN (106, 108, 55, 63) then    /* decimal/numeric types */
  1289.                     convert(int,c.prec+2)
  1290.                 else
  1291.                     isnull(d.length, convert(int,c.length))
  1292.             end LENGTH,
  1293.             SCALE = convert(smallint, c.scale),
  1294.             d.RADIX,
  1295.             NULLABLE =    /* set nullability from status flag */
  1296.                 convert(smallint, convert(bit, c.status&8)),
  1297.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  1298.             COLUMN_DEF = convert(varchar(254),substring(text,2,datalength(text)-2)),
  1299.             DATETIME_CODE = convert(int,d.SQL_DATETIME_SUB),
  1300.             CHAR_OCTET_LENGTH = isnull(convert(int,c.prec), 2147483647)+d.charbin,
  1301.             ORDINAL_POSITION = convert(int,c.colid),
  1302.             IS_NULLABLE = convert(varchar(254),rtrim(substring('NO      YES',(c.status&8)+1,3))),
  1303.             SS_DATA_TYPE = c.type
  1304.         FROM
  1305.             syscolumns c,
  1306.             sysobjects o,
  1307.             syscomments m,
  1308.             master.dbo.spt_datatype_info d,
  1309.             systypes t
  1310.         WHERE
  1311.             o.id = @table_id
  1312.             AND c.id = o.id
  1313.             AND t.type = d.ss_dtype
  1314.             AND c.length = isnull(d.fixlen, c.length)
  1315.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  1316.             AND o.type <> 'P'
  1317.             AND isnull(d.AUTO_INCREMENT,0) = (c.status&128)/128
  1318.             AND c.usertype = t.usertype
  1319.             AND c.name like @column_name
  1320.             AND c.cdefault *= m.id
  1321.         ORDER BY 16
  1322.     end
  1323.     else
  1324.     begin
  1325.         /* this block is for the case where there IS pattern
  1326.             matching done on the table name */
  1327.         if @table_owner is null /*    If owner not supplied, match all */
  1328.             select @table_owner = '%'
  1329.         SELECT
  1330.             TABLE_QUALIFIER = convert(varchar(32),DB_NAME()),
  1331.             TABLE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  1332.             TABLE_NAME = convert(varchar(32),o.name),
  1333.             COLUMN_NAME = convert(varchar(32),c.name),
  1334.             d.DATA_TYPE,
  1335.             case
  1336.                 when t.usertype > 100 or t.usertype in (18,80) then convert(varchar(30),t.name)
  1337.                 else d.TYPE_NAME
  1338.             end TYPE_NAME,
  1339.             case
  1340.                 when d.DATA_TYPE in (6,7) then d.data_precision         /* FLOAT/REAL */
  1341.                 else isnull(convert(int,c.prec), 2147483647)
  1342.             end "PRECISION",
  1343.             case
  1344.                 when d.ss_dtype IN (106, 108, 55, 63) then    /* decimal/numeric types */
  1345.                     convert(int,c.prec+2)
  1346.                 else
  1347.                     isnull(d.length, convert(int,c.length))
  1348.             end LENGTH,
  1349.             SCALE = convert(smallint, c.scale),
  1350.             d.RADIX,
  1351.             NULLABLE =    /* set nullability from status flag */
  1352.                 convert(smallint, convert(bit, c.status&8)),
  1353.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  1354.             COLUMN_DEF = convert(varchar(254),substring(text,2,datalength(text)-2)),
  1355.             DATETIME_CODE = convert(int,d.SQL_DATETIME_SUB),
  1356.             CHAR_OCTET_LENGTH = isnull(convert(int,c.prec), 2147483647)+d.charbin,
  1357.             ORDINAL_POSITION = convert(int,c.colid),
  1358.             IS_NULLABLE = convert(varchar(254),rtrim(substring('NO      YES',(c.status&8)+1,3))),
  1359.             SS_DATA_TYPE = c.type
  1360.         FROM
  1361.             syscolumns c,
  1362.             sysobjects o,
  1363.             syscomments m,
  1364.             master.dbo.spt_datatype_info d,
  1365.             systypes t
  1366.         WHERE
  1367.             o.name like @table_name
  1368.             AND user_name(o.uid) like @table_owner
  1369.             AND o.id = c.id
  1370.             AND t.type = d.ss_dtype
  1371.             AND c.length = isnull(d.fixlen, c.length)
  1372.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  1373.             AND o.type <> 'P'
  1374.             AND isnull(d.AUTO_INCREMENT,0) = (c.status&128)/128
  1375.             AND c.usertype = t.usertype
  1376.             AND c.name like @column_name
  1377.             AND c.cdefault *= m.id
  1378.         ORDER BY 2, 3, 16
  1379.     end
  1380. go
  1381.  
  1382. grant execute on sp_columns to public
  1383. go
  1384.  
  1385. dump tran master with no_log
  1386. go
  1387.  
  1388. print 'creating sp_databases'
  1389. go
  1390.  
  1391. create proc sp_databases
  1392. as
  1393.     /* Use temporary table to sum up database size w/o using group by */
  1394.     create table #databases (
  1395.                   DATABASE_NAME varchar(32) NOT NULL,
  1396.                   size int NOT NULL)
  1397.  
  1398.     /* Insert row for each database */
  1399.     insert into #databases
  1400.         select
  1401.             name,
  1402.             (select sum(size) from master.dbo.sysusages
  1403.                 where dbid = d.dbid)
  1404.         from master.dbo.sysdatabases d
  1405.  
  1406.     select
  1407.          convert(varchar(32),DATABASE_NAME),
  1408.          DATABASE_SIZE = size*2,    /* Convert from 2048 byte pages to K */
  1409.          REMARKS = convert(varchar(254),null)    /* Remarks are NULL */
  1410.     from #databases
  1411.     order by 1
  1412. go
  1413.  
  1414. grant execute on sp_databases to public
  1415. go
  1416.  
  1417. dump tran master with no_log
  1418. go
  1419.  
  1420. print 'creating sp_datatype_info'
  1421. go
  1422.  
  1423. /*    Procedure for pre-6.0 server */
  1424. create proc sp_datatype_info
  1425.     (@data_type int = 0, @ODBCVer tinyint = 2)
  1426. as
  1427.     if @ODBCVer <> 3
  1428.         select @ODBCVer = 2
  1429.     if @data_type = 0
  1430.         select
  1431.             TYPE_NAME = t.name,
  1432.             d.DATA_TYPE,
  1433.             "PRECISION" = isnull(d.data_precision, convert(int,t.length)),
  1434.             d.LITERAL_PREFIX,
  1435.             d.LITERAL_SUFFIX,
  1436.             e.CREATE_PARAMS,
  1437.             d.NULLABLE,
  1438.             d.CASE_SENSITIVE,
  1439.             d.SEARCHABLE,
  1440.             d.UNSIGNED_ATTRIBUTE,
  1441.             d.MONEY,
  1442.             d.AUTO_INCREMENT,
  1443.             LOCAL_TYPE_NAME = t.name,
  1444.             MINIMUM_SCALE = d.numeric_scale,
  1445.             MAXIMUM_SCALE = d.numeric_scale,
  1446.             d.SQL_DATA_TYPE,
  1447.             d.SQL_DATETIME_SUB,
  1448.             NUM_PREC_RADIX = convert(int,d.RADIX),
  1449.             USERTYPE = t.usertype
  1450.         from master.dbo.spt_datatype_info d, master.dbo.spt_datatype_info_ext e, systypes t
  1451.         where
  1452.             d.ss_dtype = t.type
  1453.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  1454.             and t.usertype *= e.user_type
  1455.             and t.type not in (111,109,38,110)    /* get rid of nullable types */
  1456.         order by 2, 12, 11, t.usertype
  1457.  
  1458.     else
  1459.         select
  1460.             TYPE_NAME = t.name,
  1461.             d.DATA_TYPE,
  1462.             "PRECISION" = isnull(d.data_precision, convert(int,t.length)),
  1463.             d.LITERAL_PREFIX,
  1464.             d.LITERAL_SUFFIX,
  1465.             e.CREATE_PARAMS,
  1466.             d.NULLABLE,
  1467.             d.CASE_SENSITIVE,
  1468.             d.SEARCHABLE,
  1469.             d.UNSIGNED_ATTRIBUTE,
  1470.             d.MONEY,
  1471.             d.AUTO_INCREMENT,
  1472.             LOCAL_TYPE_NAME = t.name,
  1473.             MINIMUM_SCALE = d.numeric_scale,
  1474.             MAXIMUM_SCALE = d.numeric_scale,
  1475.             d.SQL_DATA_TYPE,
  1476.             d.SQL_DATETIME_SUB,
  1477.             NUM_PREC_RADIX = convert(int,d.RADIX),
  1478.             USERTYPE = t.usertype
  1479.         from master.dbo.spt_datatype_info d, master.dbo.spt_datatype_info_ext e, systypes t
  1480.         where
  1481.             DATA_TYPE = @data_type
  1482.             and d.ss_dtype = t.type
  1483.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  1484.             and t.usertype *= e.user_type
  1485.             and t.type not in (111,109,38,110)    /* get rid of nullable types */
  1486.         order by 12, 11, t.usertype
  1487.  
  1488. go
  1489.  
  1490. if    (charindex('6.00', @@version) = 0 and
  1491.      charindex('6.50', @@version) = 0)
  1492. begin
  1493.     print ''
  1494.     print ''
  1495.     print 'Warning:'
  1496.     print 'you are installing the stored procedures '
  1497.     print 'on a pre 6.0 SQL Server.'
  1498.     print 'Ignore the following errors.'
  1499. end
  1500. else
  1501.     drop proc sp_datatype_info
  1502. go
  1503.  
  1504. /*    Procedure for 6.0 server */
  1505. create proc sp_datatype_info
  1506.     (@data_type int = 0, @ODBCVer tinyint = 2)
  1507. as
  1508.     if @ODBCVer <> 3
  1509.         select @ODBCVer = 2
  1510.     if @data_type = 0
  1511.         select
  1512.             case
  1513.                 when t.usertype > 100 or t.usertype in (18,80) then convert(varchar(30),t.name)
  1514.                 else d.TYPE_NAME
  1515.             end TYPE_NAME,
  1516.             d.DATA_TYPE,
  1517.             case
  1518.                 when d.DATA_TYPE in (6,7) then d.data_precision         /* FLOAT/REAL */
  1519.                 when d.ss_dtype in (35,34) then 2147483647                /* TEXT/IMAGE */
  1520.                 when d.ss_dtype in (55,63,106,108) then @@max_precision /* DECIMAL/NUMERIC */
  1521.                 else convert(int,t.prec)
  1522.             end "PRECISION",
  1523.             d.LITERAL_PREFIX,
  1524.             d.LITERAL_SUFFIX,
  1525.             e.CREATE_PARAMS,
  1526.             case
  1527.                 when d.AUTO_INCREMENT = 1 then convert(smallint,0) /* IDENTITY*/
  1528.                 else convert(smallint,t.allownulls)
  1529.             end NULLABLE,
  1530.             d.CASE_SENSITIVE,
  1531.             d.SEARCHABLE,
  1532.             d.UNSIGNED_ATTRIBUTE,
  1533.             d.MONEY,
  1534.             d.AUTO_INCREMENT,
  1535.             case
  1536.                 when t.usertype > 100 or t.usertype in (18,80) then convert(varchar(30),t.name)
  1537.                 else d.TYPE_NAME
  1538.             end LOCAL_TYPE_NAME,
  1539.             MINIMUM_SCALE = d.numeric_scale,
  1540.             case
  1541.                 when d.ss_dtype in (106,108) and d.AUTO_INCREMENT = 0 then convert(smallint,@@max_precision) /* DECIMAL/NUMERIC */
  1542.                 when d.ss_dtype in (106,108) and d.AUTO_INCREMENT = 1 then convert(smallint,0) /* DECIMAL/NUMERIC IDENTITY*/
  1543.                 else convert(smallint,t.scale)
  1544.             end MAXIMUM_SCALE,
  1545.             d.SQL_DATA_TYPE,
  1546.             d.SQL_DATETIME_SUB,
  1547.             NUM_PREC_RADIX = convert(int,d.RADIX),
  1548.             USERTYPE = t.usertype
  1549.         from master.dbo.spt_datatype_info d, master.dbo.spt_datatype_info_ext e, systypes t
  1550.         where
  1551.             d.ss_dtype = t.type
  1552.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  1553.             and t.usertype *= e.user_type
  1554.             and isnull(d.AUTO_INCREMENT,0) *= e.AUTO_INCREMENT
  1555.             and t.type not in (111,109,38,110,55,63)    /* get rid of nullable types */
  1556.         order by 2, 12, 11, t.usertype
  1557.  
  1558.     else
  1559.         select
  1560.             case
  1561.                 when t.usertype > 100 or t.usertype in (18,80) then convert(varchar(30),t.name)
  1562.                 else d.TYPE_NAME
  1563.             end TYPE_NAME,
  1564.             d.DATA_TYPE,
  1565.             case
  1566.                 when d.DATA_TYPE in (6,7) then d.data_precision         /* FLOAT/REAL */
  1567.                 when d.ss_dtype in (35,34) then 2147483647                /* TEXT/IMAGE */
  1568.                 when d.ss_dtype in (55,63,106,108) then @@max_precision /* DECIMAL/NUMERIC */
  1569.                 else convert(int,t.prec)
  1570.             end "PRECISION",
  1571.             d.LITERAL_PREFIX,
  1572.             d.LITERAL_SUFFIX,
  1573.             e.CREATE_PARAMS,
  1574.             case
  1575.                 when d.AUTO_INCREMENT = 1 then convert(smallint,0) /* IDENTITY*/
  1576.                 else convert(smallint,t.allownulls)
  1577.             end NULLABLE,
  1578.             d.CASE_SENSITIVE,
  1579.             d.SEARCHABLE,
  1580.             d.UNSIGNED_ATTRIBUTE,
  1581.             d.MONEY,
  1582.             d.AUTO_INCREMENT,
  1583.             case
  1584.                 when t.usertype > 100 or t.usertype in (18,80) then convert(varchar(30),t.name)
  1585.                 else d.TYPE_NAME
  1586.             end LOCAL_TYPE_NAME,
  1587.             MINIMUM_SCALE = d.numeric_scale,
  1588.             case
  1589.                 when d.ss_dtype in (106,108) and d.AUTO_INCREMENT = 0 then convert(smallint,@@max_precision) /* DECIMAL/NUMERIC */
  1590.                 when d.ss_dtype in (106,108) and d.AUTO_INCREMENT = 1 then convert(smallint,0) /* DECIMAL/NUMERIC IDENTITY*/
  1591.                 else convert(smallint,t.scale)
  1592.             end MAXIMUM_SCALE,
  1593.             d.SQL_DATA_TYPE,
  1594.             d.SQL_DATETIME_SUB,
  1595.             NUM_PREC_RADIX = convert(int,d.RADIX),
  1596.             USERTYPE = t.usertype
  1597.         from master.dbo.spt_datatype_info d, master.dbo.spt_datatype_info_ext e, systypes t
  1598.         where
  1599.             d.DATA_TYPE = @data_type
  1600.             and d.ss_dtype = t.type
  1601.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  1602.             and t.usertype *= e.user_type
  1603.             and isnull(d.AUTO_INCREMENT,0) *= e.AUTO_INCREMENT
  1604.             and t.type not in (111,109,38,110,55,63)    /* get rid of nullable types */
  1605.         order by 12, 11, t.usertype
  1606. go
  1607.  
  1608. grant execute on sp_datatype_info to public
  1609. go
  1610.  
  1611. dump tran master with no_log
  1612. go
  1613.  
  1614. print 'creating sp_fkeys'
  1615. go
  1616.  
  1617. /*    Procedure for pre-6.0 server */
  1618. CREATE PROCEDURE sp_fkeys(
  1619.                @pktable_name        varchar(32) = null,
  1620.                @pktable_owner        varchar(32) = null,
  1621.                @pktable_qualifier    varchar(32) = null,
  1622.                @fktable_name        varchar(32) = null,
  1623.                @fktable_owner        varchar(32) = null,
  1624.                @fktable_qualifier    varchar(32) = null )
  1625. as
  1626.     declare    @order_by_pk int
  1627.  
  1628.     select  @order_by_pk = 0
  1629.  
  1630.     if (@pktable_name is null) and (@fktable_name is null)
  1631.     begin    /* If neither primary key nor foreign key table names given */
  1632.         raiserror 20004 'PK table name or FK table name must be given.'
  1633.         return
  1634.     end
  1635.     if @fktable_qualifier is not null
  1636.     begin
  1637.         if db_name() <> @fktable_qualifier
  1638.         begin    /* If qualifier doesn't match current database */
  1639.             raiserror 20001 'Foreign Key Table qualifier must be name of current database'
  1640.             return
  1641.         end
  1642.     end
  1643.     if @pktable_qualifier is not null
  1644.     begin
  1645.         if db_name() <> @pktable_qualifier
  1646.         begin    /* If qualifier doesn't match current database */
  1647.             raiserror 20001 'Primary Key Table qualifier must be name of current database'
  1648.             return
  1649.         end
  1650.     end
  1651.  
  1652.     if @pktable_name is null
  1653.     begin /*  If table name not supplied, match all */
  1654.         select @pktable_name = '%'
  1655.         select @order_by_pk = 1
  1656.     end
  1657.     if @pktable_owner is null    /*    If PK owner not supplied, match all */
  1658.         select @pktable_owner = '%'
  1659.     if @fktable_name is null    /*    If table name not supplied, match all */
  1660.         select @fktable_name = '%'
  1661.     if @fktable_owner is null    /*    If FK owner not supplied, match all */
  1662.         select @fktable_owner = '%'
  1663.  
  1664.     if @@trancount <> 0
  1665.     begin    /* If inside a transaction */
  1666.         raiserror 20003 'The procedure ''sp_fkeys'' cannot be executed from within a transaction.'
  1667.         return
  1668.     end
  1669.     create table #fkeys(
  1670.              PKTABLE_QUALIFIER    varchar(32) NULL,
  1671.              PKTABLE_OWNER        varchar(32) NULL,
  1672.              PKTABLE_NAME        varchar(32) NOT NULL,
  1673.              PKCOLUMN_NAME        varchar(32) NOT NULL,
  1674.              FKTABLE_QUALIFIER    varchar(32) NULL,
  1675.              FKTABLE_OWNER        varchar(32) NULL,
  1676.              FKTABLE_NAME        varchar(32) NOT NULL,
  1677.              FKCOLUMN_NAME        varchar(32) NOT NULL,
  1678.              KEY_SEQ            smallint NOT NULL)
  1679.  
  1680.     /*    SQL Server supports upto 8 PK/FK relationships between 2 tables */
  1681.     /*    Process syskeys for each relationship */
  1682.     /*    The inserts below adds a row to the temp table for each of the
  1683.         8 possible relationships */
  1684.     insert into #fkeys
  1685.         select
  1686.             db_name(),
  1687.             user_name(o1.uid),
  1688.             object_name(k.depid),
  1689.             c2.name,
  1690.             db_name(),
  1691.             user_name(o2.uid),
  1692.             object_name(k.id),
  1693.             c1.name,
  1694.             1
  1695.         from
  1696.             syskeys k, syscolumns c1, syscolumns c2,sysobjects o1, sysobjects o2
  1697.         where
  1698.             c1.id = k.id
  1699.             and k.type = 2    /* Foreign type key */
  1700.             and c1.colid = k.key1
  1701.             and c2.id = k.depid
  1702.             and c2.colid = k.depkey1
  1703.             and o1.id = k.depid
  1704.             and o2.id = k.id
  1705.     union all
  1706.         select
  1707.             db_name(),
  1708.             user_name(o1.uid),
  1709.             object_name(k.depid),
  1710.             c2.name,
  1711.             db_name(),
  1712.             user_name(o2.uid),
  1713.             object_name(k.id),
  1714.             c1.name,
  1715.             2
  1716.         from
  1717.             syskeys k, syscolumns c1, syscolumns c2,sysobjects o1, sysobjects o2
  1718.         where
  1719.             c1.id = k.id
  1720.             and k.type = 2    /* Foreign type key */
  1721.             and c1.colid = k.key2
  1722.             and c2.id = k.depid
  1723.             and c2.colid = k.depkey2
  1724.             and o1.id = k.depid
  1725.             and o2.id = k.id
  1726.     union all
  1727.         select
  1728.             db_name(),
  1729.             user_name(o1.uid),
  1730.             object_name(k.depid),
  1731.             c2.name,
  1732.             db_name(),
  1733.             user_name(o2.uid),
  1734.             object_name(k.id),
  1735.             c1.name,
  1736.             3
  1737.         from
  1738.             syskeys k, syscolumns c1, syscolumns c2,sysobjects o1, sysobjects o2
  1739.         where
  1740.             c1.id = k.id
  1741.             and k.type = 2    /* Foreign type key */
  1742.             and c1.colid = k.key3
  1743.             and c2.id = k.depid
  1744.             and c2.colid = k.depkey3
  1745.             and o1.id = k.depid
  1746.             and o2.id = k.id
  1747.     union all
  1748.         select
  1749.             db_name(),
  1750.             user_name(o1.uid),
  1751.             object_name(k.depid),
  1752.             c2.name,
  1753.             db_name(),
  1754.             user_name(o2.uid),
  1755.             object_name(k.id),
  1756.             c1.name,
  1757.             4
  1758.         from
  1759.             syskeys k, syscolumns c1, syscolumns c2,sysobjects o1, sysobjects o2
  1760.         where
  1761.             c1.id = k.id
  1762.             and k.type = 2    /* Foreign type key */
  1763.             and c1.colid = k.key4
  1764.             and c2.id = k.depid
  1765.             and c2.colid = k.depkey4
  1766.             and o1.id = k.depid
  1767.             and o2.id = k.id
  1768.     union all
  1769.         select
  1770.             db_name(),
  1771.             user_name(o1.uid),
  1772.             object_name(k.depid),
  1773.             c2.name,
  1774.             db_name(),
  1775.             user_name(o2.uid),
  1776.             object_name(k.id),
  1777.             c1.name,
  1778.             5
  1779.         from
  1780.             syskeys k, syscolumns c1, syscolumns c2,sysobjects o1, sysobjects o2
  1781.         where
  1782.             c1.id = k.id
  1783.             and k.type = 2    /* Foreign type key */
  1784.             and c1.colid = k.key5
  1785.             and c2.id = k.depid
  1786.             and c2.colid = k.depkey5
  1787.             and o1.id = k.depid
  1788.             and o2.id = k.id
  1789.     union all
  1790.         select
  1791.             db_name(),
  1792.             user_name(o1.uid),
  1793.             object_name(k.depid),
  1794.             c2.name,
  1795.             db_name(),
  1796.             user_name(o2.uid),
  1797.             object_name(k.id),
  1798.             c1.name,
  1799.             6
  1800.         from
  1801.             syskeys k, syscolumns c1, syscolumns c2,sysobjects o1, sysobjects o2
  1802.         where
  1803.             c1.id = k.id
  1804.             and k.type = 2    /* Foreign type key */
  1805.             and c1.colid = k.key6
  1806.             and c2.id = k.depid
  1807.             and c2.colid = k.depkey6
  1808.             and o1.id = k.depid
  1809.             and o2.id = k.id
  1810.     union all
  1811.         select
  1812.             db_name(),
  1813.             user_name(o1.uid),
  1814.             object_name(k.depid),
  1815.             c2.name,
  1816.             db_name(),
  1817.             user_name(o2.uid),
  1818.             object_name(k.id),
  1819.             c1.name,
  1820.             7
  1821.         from
  1822.             syskeys k, syscolumns c1, syscolumns c2,sysobjects o1, sysobjects o2
  1823.         where
  1824.             c1.id = k.id
  1825.             and k.type = 2    /* Foreign type key */
  1826.             and c1.colid = k.key7
  1827.             and c2.id = k.depid
  1828.             and c2.colid = k.depkey7
  1829.             and o1.id = k.depid
  1830.             and o2.id = k.id
  1831.     union all
  1832.         select
  1833.             db_name(),
  1834.             user_name(o1.uid),
  1835.             object_name(k.depid),
  1836.             c2.name,
  1837.             db_name(),
  1838.             user_name(o2.uid),
  1839.             object_name(k.id),
  1840.             c1.name,
  1841.             8
  1842.         from
  1843.             syskeys k, syscolumns c1, syscolumns c2,sysobjects o1, sysobjects o2
  1844.         where
  1845.             c1.id = k.id
  1846.             and k.type = 2    /* Foreign type key */
  1847.             and c1.colid = k.key8
  1848.             and c2.id = k.depid
  1849.             and c2.colid = k.depkey8
  1850.             and o1.id = k.depid
  1851.             and o2.id = k.id
  1852.  
  1853.     if @order_by_pk = 1 /*    If order by PK fields */
  1854.         select
  1855.             PKTABLE_QUALIFIER,
  1856.             PKTABLE_OWNER,
  1857.             PKTABLE_NAME,
  1858.             PKCOLUMN_NAME,
  1859.             FKTABLE_QUALIFIER,
  1860.             FKTABLE_OWNER,
  1861.             FKTABLE_NAME,
  1862.             FKCOLUMN_NAME,
  1863.             KEY_SEQ,
  1864.             UPDATE_RULE = convert(smallint, null),
  1865.             DELETE_RULE = convert(smallint,null),
  1866.             FK_NAME = convert(varchar(32),null),
  1867.             PK_NAME = convert(varchar(32),null)
  1868.         from #fkeys
  1869.         where FKTABLE_NAME like @fktable_name
  1870.             and FKTABLE_OWNER like @fktable_owner
  1871.             and PKTABLE_NAME  like @pktable_name
  1872.             and PKTABLE_OWNER like @pktable_owner
  1873.         order by 1, 2, 3, 9
  1874.     else        /*    Order by FK fields */
  1875.         select
  1876.             PKTABLE_QUALIFIER,
  1877.             PKTABLE_OWNER,
  1878.             PKTABLE_NAME,
  1879.             PKCOLUMN_NAME,
  1880.             FKTABLE_QUALIFIER,
  1881.             FKTABLE_OWNER,
  1882.             FKTABLE_NAME,
  1883.             FKCOLUMN_NAME,
  1884.             KEY_SEQ,
  1885.             UPDATE_RULE = convert(smallint,null),
  1886.             DELETE_RULE = convert(smallint,null),
  1887.             FK_NAME = convert(varchar(32),null),
  1888.             PK_NAME = convert(varchar(32),null)
  1889.         from #fkeys
  1890.         where FKTABLE_NAME like @fktable_name
  1891.             and FKTABLE_OWNER like @fktable_owner
  1892.             and PKTABLE_NAME  like @pktable_name
  1893.             and PKTABLE_OWNER like @pktable_owner
  1894.         order by 5, 6, 7, 9
  1895. go
  1896.  
  1897. if    (charindex('6.00', @@version) = 0 and
  1898.      charindex('6.50', @@version) = 0)
  1899. begin
  1900.     print ''
  1901.     print ''
  1902.     print 'Warning:'
  1903.     print 'you are installing the stored procedures '
  1904.     print 'on a pre 6.0 SQL Server.'
  1905.     print 'Ignore the following errors.'
  1906. end
  1907. else
  1908.     drop proc sp_fkeys
  1909. go
  1910.  
  1911. /*    Procedure for 6.0 server */
  1912. CREATE PROCEDURE sp_fkeys(
  1913.                @pktable_name        varchar(32) = null,
  1914.                @pktable_owner        varchar(32) = null,
  1915.                @pktable_qualifier    varchar(32) = null,
  1916.                @fktable_name        varchar(32) = null,
  1917.                @fktable_owner        varchar(32) = null,
  1918.                @fktable_qualifier    varchar(32) = null )
  1919. as
  1920.     DECLARE @pktable_id            int
  1921.     DECLARE @pkfull_table_name    char(70)
  1922.     DECLARE @fktable_id            int
  1923.     DECLARE @fkfull_table_name    char(70)
  1924.     declare    @order_by_pk        int
  1925.  
  1926.     select  @order_by_pk = 0
  1927.  
  1928.     if (@pktable_name is null) and (@fktable_name is null)
  1929.     begin    /* If neither primary key nor foreign key table names given */
  1930.         raiserror (15252,-1,-1)
  1931.         return
  1932.     end
  1933.  
  1934.     if @pktable_owner is null
  1935.     begin    /* If unqualified primary key table name */
  1936.         SELECT @pkfull_table_name = @pktable_name
  1937.     end
  1938.     else
  1939.     begin    /* Qualified primary key table name */
  1940.         SELECT @pkfull_table_name = @pktable_owner + '.' + @pktable_name
  1941.     end
  1942.     /*    Get Object ID */
  1943.     SELECT @pktable_id = object_id(@pkfull_table_name)
  1944.  
  1945.     if @fktable_owner is null
  1946.     begin    /* If unqualified foreign key table name */
  1947.         SELECT @fkfull_table_name = @fktable_name
  1948.     end
  1949.     else
  1950.     begin    /* Qualified foreign key table name */
  1951.         SELECT @fkfull_table_name = @fktable_owner + '.' + @fktable_name
  1952.     end
  1953.     /*    Get Object ID */
  1954.     SELECT @fktable_id = object_id(@fkfull_table_name)
  1955.  
  1956.     if @fktable_name is not null
  1957.     begin
  1958.         if @fktable_id is null
  1959.             SELECT @fktable_id = 0    /* fk table not found, empty result */
  1960.     end
  1961.  
  1962.     if @pktable_name is null
  1963.     begin /*  If table name not supplied, match all */
  1964.         select @order_by_pk = 1
  1965.     end
  1966.     else
  1967.     begin
  1968.         if @pktable_id is null
  1969.         begin
  1970.             SELECT @pktable_id = 0    /* pk table not found, empty result */
  1971.         end
  1972.     end
  1973.  
  1974.     if (@@trancount <> 0 and charindex('6.50', @@version) = 0)
  1975.     begin    /* If inside a transaction */
  1976.         raiserror(15002,-1,-1,'sp_fkeys')
  1977.         return
  1978.     end
  1979.  
  1980.     create table #fkeys(
  1981.              pkdb_id        int NOT NULL,
  1982.              pktable_id     int NOT NULL,
  1983.              pkcolid        int NOT NULL,
  1984.              fkdb_id        int NOT NULL,
  1985.              fktable_id        int NOT NULL,
  1986.              fkcolid        int NOT NULL,
  1987.              KEY_SEQ        smallint NOT NULL,
  1988.              fk_id            int NOT NULL,
  1989.              pk_id            int NOT NULL)
  1990.  
  1991.     /*    SQL Server supports upto 16 PK/FK relationships between 2 tables */
  1992.     /*    Process syskeys for each relationship */
  1993.     /*    The inserts below adds a row to the temp table for each of the
  1994.         16 possible relationships */
  1995.     insert into #fkeys
  1996.         select
  1997.             r.rkeydbid,
  1998.             r.rkeyid,
  1999.             r.rkey1,
  2000.             r.fkeydbid,
  2001.             r.fkeyid,
  2002.             r.fkey1,
  2003.             1,
  2004.             r.constid,
  2005.             s.constid
  2006.         from
  2007.             sysreferences r, sysconstraints s, sysconstraints s1
  2008.         where    r.rkeyid = s.id
  2009.             AND (s.status & 0xf) = 1
  2010.             AND r.constid = s1.constid
  2011.             AND (s1.status & 0x400f) = 3
  2012.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2013.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2014.       union all
  2015.         select
  2016.             r.rkeydbid,
  2017.             r.rkeyid,
  2018.             r.rkey2,
  2019.             r.fkeydbid,
  2020.             r.fkeyid,
  2021.             r.fkey2,
  2022.             2,
  2023.             r.constid,
  2024.             s.constid
  2025.         from
  2026.             sysreferences r, sysconstraints s, sysconstraints s1
  2027.         where    r.rkeyid = s.id
  2028.             AND (s.status & 0xf) = 1
  2029.             AND r.constid = s1.constid
  2030.             AND (s1.status & 0x400f) = 3
  2031.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2032.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2033.       union all
  2034.         select
  2035.             r.rkeydbid,
  2036.             r.rkeyid,
  2037.             r.rkey3,
  2038.             r.fkeydbid,
  2039.             r.fkeyid,
  2040.             r.fkey3,
  2041.             3,
  2042.             r.constid,
  2043.             s.constid
  2044.         from
  2045.             sysreferences r, sysconstraints s, sysconstraints s1
  2046.         where    r.rkeyid = s.id
  2047.             AND (s.status & 0xf) = 1
  2048.             AND r.constid = s1.constid
  2049.             AND (s1.status & 0x400f) = 3
  2050.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2051.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2052.       union all
  2053.         select
  2054.             r.rkeydbid,
  2055.             r.rkeyid,
  2056.             r.rkey4,
  2057.             r.fkeydbid,
  2058.             r.fkeyid,
  2059.             r.fkey4,
  2060.             4,
  2061.             r.constid,
  2062.             s.constid
  2063.         from
  2064.             sysreferences r, sysconstraints s, sysconstraints s1
  2065.         where    r.rkeyid = s.id
  2066.             AND (s.status & 0xf) = 1
  2067.             AND r.constid = s1.constid
  2068.             AND (s1.status & 0x400f) = 3
  2069.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2070.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2071.       union all
  2072.         select
  2073.             r.rkeydbid,
  2074.             r.rkeyid,
  2075.             r.rkey5,
  2076.             r.fkeydbid,
  2077.             r.fkeyid,
  2078.             r.fkey5,
  2079.             5,
  2080.             r.constid,
  2081.             s.constid
  2082.         from
  2083.             sysreferences r, sysconstraints s, sysconstraints s1
  2084.         where    r.rkeyid = s.id
  2085.             AND (s.status & 0xf) = 1
  2086.             AND r.constid = s1.constid
  2087.             AND (s1.status & 0x400f) = 3
  2088.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2089.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2090.       union all
  2091.         select
  2092.             r.rkeydbid,
  2093.             r.rkeyid,
  2094.             r.rkey6,
  2095.             r.fkeydbid,
  2096.             r.fkeyid,
  2097.             r.fkey6,
  2098.             6,
  2099.             r.constid,
  2100.             s.constid
  2101.         from
  2102.             sysreferences r, sysconstraints s, sysconstraints s1
  2103.         where    r.rkeyid = s.id
  2104.             AND (s.status & 0xf) = 1
  2105.             AND r.constid = s1.constid
  2106.             AND (s1.status & 0x400f) = 3
  2107.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2108.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2109.       union all
  2110.         select
  2111.             r.rkeydbid,
  2112.             r.rkeyid,
  2113.             r.rkey7,
  2114.             r.fkeydbid,
  2115.             r.fkeyid,
  2116.             r.fkey7,
  2117.             7,
  2118.             r.constid,
  2119.             s.constid
  2120.         from
  2121.             sysreferences r, sysconstraints s, sysconstraints s1
  2122.         where    r.rkeyid = s.id
  2123.             AND (s.status & 0xf) = 1
  2124.             AND r.constid = s1.constid
  2125.             AND (s1.status & 0x400f) = 3
  2126.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2127.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2128.       union all
  2129.         select
  2130.             r.rkeydbid,
  2131.             r.rkeyid,
  2132.             r.rkey8,
  2133.             r.fkeydbid,
  2134.             r.fkeyid,
  2135.             r.fkey8,
  2136.             8,
  2137.             r.constid,
  2138.             s.constid
  2139.         from
  2140.             sysreferences r, sysconstraints s, sysconstraints s1
  2141.         where    r.rkeyid = s.id
  2142.             AND (s.status & 0xf) = 1
  2143.             AND r.constid = s1.constid
  2144.             AND (s1.status & 0x400f) = 3
  2145.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2146.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2147.       union all
  2148.         select
  2149.             r.rkeydbid,
  2150.             r.rkeyid,
  2151.             r.rkey9,
  2152.             r.fkeydbid,
  2153.             r.fkeyid,
  2154.             r.fkey9,
  2155.             9,
  2156.             r.constid,
  2157.             s.constid
  2158.         from
  2159.             sysreferences r, sysconstraints s, sysconstraints s1
  2160.         where    r.rkeyid = s.id
  2161.             AND (s.status & 0xf) = 1
  2162.             AND r.constid = s1.constid
  2163.             AND (s1.status & 0x400f) = 3
  2164.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2165.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2166.       union all
  2167.         select
  2168.             r.rkeydbid,
  2169.             r.rkeyid,
  2170.             r.rkey10,
  2171.             r.fkeydbid,
  2172.             r.fkeyid,
  2173.             r.fkey10,
  2174.             10,
  2175.             r.constid,
  2176.             s.constid
  2177.         from
  2178.             sysreferences r, sysconstraints s, sysconstraints s1
  2179.         where    r.rkeyid = s.id
  2180.             AND (s.status & 0xf) = 1
  2181.             AND r.constid = s1.constid
  2182.             AND (s1.status & 0x400f) = 3
  2183.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2184.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2185.       union all
  2186.         select
  2187.             r.rkeydbid,
  2188.             r.rkeyid,
  2189.             r.rkey11,
  2190.             r.fkeydbid,
  2191.             r.fkeyid,
  2192.             r.fkey11,
  2193.             11,
  2194.             r.constid,
  2195.             s.constid
  2196.         from
  2197.             sysreferences r, sysconstraints s, sysconstraints s1
  2198.         where    r.rkeyid = s.id
  2199.             AND (s.status & 0xf) = 1
  2200.             AND r.constid = s1.constid
  2201.             AND (s1.status & 0x400f) = 3
  2202.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2203.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2204.       union all
  2205.         select
  2206.             r.rkeydbid,
  2207.             r.rkeyid,
  2208.             r.rkey12,
  2209.             r.fkeydbid,
  2210.             r.fkeyid,
  2211.             r.fkey12,
  2212.             12,
  2213.             r.constid,
  2214.             s.constid
  2215.         from
  2216.             sysreferences r, sysconstraints s, sysconstraints s1
  2217.         where    r.rkeyid = s.id
  2218.             AND (s.status & 0xf) = 1
  2219.             AND r.constid = s1.constid
  2220.             AND (s1.status & 0x400f) = 3
  2221.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2222.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2223.       union all
  2224.         select
  2225.             r.rkeydbid,
  2226.             r.rkeyid,
  2227.             r.rkey13,
  2228.             r.fkeydbid,
  2229.             r.fkeyid,
  2230.             r.fkey13,
  2231.             13,
  2232.             r.constid,
  2233.             s.constid
  2234.         from
  2235.             sysreferences r, sysconstraints s, sysconstraints s1
  2236.         where    r.rkeyid = s.id
  2237.             AND (s.status & 0xf) = 1
  2238.             AND r.constid = s1.constid
  2239.             AND (s1.status & 0x400f) = 3
  2240.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2241.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2242.       union all
  2243.         select
  2244.             r.rkeydbid,
  2245.             r.rkeyid,
  2246.             r.rkey14,
  2247.             r.fkeydbid,
  2248.             r.fkeyid,
  2249.             r.fkey14,
  2250.             14,
  2251.             r.constid,
  2252.             s.constid
  2253.         from
  2254.             sysreferences r, sysconstraints s, sysconstraints s1
  2255.         where    r.rkeyid = s.id
  2256.             AND (s.status & 0xf) = 1
  2257.             AND r.constid = s1.constid
  2258.             AND (s1.status & 0x400f) = 3
  2259.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2260.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2261.       union all
  2262.         select
  2263.             r.rkeydbid,
  2264.             r.rkeyid,
  2265.             r.rkey15,
  2266.             r.fkeydbid,
  2267.             r.fkeyid,
  2268.             r.fkey15,
  2269.             15,
  2270.             r.constid,
  2271.             s.constid
  2272.         from
  2273.             sysreferences r, sysconstraints s, sysconstraints s1
  2274.         where    r.rkeyid = s.id
  2275.             AND (s.status & 0xf) = 1
  2276.             AND r.constid = s1.constid
  2277.             AND (s1.status & 0x400f) = 3
  2278.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2279.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2280.       union all
  2281.         select
  2282.             r.rkeydbid,
  2283.             r.rkeyid,
  2284.             r.rkey16,
  2285.             r.fkeydbid,
  2286.             r.fkeyid,
  2287.             r.fkey16,
  2288.             16,
  2289.             r.constid,
  2290.             s.constid
  2291.         from
  2292.             sysreferences r, sysconstraints s, sysconstraints s1
  2293.         where    r.rkeyid = s.id
  2294.             AND (s.status & 0xf) = 1
  2295.             AND r.constid = s1.constid
  2296.             AND (s1.status & 0x400f) = 3
  2297.             AND r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
  2298.             AND r.fkeyid between isnull(@fktable_id, 0) and isnull(@fktable_id, 0x7fffffff)
  2299.  
  2300.     if @order_by_pk = 1 /*    If order by PK fields */
  2301.         select
  2302.             PKTABLE_QUALIFIER = convert(varchar(32),DB_NAME(f.pkdb_id)),
  2303.             PKTABLE_OWNER = convert(varchar(32),USER_NAME(o1.uid)),
  2304.             PKTABLE_NAME = convert(varchar(32),o1.name),
  2305.             PKCOLUMN_NAME = convert(varchar(32),c1.name),
  2306.             FKTABLE_QUALIFIER = convert(varchar(32),DB_NAME(f.fkdb_id)),
  2307.             FKTABLE_OWNER = convert(varchar(32),USER_NAME(o2.uid)),
  2308.             FKTABLE_NAME = convert(varchar(32),o2.name),
  2309.             FKCOLUMN_NAME = convert(varchar(32),c2.name),
  2310.             KEY_SEQ,
  2311.             UPDATE_RULE = convert(smallint,1),
  2312.             DELETE_RULE = convert(smallint,1),
  2313.             FK_NAME = convert(varchar(128),OBJECT_NAME(fk_id)),
  2314.             PK_NAME = convert(varchar(128),OBJECT_NAME(pk_id))
  2315.         from #fkeys f,
  2316.             sysobjects o1, sysobjects o2,
  2317.             syscolumns c1, syscolumns c2
  2318.         where    o1.id = f.pktable_id
  2319.             AND o2.id = f.fktable_id
  2320.             AND c1.id = f.pktable_id
  2321.             AND c2.id = f.fktable_id
  2322.             AND c1.colid = f.pkcolid
  2323.             AND c2.colid = f.fkcolid
  2324.         order by 1,2,3,9
  2325.     else        /*    Order by FK fields */
  2326.         select
  2327.             PKTABLE_QUALIFIER = convert(varchar(32),DB_NAME(f.pkdb_id)),
  2328.             PKTABLE_OWNER = convert(varchar(32),USER_NAME(o1.uid)),
  2329.             PKTABLE_NAME = convert(varchar(32),o1.name),
  2330.             PKCOLUMN_NAME = convert(varchar(32),c1.name),
  2331.             FKTABLE_QUALIFIER = convert(varchar(32),DB_NAME(f.fkdb_id)),
  2332.             FKTABLE_OWNER = convert(varchar(32),USER_NAME(o2.uid)),
  2333.             FKTABLE_NAME = convert(varchar(32),o2.name),
  2334.             FKCOLUMN_NAME = convert(varchar(32),c2.name),
  2335.             KEY_SEQ,
  2336.             UPDATE_RULE = convert(smallint,1),
  2337.             DELETE_RULE = convert(smallint,1),
  2338.             FK_NAME = convert(varchar(128),OBJECT_NAME(fk_id)),
  2339.             PK_NAME = convert(varchar(128),OBJECT_NAME(pk_id))
  2340.         from #fkeys f,
  2341.             sysobjects o1, sysobjects o2,
  2342.             syscolumns c1, syscolumns c2
  2343.         where    o1.id = f.pktable_id
  2344.             AND o2.id = f.fktable_id
  2345.             AND c1.id = f.pktable_id
  2346.             AND c2.id = f.fktable_id
  2347.             AND c1.colid = f.pkcolid
  2348.             AND c2.colid = f.fkcolid
  2349.         order by 5,6,7,9
  2350. go
  2351.  
  2352. grant execute on sp_fkeys to public
  2353. go
  2354.  
  2355. dump tran master with no_log
  2356. go
  2357.  
  2358. print 'creating sp_pkeys'
  2359. go
  2360.  
  2361. /*    Procedure for pre-6.0 server */
  2362. CREATE PROCEDURE sp_pkeys(
  2363.                @table_name        varchar(32),
  2364.                @table_owner     varchar(32) = null,
  2365.                @table_qualifier varchar(32) = null )
  2366. as
  2367.     if @table_qualifier is not null
  2368.     begin
  2369.         if db_name() <> @table_qualifier
  2370.         begin    /* If qualifier doesn't match current database */
  2371.             raiserror 20001 'Table qualifier must be name of current database'
  2372.             return
  2373.         end
  2374.     end
  2375.     if @table_owner is null /*    If owner not supplied, match all */
  2376.         select @table_owner = '%'
  2377.     if @@trancount <> 0
  2378.     begin    /* If inside a transaction */
  2379.         raiserror 20003 'The procedure ''sp_pkeys'' cannot be executed from within a transaction.'
  2380.         return
  2381.     end
  2382.  
  2383.     create table #pkeys(
  2384.              TABLE_QUALIFIER varchar(32) NULL,
  2385.              TABLE_OWNER     varchar(32) NULL,
  2386.              TABLE_NAME      varchar(32) NOT NULL,
  2387.              COLUMN_NAME     varchar(32) NOT NULL,
  2388.              KEY_SEQ         smallint NOT NULL)
  2389.  
  2390.     /*    SQL Server supports upto 8 PK/FK relationships between 2 tables */
  2391.     /*    Process syskeys for each relationship */
  2392.     /*    The inserts below adds a row to the temp table for each of the
  2393.         8 possible relationships */
  2394.     insert into #pkeys
  2395.         select
  2396.             db_name(),
  2397.             (select user_name(uid) from sysobjects o where o.id = k.id),
  2398.             object_name(k.id),
  2399.             c.name,
  2400.             1
  2401.         from
  2402.             syskeys k, syscolumns c
  2403.         where
  2404.             c.id = k.id
  2405.             and k.type = 1    /* Primary type key */
  2406.             and c.colid = k.key1
  2407.     if (@@rowcount = 0)
  2408.         goto done
  2409.  
  2410.     insert into #pkeys
  2411.         select
  2412.             db_name(),
  2413.             (select user_name(uid) from sysobjects o where o.id = k.id),
  2414.             object_name(k.id),
  2415.             c.name,
  2416.             2
  2417.         from
  2418.             syskeys k, syscolumns c
  2419.         where
  2420.             c.id = k.id
  2421.             and k.type = 1    /* Primary type key */
  2422.             and c.colid = key2
  2423.     if (@@rowcount = 0)
  2424.         goto done
  2425.  
  2426.     insert into #pkeys
  2427.         select
  2428.             db_name(),
  2429.             (select user_name(uid) from sysobjects o where o.id = k.id),
  2430.             object_name(k.id),
  2431.             c.name,
  2432.             3
  2433.         from
  2434.             syskeys k, syscolumns c
  2435.         where
  2436.             c.id = k.id
  2437.             and k.type = 1    /* Primary type key */
  2438.             and c.colid = key3
  2439.     if (@@rowcount = 0)
  2440.         goto done
  2441.  
  2442.     insert into #pkeys
  2443.         select
  2444.             db_name(),
  2445.             (select user_name(uid) from sysobjects o where o.id = k.id),
  2446.             object_name(k.id),
  2447.             c.name,
  2448.             4
  2449.         from
  2450.             syskeys k, syscolumns c
  2451.         where
  2452.             c.id = k.id
  2453.             and k.type = 1    /* Primary type key */
  2454.             and c.colid = key4
  2455.     if (@@rowcount = 0)
  2456.         goto done
  2457.  
  2458.     insert into #pkeys
  2459.         select
  2460.             db_name(),
  2461.             (select user_name(uid) from sysobjects o where o.id = k.id),
  2462.             object_name(k.id),
  2463.             c.name,
  2464.             5
  2465.         from
  2466.             syskeys k, syscolumns c
  2467.         where
  2468.             c.id = k.id
  2469.             and k.type = 1    /* Primary type key */
  2470.             and c.colid = key5
  2471.     if (@@rowcount = 0)
  2472.         goto done
  2473.  
  2474.     insert into #pkeys
  2475.         select
  2476.             db_name(),
  2477.             (select user_name(uid) from sysobjects o where o.id = k.id),
  2478.             object_name(k.id),
  2479.             c.name,
  2480.             6
  2481.         from
  2482.             syskeys k, syscolumns c
  2483.         where
  2484.             c.id = k.id
  2485.             and k.type = 1    /* Primary type key */
  2486.             and c.colid = key6
  2487.     if (@@rowcount = 0)
  2488.         goto done
  2489.  
  2490.     insert into #pkeys
  2491.         select
  2492.             db_name(),
  2493.             (select user_name(uid) from sysobjects o where o.id = k.id),
  2494.             object_name(k.id),
  2495.             c.name,
  2496.             7
  2497.         from
  2498.             syskeys k, syscolumns c
  2499.         where
  2500.             c.id = k.id
  2501.             and k.type = 1    /* Primary type key */
  2502.             and c.colid = key7
  2503.     if (@@rowcount = 0)
  2504.         goto done
  2505.  
  2506.     insert into #pkeys
  2507.          select
  2508.              db_name(),
  2509.              (select user_name(uid) from sysobjects o where o.id = k.id),
  2510.              object_name(k.id),
  2511.              c.name,
  2512.              8
  2513.          from
  2514.              syskeys k, syscolumns c
  2515.          where
  2516.              c.id = k.id
  2517.              and k.type = 1 /* Primary type key */
  2518.              and c.colid = key8
  2519.  
  2520.     done:
  2521.     select
  2522.         TABLE_QUALIFIER,
  2523.         TABLE_OWNER,
  2524.         TABLE_NAME,
  2525.         COLUMN_NAME,
  2526.         KEY_SEQ,
  2527.         PK_NAME = convert(varchar(32),null)
  2528.     from #pkeys
  2529.     where TABLE_NAME = @table_name
  2530.         and TABLE_OWNER like @table_owner
  2531.     order by 1, 2, 3, 5
  2532. go
  2533.  
  2534. if    (charindex('6.00', @@version) = 0 and
  2535.      charindex('6.50', @@version) = 0)
  2536. begin
  2537.     print ''
  2538.     print ''
  2539.     print 'Warning:'
  2540.     print 'you are installing the stored procedures '
  2541.     print 'on a pre 6.0 SQL Server.'
  2542.     print 'Ignore the following error.'
  2543. end
  2544. else
  2545.     drop proc sp_pkeys
  2546. go
  2547.  
  2548. /*    Procedure for 6.0 server */
  2549. CREATE PROCEDURE sp_pkeys(
  2550.                @table_name        varchar(32),
  2551.                @table_owner     varchar(32) = null,
  2552.                @table_qualifier varchar(32) = null )
  2553. as
  2554.     DECLARE @table_id            int
  2555.     DECLARE @full_table_name    char(70)
  2556.  
  2557.     if @table_qualifier is not null
  2558.     begin
  2559.         if db_name() <> @table_qualifier
  2560.         begin    /* If qualifier doesn't match current database */
  2561.             raiserror (15250, -1,-1,'Table')
  2562.             return
  2563.         end
  2564.     end
  2565.     if @table_owner is null
  2566.     begin    /* If unqualified table name */
  2567.         SELECT @full_table_name = @table_name
  2568.     end
  2569.     else
  2570.     begin    /* Qualified table name */
  2571.         SELECT @full_table_name = @table_owner + '.' + @table_name
  2572.     end
  2573.     /*    Get Object ID */
  2574.     SELECT @table_id = object_id(@full_table_name)
  2575.  
  2576.     select
  2577.         TABLE_QUALIFIER = convert(varchar(32),db_name()),
  2578.         TABLE_OWNER = convert(varchar(32),user_name(o.uid)),
  2579.         TABLE_NAME = convert(varchar(32),o.name),
  2580.         COLUMN_NAME = convert(varchar(32),c.name),
  2581.         KEY_SEQ = convert(smallint,c1.colid),
  2582.         PK_NAME = convert(varchar(32),i.name)
  2583.     from
  2584.         sysindexes i, syscolumns c, sysobjects o, syscolumns c1
  2585.     where
  2586.         o.id = @table_id
  2587.         and o.id = c.id
  2588.         and o.id = i.id
  2589.         and (i.status & 0x800) = 0x800
  2590.         and c.name = index_col (@full_table_name, i.indid, c1.colid)
  2591.         and c1.colid <= i.keycnt    /* create rows from 1 to keycnt */
  2592.         and c1.id = @table_id
  2593.     order by 1, 2, 3, 5
  2594. go
  2595.  
  2596. grant execute on sp_pkeys to public
  2597. go
  2598.  
  2599. dump tran master with no_log
  2600. go
  2601.  
  2602. print 'creating sp_server_info'
  2603. go
  2604.  
  2605. create proc sp_server_info (
  2606.             @attribute_id  int = null)
  2607. as
  2608.     if @attribute_id is not null
  2609.         select *
  2610.         from master.dbo.spt_server_info
  2611.         where attribute_id = @attribute_id
  2612.     else
  2613.         select *
  2614.         from master.dbo.spt_server_info
  2615.         order by attribute_id
  2616. go
  2617.  
  2618. grant execute on sp_server_info to public
  2619. go
  2620.  
  2621. dump tran master with no_log
  2622. go
  2623.  
  2624. print 'creating sp_special_columns'
  2625. go
  2626.  
  2627. /*    Procedure for pre-6.0 server */
  2628. CREATE PROCEDURE sp_special_columns (
  2629.                  @table_name        varchar(32),
  2630.                  @table_owner        varchar(32) = null,
  2631.                  @table_qualifier    varchar(32) = null,
  2632.                  @col_type            char(1) = 'R',
  2633.                  @scope                char(1) = 'T',
  2634.                  @nullable            char(1) = 'U',
  2635.                  @ODBCVer            int = 2)
  2636. AS
  2637.     DECLARE @indid                int
  2638.     DECLARE @table_id            int
  2639.     DECLARE @full_table_name    char(70)
  2640.     DECLARE @msg                char(70)
  2641.     DECLARE @scopeout            smallint
  2642.  
  2643.     if @col_type not in ('R','V')
  2644.         begin
  2645.             raiserror 20002 'Illegal ''col_type'' specified -- must be ''R'' or ''V''.'
  2646.             return
  2647.         end
  2648.  
  2649.     if @scope = 'C'
  2650.         select @scopeout = 0
  2651.     else if @scope = 'T'
  2652.         select @scopeout = 1
  2653.     else
  2654.         begin
  2655.             raiserror 20002 'Illegal ''scope'' specified -- must be ''C'' or ''T''.'
  2656.             return
  2657.         end
  2658.  
  2659.     if @nullable not in ('U','O')
  2660.         begin
  2661.             raiserror 20002 'Illegal ''nullable'' specified -- must be ''U'' or ''O''.'
  2662.             return
  2663.         end
  2664.  
  2665.     if @table_qualifier is not null
  2666.        begin
  2667.           if db_name() <> @table_qualifier
  2668.               begin    /* If qualifier doesn't match current database */
  2669.                 raiserror 20001 'Table qualifier must be name of current database'
  2670.                 return
  2671.               end
  2672.        end
  2673.     if @table_owner is null
  2674.        begin    /* If unqualified table name */
  2675.           SELECT @full_table_name = @table_name
  2676.        end
  2677.     else
  2678.        begin    /* Qualified table name */
  2679.           SELECT @full_table_name = @table_owner + '.' + @table_name
  2680.        end
  2681.     /*    Get Object ID */
  2682.     SELECT @table_id = object_id(@full_table_name)
  2683.  
  2684.     if @col_type = 'V'
  2685.     BEGIN /* if ROWVER, just run that query */
  2686.         SELECT
  2687.             SCOPE = convert(smallint,NULL),
  2688.             COLUMN_NAME = convert(varchar(32),c.name),
  2689.             DATA_TYPE = convert(smallint, -3),
  2690.             TYPE_NAME = t.name,
  2691.             "PRECISION" = convert(int,8),
  2692.             LENGTH = convert(int,8),
  2693.             SCALE = convert(smallint, NULL),
  2694.             PSEUDO_COLUMN = convert(smallint,1)
  2695.         FROM
  2696.             systypes t, syscolumns c, master.dbo.spt_datatype_info d
  2697.         WHERE
  2698.             c.id = @table_id
  2699.             AND c.type = d.ss_dtype
  2700.             AND c.usertype = 80 /*    TIMESTAMP */
  2701.             AND t.usertype = 80 /*    TIMESTAMP */
  2702.         RETURN
  2703.     END
  2704.  
  2705.     /* ROWID, now find the id of the 'best' index for this table */
  2706.  
  2707.     IF @nullable = 'O'    /* Don't include any indexes that contain
  2708.                            nullable columns. */
  2709.  
  2710.             SELECT @indid = MIN(indid)
  2711.                 FROM sysindexes i,syscolumns c,syscolumns c2
  2712.                 WHERE
  2713.                     i.status&2 = 2        /*    If Unique Index */
  2714.                      AND c.id = i.id
  2715.                      AND c2.id = c.id
  2716.                      AND c2.colid < i.keycnt + (i.status&16)/16
  2717.                     AND i.id = @table_id
  2718.                     AND indid > 0        /*    Eliminate Table Row */
  2719.                     AND c.name = index_col(@table_name,i.indid,c2.colid)
  2720.                     GROUP BY indid HAVING SUM(c.status&8) = 0
  2721.  
  2722.     ELSE    /* Include indexes that are partially nullable. */
  2723.  
  2724.         SELECT @indid = MIN(indid)
  2725.             FROM sysindexes i
  2726.             WHERE
  2727.                 status&2 = 2        /*    If Unique Index */
  2728.                 AND id = @table_id
  2729.                 AND indid > 0        /*    Eliminate Table Row */
  2730.  
  2731.     SELECT
  2732.         SCOPE = @scopeout,
  2733.         COLUMN_NAME = convert(varchar(32),INDEX_COL(@full_table_name,indid,c2.colid)),
  2734.         d.DATA_TYPE,
  2735.         TYPE_NAME = t.name,
  2736.         "PRECISION" = isnull(d.data_precision, convert(int,c.length)),
  2737.         LENGTH = isnull(d.length, convert(int,c.length)),
  2738.         SCALE = d.numeric_scale,
  2739.         PSEUDO_COLUMN = convert(smallint,1)
  2740.     FROM
  2741.         sysindexes x,
  2742.         syscolumns c,
  2743.         master.dbo.spt_datatype_info d,
  2744.         systypes t,
  2745.         syscolumns c2    /* Self-join to generate list of index columns and */
  2746.                         /* to extract datatype names */
  2747.     WHERE
  2748.         x.id = @table_id
  2749.         AND c.name = INDEX_COL(@full_table_name,@indid,c2.colid)
  2750.         AND c.id = x.id
  2751.         AND c2.id = x.id
  2752.         AND c2.colid < keycnt+(x.status&16)/16
  2753.         AND x.indid = @indid
  2754.         AND t.type = d.ss_dtype
  2755.         AND c.length = d.fixlen
  2756.         AND c.usertype = t.usertype
  2757.  
  2758. go
  2759.  
  2760. if    (charindex('6.00', @@version) = 0 and
  2761.      charindex('6.50', @@version) = 0)
  2762. begin
  2763.     print ''
  2764.     print ''
  2765.     print 'Warning:'
  2766.     print 'you are installing the stored procedures '
  2767.     print 'on a pre 6.0 SQL Server.'
  2768.     print 'Ignore the following errors.'
  2769. end
  2770. else
  2771.     drop proc sp_special_columns
  2772. go
  2773.  
  2774. /*    Procedure for 6.0 server */
  2775. CREATE PROCEDURE sp_special_columns (
  2776.                  @table_name        varchar(32),
  2777.                  @table_owner        varchar(32) = null,
  2778.                  @table_qualifier    varchar(32) = null,
  2779.                  @col_type            char(1) = 'R',
  2780.                  @scope                char(1) = 'T',
  2781.                  @nullable            char(1) = 'U',
  2782.                  @ODBCVer            int = 2)
  2783. AS
  2784.     DECLARE @indid                int
  2785.     DECLARE @table_id            int
  2786.     DECLARE @full_table_name    char(70)
  2787.     DECLARE @msg                char(70)
  2788.     DECLARE @scopeout            smallint
  2789.  
  2790.     if @col_type not in ('R','V')
  2791.         begin
  2792.             raiserror (15251,-1,-1,'col_type','''R'' or ''V''')
  2793.             return
  2794.         end
  2795.  
  2796.     if @scope = 'C'
  2797.         select @scopeout = 0
  2798.     else if @scope = 'T'
  2799.         select @scopeout = 1
  2800.     else
  2801.         begin
  2802.             raiserror (15251,-1,-1,'scope','''C'' or ''T''')
  2803.             return
  2804.         end
  2805.  
  2806.     if @nullable not in ('U','O')
  2807.         begin
  2808.             raiserror (15251,-1,-1,'nullable','''U'' or ''O''')
  2809.             return
  2810.         end
  2811.  
  2812.     if @table_qualifier is not null
  2813.        begin
  2814.           if db_name() <> @table_qualifier
  2815.               begin    /* If qualifier doesn't match current database */
  2816.                 raiserror (15250, -1,-1,'Table')
  2817.                 return
  2818.               end
  2819.        end
  2820.     if @table_owner is null
  2821.        begin    /* If unqualified table name */
  2822.           SELECT @full_table_name = @table_name
  2823.        end
  2824.     else
  2825.        begin    /* Qualified table name */
  2826.           SELECT @full_table_name = @table_owner + '.' + @table_name
  2827.        end
  2828.     /*    Get Object ID */
  2829.     SELECT @table_id = object_id(@full_table_name)
  2830.  
  2831.     if @col_type = 'V'
  2832.     BEGIN /* if ROWVER, just run that query */
  2833.         SELECT
  2834.             SCOPE = convert(smallint,NULL),
  2835.             COLUMN_NAME = convert(varchar(32),c.name),
  2836.             DATA_TYPE = convert(smallint, -2),
  2837.             TYPE_NAME = t.name,
  2838.             "PRECISION" = convert(int,8),
  2839.             LENGTH = convert(int,8),
  2840.             SCALE = convert(smallint, NULL),
  2841.             PSEUDO_COLUMN = convert(smallint,1)
  2842.         FROM
  2843.             systypes t, syscolumns c, master.dbo.spt_datatype_info d
  2844.         WHERE
  2845.             c.id = @table_id
  2846.             AND c.type = d.ss_dtype
  2847.             AND c.usertype = 80 /*    TIMESTAMP */
  2848.             AND t.usertype = 80 /*    TIMESTAMP */
  2849.         RETURN
  2850.     END
  2851.  
  2852.     /* ROWID, now find the id of the 'best' index for this table */
  2853.  
  2854.     IF @nullable = 'O'    /* Don't include any indexes that contain
  2855.                            nullable columns. */
  2856.  
  2857.         SELECT @indid = MIN(indid)
  2858.             FROM sysindexes i,syscolumns c,syscolumns c2
  2859.             WHERE
  2860.                 i.status&2 = 2        /*    If Unique Index */
  2861.                 AND c.id = i.id
  2862.                 AND c2.id = c.id
  2863.                 AND c2.colid < i.keycnt + (i.status&16)/16
  2864.                 AND i.id = @table_id
  2865.                 AND indid > 0        /*    Eliminate Table Row */
  2866.                 AND c.name = index_col(@table_name,i.indid,c2.colid)
  2867.                 GROUP BY indid HAVING SUM(c.status&8) = 0
  2868.  
  2869.     ELSE    /* Include indexes that are partially nullable. */
  2870.  
  2871.         SELECT @indid = MIN(indid)
  2872.             FROM sysindexes i
  2873.             WHERE
  2874.                 status&2 = 2        /*    If Unique Index */
  2875.                 AND id = @table_id
  2876.                 AND indid > 0        /*    Eliminate Table Row */
  2877.  
  2878.     SELECT
  2879.         SCOPE = @scopeout,
  2880.         COLUMN_NAME = convert(varchar(32),INDEX_COL(@full_table_name,indid,c2.colid)),
  2881.         d.DATA_TYPE,
  2882.         case
  2883.             when t.usertype > 100 or t.usertype in (18,80) then convert(varchar(30),t.name)
  2884.             else d.TYPE_NAME
  2885.         end TYPE_NAME,
  2886.         case
  2887.             when d.DATA_TYPE in (6,7) then d.data_precision         /* FLOAT/REAL */
  2888.             else isnull(convert(int,c.prec), 2147483647)
  2889.         end "PRECISION",
  2890.         case
  2891.             when d.ss_dtype IN (106, 108, 55, 63) then    /* decimal/numeric types */
  2892.                 convert(int,c.prec+2)
  2893.             else
  2894.                 isnull(d.length, convert(int,c.length))
  2895.         end LENGTH,
  2896.         SCALE = convert(smallint, c.scale),
  2897.         PSEUDO_COLUMN = convert(smallint,1)
  2898.     FROM
  2899.         sysindexes x,
  2900.         syscolumns c,
  2901.         master.dbo.spt_datatype_info d,
  2902.         systypes t,
  2903.         syscolumns c2    /* Self-join to generate list of index columns and */
  2904.                         /* to extract datatype names */
  2905.     WHERE
  2906.         x.id = @table_id
  2907.         AND c.name = INDEX_COL(@full_table_name,@indid,c2.colid)
  2908.         AND c.id = x.id
  2909.         AND c2.id = x.id
  2910.         AND c2.colid < x.keycnt+(x.status&16)/16
  2911.         AND x.indid = @indid
  2912.         AND t.type = d.ss_dtype
  2913.         AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  2914.         AND isnull(d.AUTO_INCREMENT,0) = (c.status&128)/128
  2915.         AND c.usertype = t.usertype
  2916. go
  2917.  
  2918. grant execute on sp_special_columns to public
  2919. go
  2920.  
  2921. dump tran master with no_log
  2922. go
  2923.  
  2924. print 'creating sp_sproc_columns'
  2925. go
  2926.  
  2927. /*    Procedure for pre-6.0 server */
  2928. CREATE PROCEDURE sp_sproc_columns (
  2929.                  @procedure_name        varchar(96) = '%',
  2930.                  @procedure_owner        varchar(90) = null,
  2931.                  @procedure_qualifier    varchar(32) = null,
  2932.                  @column_name            varchar(90) = null,
  2933.                  @ODBCVer                int = 2)
  2934. AS
  2935.     DECLARE @group_num int
  2936.     DECLARE @semi_position int
  2937.     DECLARE @full_procedure_name    char(187)
  2938.     DECLARE @procedure_id int
  2939.  
  2940.     if @column_name is null /*    If column name not supplied, match all */
  2941.         select @column_name = '%'
  2942.     if @procedure_qualifier is not null
  2943.     begin
  2944.         if db_name() <> @procedure_qualifier
  2945.         begin
  2946.             if @procedure_qualifier = ''
  2947.             begin
  2948.                 /* in this case, we need to return an empty result set */
  2949.                 /* because the user has requested a database with an empty name */
  2950.                 select @procedure_name = ''
  2951.                 select @procedure_owner = ''
  2952.             end
  2953.             else
  2954.             begin    /* If qualifier doesn't match current database */
  2955.                 raiserror 20001 'Procedure qualifier must be name of current database'
  2956.                 return
  2957.             end
  2958.         end
  2959.     end
  2960.  
  2961.     if @procedure_name is null
  2962.     begin    /*    If procedure name not supplied, match all */
  2963.         select @procedure_name = '%'
  2964.     end
  2965.  
  2966.     /* first we need to extract the procedure group number, if one exists */
  2967.     select @semi_position = charindex(';',@procedure_name)
  2968.     if (@semi_position > 0)
  2969.     begin    /* If group number separator (;) found */
  2970.         select @group_num = convert(int,substring(@procedure_name, @semi_position + 1, 2))
  2971.         select @procedure_name = substring(@procedure_name, 1, @semi_position -1)
  2972.     end
  2973.     else
  2974.     begin    /* No group separator, so default to group number of 1 */
  2975.         select @group_num = 1
  2976.     end
  2977.  
  2978.     if @procedure_owner is null
  2979.     begin    /* If unqualified procedure name */
  2980.         SELECT @full_procedure_name = @procedure_name
  2981.     end
  2982.     else
  2983.     begin    /* Qualified procedure name */
  2984.         SELECT @full_procedure_name = @procedure_owner + '.' + @procedure_name
  2985.     end
  2986.  
  2987.     /*    Get Object ID */
  2988.     SELECT @procedure_id = object_id(@full_procedure_name)
  2989.     if ((charindex('%',@full_procedure_name) = 0) and
  2990.         (charindex('_',@full_procedure_name) = 0)  and
  2991.         @procedure_id <> 0)
  2992.     begin
  2993.         /* this block is for the case where there is no pattern
  2994.             matching required for the procedure name */
  2995.         SELECT
  2996.             PROCEDURE_QUALIFIER = convert(varchar(32),DB_NAME()),
  2997.             PROCEDURE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  2998.             PROCEDURE_NAME = convert(varchar(41),o.name +';'+ ltrim(str(c.number,5))),
  2999.             COLUMN_NAME = convert(varchar(32),c.name),
  3000.             COLUMN_TYPE = convert(smallint, 0),
  3001.             d.DATA_TYPE,
  3002.             TYPE_NAME = t.name,
  3003.             "PRECISION" = isnull(d.data_precision, convert(int,c.length)),
  3004.             LENGTH = isnull(d.length, convert(int,c.length)),
  3005.             SCALE = d.numeric_scale,
  3006.             d.RADIX,
  3007.             d.NULLABLE,
  3008.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  3009.             COLUMN_DEF = convert(varchar(254),null),
  3010.             d.SQL_DATETIME_SUB,
  3011.             CHAR_OCTET_LENGTH = isnull(d.data_precision, convert(int,c.length))+d.charbin,
  3012.             ORDINAL_POSITION = convert(int,c.colid),
  3013.             IS_NULLABLE = convert(varchar(254),rtrim(substring('NO YES',d.NULLABLE*3+1,3))),
  3014.             SS_DATA_TYPE = c.type
  3015.         FROM
  3016.             syscolumns c,
  3017.             sysobjects o,
  3018.             master.dbo.spt_datatype_info d,
  3019.             systypes t
  3020.         WHERE
  3021.             o.id = @procedure_id
  3022.             AND c.id = o.id
  3023.             AND t.type = d.ss_dtype
  3024.             AND c.length = isnull(d.fixlen, c.length)
  3025.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  3026.             AND c.usertype = t.usertype
  3027.             AND c.name like @column_name
  3028.             AND c.number = @group_num
  3029.         UNION ALL
  3030.         SELECT           /* return value row*/
  3031.             PROCEDURE_QUALIFIER = convert(varchar(32),DB_NAME()),
  3032.             PROCEDURE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  3033.             PROCEDURE_NAME = convert(varchar(41),o.name +';'+ isnull(ltrim(str(c.number,5)),'1')),
  3034.             COLUMN_NAME = convert(varchar(32),'RETURN_VALUE'),
  3035.             COLUMN_TYPE = convert(smallint, 5),
  3036.             DATA_TYPE = convert(smallint, 4),
  3037.             TYPE_NAME = convert(varchar(30),'int'),
  3038.             "PRECISION" = convert(int,10),
  3039.             LENGTH = convert(int,4),
  3040.             SCALE = convert(smallint,0),
  3041.             RADIX = convert(smallint,10),
  3042.             NULLABLE = convert(smallint,0),
  3043.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  3044.             COLUMN_DEF = convert(varchar(254),NULL),
  3045.             SQL_DATETIME_SUB = convert(smallint,null),
  3046.             CHAR_OCTET_LENGTH = convert(int,null),
  3047.             ORDINAL_POSITION = convert(int,0),
  3048.             IS_NULLABLE = convert(varchar(254),'NO'),
  3049.             SS_DATA_TYPE = convert(tinyint,56)
  3050.         FROM
  3051.             syscolumns c,
  3052.             sysobjects o
  3053.         WHERE
  3054.             o.id = @procedure_id
  3055.             AND c.id =* o.id
  3056.             AND c.colid = 1
  3057.             AND 'RETURN_VALUE' like @column_name
  3058.         ORDER BY 1, 2, 3, 17
  3059.     end
  3060.     else
  3061.     begin
  3062.         /* this block is for the case where there IS pattern
  3063.             matching done on the procedure name */
  3064.         if @procedure_owner is null
  3065.             select @procedure_owner = '%'
  3066.         SELECT
  3067.             PROCEDURE_QUALIFIER = convert(varchar(32),DB_NAME()),
  3068.             PROCEDURE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  3069.             PROCEDURE_NAME = convert(varchar(41),o.name +';'+ ltrim(str(c.number,5))),
  3070.             COLUMN_NAME = convert(varchar(32),c.name),
  3071.             COLUMN_TYPE = convert(smallint, 0),
  3072.             d.DATA_TYPE,
  3073.             TYPE_NAME = t.name,
  3074.             "PRECISION" = isnull(d.data_precision, convert(int,c.length)),
  3075.             LENGTH = isnull(d.length, convert(int,c.length)),
  3076.             SCALE = d.numeric_scale,
  3077.             d.RADIX,
  3078.             d.NULLABLE,
  3079.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  3080.             COLUMN_DEF = convert(varchar(254),null),
  3081.             d.SQL_DATETIME_SUB,
  3082.             CHAR_OCTET_LENGTH = isnull(d.data_precision, convert(int,c.length))+d.charbin,
  3083.             ORDINAL_POSITION = convert(int,c.colid),
  3084.             IS_NULLABLE = convert(varchar(254),rtrim(substring('NO YES',d.NULLABLE*3+1,3))),
  3085.             SS_DATA_TYPE = c.type
  3086.         FROM
  3087.             syscolumns c,
  3088.             sysobjects o,
  3089.             master.dbo.spt_datatype_info d,
  3090.             systypes t
  3091.         WHERE
  3092.             o.name like @procedure_name
  3093.             AND user_name(o.uid) like @procedure_owner
  3094.             AND o.id = c.id
  3095.             AND t.type = d.ss_dtype
  3096.             AND c.length = isnull(d.fixlen, c.length)
  3097.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  3098.             AND c.usertype = t.usertype
  3099.             AND o.type = 'P'                            /* Just Procedures */
  3100.             AND c.name like @column_name
  3101.         UNION ALL
  3102.         SELECT           /* return value row*/
  3103.             PROCEDURE_QUALIFIER = convert(varchar(32),DB_NAME()),
  3104.             PROCEDURE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  3105.             PROCEDURE_NAME = convert(varchar(41),o.name +';'+ isnull(ltrim(str(c.number,5)),'1')),
  3106.             COLUMN_NAME = convert(varchar(32),'RETURN_VALUE'),
  3107.             COLUMN_TYPE = convert(smallint, 5),
  3108.             DATA_TYPE = convert(smallint, 4),
  3109.             TYPE_NAME = convert(varchar(30),'int'),
  3110.             "PRECISION" = convert(int,10),
  3111.             LENGTH = convert(int,4),
  3112.             SCALE = convert(smallint,0),
  3113.             RADIX = convert(smallint,10),
  3114.             NULLABLE = convert(smallint,0),
  3115.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  3116.             COLUMN_DEF = convert(varchar(254),NULL),
  3117.             SQL_DATETIME_SUB = convert(smallint,null),
  3118.             CHAR_OCTET_LENGTH = convert(int,null),
  3119.             ORDINAL_POSITION = convert(int,0),
  3120.             IS_NULLABLE = convert(varchar(254),'NO'),
  3121.             SS_DATA_TYPE = convert(tinyint,56)
  3122.         FROM
  3123.             syscolumns c,
  3124.             sysobjects o
  3125.         WHERE
  3126.             o.name like @procedure_name
  3127.             AND user_name(o.uid) like @procedure_owner
  3128.             AND c.id =* o.id
  3129.             AND c.colid = 1
  3130.             AND o.type = 'P'                        /* Just Procedures */
  3131.             AND 'RETURN_VALUE' like @column_name
  3132.         ORDER BY 1, 2, 3, 17
  3133.     end
  3134. go
  3135.  
  3136. if    (charindex('6.00', @@version) = 0 and
  3137.      charindex('6.50', @@version) = 0)
  3138. begin
  3139.     print ''
  3140.     print ''
  3141.     print 'Warning:'
  3142.     print 'you are installing the stored procedures '
  3143.     print 'on a pre 6.0 SQL Server.'
  3144.     print 'Ignore the following error.'
  3145. end
  3146. else
  3147.     drop proc sp_sproc_columns
  3148. go
  3149.  
  3150. /*    Procedure for 6.0 server */
  3151. CREATE PROCEDURE sp_sproc_columns (
  3152.                  @procedure_name        varchar(96) = '%',
  3153.                  @procedure_owner        varchar(90) = null,
  3154.                  @procedure_qualifier    varchar(32) = null,
  3155.                  @column_name            varchar(90) = null,
  3156.                  @ODBCVer                int = 2)
  3157. AS
  3158.     DECLARE @group_num int
  3159.     DECLARE @semi_position int
  3160.     DECLARE @full_procedure_name    char(187)
  3161.     DECLARE @procedure_id int
  3162.  
  3163.     if @column_name is null /*    If column name not supplied, match all */
  3164.         select @column_name = '%'
  3165.     if @procedure_qualifier is not null
  3166.     begin
  3167.         if db_name() <> @procedure_qualifier
  3168.         begin
  3169.             if @procedure_qualifier = ''
  3170.             begin
  3171.                 /* in this case, we need to return an empty result set */
  3172.                 /* because the user has requested a database with an empty name */
  3173.                 select @procedure_name = ''
  3174.                 select @procedure_owner = ''
  3175.             end
  3176.             else
  3177.             begin    /* If qualifier doesn't match current database */
  3178.                 raiserror (15250, -1,-1,'Procedure')
  3179.                 return
  3180.             end
  3181.         end
  3182.     end
  3183.  
  3184.     if @procedure_name is null
  3185.     begin    /*    If procedure name not supplied, match all */
  3186.         select @procedure_name = '%'
  3187.     end
  3188.  
  3189.     /* first we need to extract the procedure group number, if one exists */
  3190.     select @semi_position = charindex(';',@procedure_name)
  3191.     if (@semi_position > 0)
  3192.     begin    /* If group number separator (;) found */
  3193.         select @group_num = convert(int,substring(@procedure_name, @semi_position + 1, 2))
  3194.         select @procedure_name = substring(@procedure_name, 1, @semi_position -1)
  3195.     end
  3196.     else
  3197.     begin    /* No group separator, so default to group number of 1 */
  3198.         select @group_num = 1
  3199.     end
  3200.  
  3201.     if @procedure_owner is null
  3202.     begin    /* If unqualified procedure name */
  3203.         SELECT @full_procedure_name = @procedure_name
  3204.     end
  3205.     else
  3206.     begin    /* Qualified procedure name */
  3207.         SELECT @full_procedure_name = @procedure_owner + '.' + @procedure_name
  3208.     end
  3209.  
  3210.     /*    Get Object ID */
  3211.     SELECT @procedure_id = object_id(@full_procedure_name)
  3212.     if ((charindex('%',@full_procedure_name) = 0) and
  3213.         (charindex('_',@full_procedure_name) = 0)  and
  3214.         @procedure_id <> 0)
  3215.     begin
  3216.         /* this block is for the case where there is no pattern
  3217.             matching required for the procedure name */
  3218.         SELECT
  3219.             PROCEDURE_QUALIFIER = convert(varchar(32),DB_NAME()),
  3220.             PROCEDURE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  3221.             PROCEDURE_NAME = convert(varchar(41),o.name +';'+ ltrim(str(c.number,5))),
  3222.             COLUMN_NAME = convert(varchar(32),c.name),
  3223.             COLUMN_TYPE = convert(smallint, 1+((c.status/64)&1)),
  3224.             d.DATA_TYPE,
  3225.             TYPE_NAME = t.name,
  3226.             case
  3227.                 when d.DATA_TYPE in (6,7) then d.data_precision         /* FLOAT/REAL */
  3228.                 else isnull(convert(int,c.prec), 2147483647)
  3229.             end "PRECISION",
  3230.             case
  3231.                 when d.ss_dtype IN (106, 108, 55, 63) then    /* decimal/numeric types */
  3232.                     convert(int,c.prec+2)
  3233.                 else
  3234.                     isnull(d.length, convert(int,c.length))
  3235.             end LENGTH,
  3236.             SCALE = convert(smallint, c.scale),
  3237.             d.RADIX,
  3238.             d.NULLABLE,
  3239.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  3240.             COLUMN_DEF = convert(varchar(254),NULL),
  3241.             d.SQL_DATETIME_SUB,
  3242.             CHAR_OCTET_LENGTH = isnull(convert(int,c.prec), 2147483647)+d.charbin,
  3243.             ORDINAL_POSITION = convert(int,c.colid),
  3244.             IS_NULLABLE = convert(varchar(254),rtrim(substring('NO YES',d.NULLABLE*3+1,3))),
  3245.             SS_DATA_TYPE = c.type
  3246.         FROM
  3247.             syscolumns c,
  3248.             sysobjects o,
  3249.             master.dbo.spt_datatype_info d,
  3250.             systypes t
  3251.         WHERE
  3252.             o.id = @procedure_id
  3253.             AND c.id = o.id
  3254.             AND c.type = d.ss_dtype
  3255.             AND c.length = isnull(d.fixlen, c.length)
  3256.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  3257.             AND isnull(d.AUTO_INCREMENT,0) = 0
  3258.             AND c.usertype *= t.usertype
  3259.             AND c.name like @column_name
  3260.             AND c.number = @group_num
  3261.         UNION ALL
  3262.         SELECT           /* return value row*/
  3263.             PROCEDURE_QUALIFIER = convert(varchar(32),DB_NAME()),
  3264.             PROCEDURE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  3265.             PROCEDURE_NAME = convert(varchar(41),o.name +';'+ isnull(ltrim(str(c.number,5)),'1')),
  3266.             COLUMN_NAME = convert(varchar(32),'RETURN_VALUE'),
  3267.             COLUMN_TYPE = convert(smallint, 5),
  3268.             DATA_TYPE = convert(smallint, 4),
  3269.             TYPE_NAME = convert(varchar(30),'int'),
  3270.             "PRECISION" = convert(int,10),
  3271.             LENGTH = convert(int,4),
  3272.             SCALE = convert(smallint,0),
  3273.             RADIX = convert(smallint,10),
  3274.             NULLABLE = convert(smallint,0),
  3275.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  3276.             COLUMN_DEF = convert(varchar(254),NULL),
  3277.             SQL_DATETIME_SUB = convert(smallint,null),
  3278.             CHAR_OCTET_LENGTH = convert(int,null),
  3279.             ORDINAL_POSITION = convert(int,0),
  3280.             IS_NULLABLE = convert(varchar(254),'NO'),
  3281.             SS_DATA_TYPE = convert(tinyint,56)
  3282.         FROM
  3283.             syscolumns c,
  3284.             sysobjects o
  3285.         WHERE
  3286.             o.id = @procedure_id
  3287.             AND c.id =* o.id
  3288.             AND c.colid = 1
  3289.             AND 'RETURN_VALUE' like @column_name
  3290.         ORDER BY 1, 2, 3, 17
  3291.     end
  3292.     else
  3293.     begin
  3294.         /* this block is for the case where there IS pattern
  3295.             matching done on the procedure name */
  3296.         if @procedure_owner is null
  3297.             select @procedure_owner = '%'
  3298.         SELECT
  3299.             PROCEDURE_QUALIFIER = convert(varchar(32),DB_NAME()),
  3300.             PROCEDURE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  3301.             PROCEDURE_NAME = convert(varchar(41),o.name +';'+ ltrim(str(c.number,5))),
  3302.             COLUMN_NAME = convert(varchar(32),c.name),
  3303.             COLUMN_TYPE = convert(smallint, 1+((c.status/64)&1)),
  3304.             d.DATA_TYPE,
  3305.             TYPE_NAME = t.name,
  3306.             case
  3307.                 when d.DATA_TYPE in (6,7) then d.data_precision         /* FLOAT/REAL */
  3308.                 else isnull(convert(int,c.prec), 2147483647)
  3309.             end "PRECISION",
  3310.             case
  3311.                 when d.ss_dtype IN (106, 108, 55, 63) then    /* decimal/numeric types */
  3312.                     convert(int,c.prec+2)
  3313.                 else
  3314.                     isnull(d.length, convert(int,c.length))
  3315.             end LENGTH,
  3316.             SCALE = convert(smallint, c.scale),
  3317.             d.RADIX,
  3318.             d.NULLABLE,
  3319.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  3320.             COLUMN_DEF = convert(varchar(254),NULL),
  3321.             d.SQL_DATETIME_SUB,
  3322.             CHAR_OCTET_LENGTH = isnull(convert(int,c.prec), 2147483647)+d.charbin,
  3323.             ORDINAL_POSITION = convert(int,c.colid),
  3324.             IS_NULLABLE = convert(varchar(254),rtrim(substring('NO YES',d.NULLABLE*3+1,3))),
  3325.             SS_DATA_TYPE = c.type
  3326.         FROM
  3327.             syscolumns c,
  3328.             sysobjects o,
  3329.             master.dbo.spt_datatype_info d,
  3330.             systypes t
  3331.         WHERE
  3332.             o.name like @procedure_name
  3333.             AND user_name(o.uid) like @procedure_owner
  3334.             AND o.id = c.id
  3335.             AND c.type = d.ss_dtype
  3336.             AND c.length = isnull(d.fixlen, c.length)
  3337.             AND (d.ODBCVer is null or d.ODBCVer = @ODBCVer)
  3338.             AND isnull(d.AUTO_INCREMENT,0) = 0
  3339.             AND c.usertype *= t.usertype
  3340.             AND o.type = 'P'                            /* Just Procedures */
  3341.             AND c.name like @column_name
  3342.         UNION ALL
  3343.         SELECT           /* return value row*/
  3344.             PROCEDURE_QUALIFIER = convert(varchar(32),DB_NAME()),
  3345.             PROCEDURE_OWNER = convert(varchar(32),USER_NAME(o.uid)),
  3346.             PROCEDURE_NAME = convert(varchar(41),o.name +';'+ isnull(ltrim(str(c.number,5)),'1')),
  3347.             COLUMN_NAME = convert(varchar(32),'RETURN_VALUE'),
  3348.             COLUMN_TYPE = convert(smallint, 5),
  3349.             DATA_TYPE = convert(smallint, 4),
  3350.             TYPE_NAME = convert(varchar(30),'int'),
  3351.             "PRECISION" = convert(int,10),
  3352.             LENGTH = convert(int,4),
  3353.             SCALE = convert(smallint,0),
  3354.             RADIX = convert(smallint,10),
  3355.             NULLABLE = convert(smallint,0),
  3356.             REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  3357.             COLUMN_DEF = convert(varchar(254),NULL),
  3358.             SQL_DATETIME_SUB = convert(smallint,null),
  3359.             CHAR_OCTET_LENGTH = convert(int,null),
  3360.             ORDINAL_POSITION = convert(int,0),
  3361.             IS_NULLABLE = convert(varchar(254),'NO'),
  3362.             SS_DATA_TYPE = convert(tinyint,56)
  3363.         FROM
  3364.             syscolumns c,
  3365.             sysobjects o
  3366.         WHERE
  3367.             o.name like @procedure_name
  3368.             AND user_name(o.uid) like @procedure_owner
  3369.             AND c.id =* o.id
  3370.             AND c.colid = 1
  3371.             AND o.type = 'P'                        /* Just Procedures */
  3372.             AND 'RETURN_VALUE' like @column_name
  3373.         ORDER BY 1, 2, 3, 17
  3374.     end
  3375. go
  3376.  
  3377. grant execute on sp_sproc_columns to public
  3378. go
  3379.  
  3380. dump tran master with no_log
  3381. go
  3382.  
  3383. print 'creating sp_statistics'
  3384. go
  3385.  
  3386. CREATE PROCEDURE sp_statistics (
  3387.                  @table_name        varchar(32),
  3388.                  @table_owner        varchar(32) = null,
  3389.                  @table_qualifier    varchar(32) = null,
  3390.                  @index_name        varchar(32) = '%',
  3391.                  @is_unique         char(1) = 'N',
  3392.                  @accuracy            char(1) = 'Q')
  3393. AS
  3394.     DECLARE @indid                int
  3395.     DECLARE @lastindid            int
  3396.     DECLARE @table_id            int
  3397.     DECLARE @full_table_name    char(70)
  3398.  
  3399.     if @table_qualifier is not null
  3400.     begin
  3401.         if db_name() <> @table_qualifier
  3402.         begin    /* If qualifier doesn't match current database */
  3403.             raiserror 20001 'Table qualifier must be name of current database'
  3404.             return
  3405.         end
  3406.     end
  3407.  
  3408.     if @accuracy not in ('Q','E')
  3409.         begin
  3410.             raiserror 20002 'Illegal ''accuracy'' specified -- must be ''Q'' or ''E''.'
  3411.             return
  3412.         end
  3413.  
  3414.     if (@@trancount <> 0 and charindex('6.50', @@version) = 0)
  3415.     begin    /* If inside a transaction */
  3416.         raiserror 20003 'The procedure ''sp_statistics'' cannot be executed from within a transaction.'
  3417.         return
  3418.     end
  3419.     create table #TmpIndex(
  3420.         TABLE_QUALIFIER varchar(32) NULL,
  3421.         TABLE_OWNER     varchar(32) NULL,
  3422.         TABLE_NAME        varchar(32) NOT NULL,
  3423.         INDEX_QUALIFIER varchar(32) null,
  3424.         INDEX_NAME        varchar(32) null,
  3425.         NON_UNIQUE        smallint null,
  3426.         TYPE            smallint NOT NULL,
  3427.         SEQ_IN_INDEX    smallint null,
  3428.         COLUMN_NAME     varchar(32) null,
  3429.         COLLATION        char(1) null,
  3430.         index_id        int null,
  3431.         CARDINALITY     int null,
  3432.         PAGES            int null,
  3433.         status            smallint NOT NULL)
  3434.     if @table_owner is null
  3435.     begin    /* If unqualified table name */
  3436.         SELECT @full_table_name = @table_name
  3437.     end
  3438.     else
  3439.     begin    /* Qualified table name */
  3440.         SELECT @full_table_name = @table_owner + '.' + @table_name
  3441.     end
  3442.     /*    Get Object ID */
  3443.     SELECT @table_id = object_id(@full_table_name)
  3444.  
  3445.     /*    Start at lowest index id */
  3446.     SELECT @indid = min(indid)
  3447.     FROM sysindexes
  3448.     WHERE id = @table_id
  3449.         AND indid > 0
  3450.         AND indid < 255
  3451.  
  3452.     WHILE @indid <> NULL
  3453.     BEGIN
  3454.         INSERT #TmpIndex    /* Add all columns that are in index */
  3455.             SELECT
  3456.                 DB_NAME(),                                /* TABLE_QUALIFIER */
  3457.                 USER_NAME(o.uid),                        /* TABLE_OWNER       */
  3458.                 o.name,                                 /* TABLE_NAME       */
  3459.                 o.name,                                 /* INDEX_QUALIFIER */
  3460.                 x.name,                                 /* INDEX_NAME       */
  3461.                 0,                                        /* NON_UNIQUE       */
  3462.                 1,                                        /* SQL_INDEX_CLUSTERED */
  3463.                 colid,                                    /* SEQ_IN_INDEX    */
  3464.                 INDEX_COL(@full_table_name,indid,colid),/* COLUMN_NAME       */
  3465.                 'A',                                    /* COLLATION       */
  3466.                 @indid,                                 /* index_id        */
  3467.                 x.rows,                                 /* CARDINALITY       */
  3468.                 x.dpages,                                /* PAGES           */
  3469.                 x.status                                /* status            */
  3470.             FROM sysindexes x, syscolumns c, sysobjects o
  3471.             WHERE
  3472.                 x.id = @table_id
  3473.                 AND x.id = o.id
  3474.                 AND x.id = c.id
  3475.                 AND c.colid < keycnt+(x.status&16)/16
  3476.                 AND x.indid = @indid
  3477.         /*
  3478.         **      Now move @indid to the next index.
  3479.         */
  3480.         SELECT @lastindid = @indid
  3481.         SELECT @indid = NULL
  3482.  
  3483.         SELECT @indid = min(indid)
  3484.         FROM sysindexes
  3485.         WHERE id = @table_id
  3486.             AND indid > @lastindid
  3487.             AND indid < 255
  3488.     END
  3489.  
  3490.     UPDATE #TmpIndex
  3491.         SET NON_UNIQUE = 1
  3492.         WHERE status&2 <> 2 /* If non-unique index */
  3493.     UPDATE #TmpIndex
  3494.         SET
  3495.             TYPE = 3,            /* SQL_INDEX_OTHER */
  3496.             CARDINALITY = NULL,
  3497.             PAGES = NULL
  3498.         WHERE index_id > 1    /* If non-clustered index */
  3499.  
  3500.     /* now add row for table statistics */
  3501.     INSERT #TmpIndex
  3502.         SELECT
  3503.             DB_NAME(),                /* TABLE_QUALIFIER */
  3504.             USER_NAME(o.uid),        /* TABLE_OWNER       */
  3505.             o.name,                 /* TABLE_NAME       */
  3506.             null,                    /* INDEX_QUALIFIER */
  3507.             null,                    /* INDEX_NAME       */
  3508.             null,                    /* NON_UNIQUE       */
  3509.             0,                        /* SQL_TABLE_STAT  */
  3510.             null,                    /* SEQ_IN_INDEX    */
  3511.             null,                    /* COLUMN_NAME       */
  3512.             null,                    /* COLLATION       */
  3513.             0,                        /* index_id        */
  3514.             x.rows,                 /* CARDINALITY       */
  3515.             x.dpages,                /* PAGES           */
  3516.             0                        /* status           */
  3517.         FROM sysindexes x, sysobjects o
  3518.         WHERE o.id = @table_id
  3519.             AND x.id = o.id
  3520.             AND (x.indid = 0 or x.indid = 1)    /*    If there are no indexes */
  3521.                                                 /*    then table stats are in */
  3522.                                                 /*    a row with indid =0        */
  3523.  
  3524.     if @is_unique <> 'Y'    /* If all indexes desired */
  3525.         SELECT
  3526.             TABLE_QUALIFIER,
  3527.             TABLE_OWNER,
  3528.             TABLE_NAME,
  3529.             NON_UNIQUE,
  3530.             INDEX_QUALIFIER,
  3531.             INDEX_NAME,
  3532.             TYPE,
  3533.             SEQ_IN_INDEX,
  3534.             COLUMN_NAME,
  3535.             COLLATION,
  3536.             CARDINALITY,
  3537.             PAGES,
  3538.             FILTER_CONDITION = convert(varchar(128),null)
  3539.         FROM #TmpIndex
  3540.         WHERE
  3541.             INDEX_NAME like @index_name /* If matching name */
  3542.             or INDEX_NAME is null        /* If SQL_TABLE_STAT row */
  3543.         ORDER BY 4, 7, 6, 8
  3544.     else                    /* If only unique indexes desired */
  3545.         SELECT
  3546.             TABLE_QUALIFIER,
  3547.             TABLE_OWNER,
  3548.             TABLE_NAME,
  3549.             NON_UNIQUE,
  3550.             INDEX_QUALIFIER,
  3551.             INDEX_NAME,
  3552.             TYPE,
  3553.             SEQ_IN_INDEX,
  3554.             COLUMN_NAME,
  3555.             COLLATION,
  3556.             CARDINALITY,
  3557.             PAGES,
  3558.             FILTER_CONDITION = convert(varchar(128),null)
  3559.         FROM #TmpIndex
  3560.         WHERE
  3561.             (NON_UNIQUE = 0             /* If unique */
  3562.                 or NON_UNIQUE is NULL)    /* If SQL_TABLE_STAT row */
  3563.             and (INDEX_NAME like @index_name    /* If matching name */
  3564.                 or INDEX_NAME is null)    /* If SQL_TABLE_STAT row */
  3565.         ORDER BY 4, 7, 6, 8
  3566.  
  3567.     DROP TABLE #TmpIndex
  3568. go
  3569.  
  3570. grant execute on sp_statistics to public
  3571. go
  3572.  
  3573. dump tran master with no_log
  3574. go
  3575.  
  3576. print 'creating sp_stored_procedures'
  3577. go
  3578.  
  3579. create procedure sp_stored_procedures(
  3580.                         @sp_name        varchar(96) = null,
  3581.                         @sp_owner        varchar(90) = null,
  3582.                         @sp_qualifier    varchar(32) = null)
  3583. as
  3584.     declare @proc_type smallint
  3585.  
  3586.     if @sp_qualifier is not null
  3587.     begin
  3588.         if db_name() <> @sp_qualifier
  3589.         begin
  3590.             if @sp_qualifier = ''
  3591.             begin
  3592.                 /* in this case, we need to return an empty result set */
  3593.                 /* because the user has requested a database with an empty name */
  3594.                 select @sp_name = ''
  3595.                 select @sp_owner = ''
  3596.             end else
  3597.             begin    /* If qualifier doesn't match current database */
  3598.                 raiserror 20001 'Procedure qualifier must be name of current database'
  3599.                 return
  3600.             end
  3601.         end
  3602.     end
  3603.  
  3604.     if @sp_name is null
  3605.     begin  /*  If procedure name not supplied, match all */
  3606.         select @sp_name = '%'
  3607.     end
  3608.     else begin
  3609.         if (@sp_owner is null) and (charindex('%', @sp_name) = 0)
  3610.         begin
  3611.             if exists (select * from sysobjects
  3612.                 where uid = user_id()
  3613.                     and name = @sp_name
  3614.                     and type = 'P') /* Object type of Procedure */
  3615.             begin
  3616.                 select @sp_owner = user_name()
  3617.             end
  3618.         end
  3619.     end
  3620.     if @sp_owner is null    /*    If procedure owner not supplied, match all */
  3621.         select @sp_owner = '%'
  3622.  
  3623.     select @proc_type=2        /* Return 2 for 4.2 and later servers. */
  3624.  
  3625.     select
  3626.         PROCEDURE_QUALIFIER = convert(varchar(32),db_name()),
  3627.         PROCEDURE_OWNER = convert(varchar(32),user_name(o.uid)),
  3628.         PROCEDURE_NAME = convert(varchar(41),o.name +';'+ ltrim(str(p.number,5))),
  3629.         NUM_INPUT_PARAMS = -1,    /* Constant since value unknown */
  3630.         NUM_OUTPUT_PARAMS = -1, /* Constant since value unknown */
  3631.         NUM_RESULT_SETS = -1,    /* Constant since value unknown */
  3632.         REMARKS = convert(varchar(254),null),    /* Remarks are NULL */
  3633.         PROCEDURE_TYPE = @proc_type
  3634.     from
  3635.         sysobjects o,sysprocedures p,sysusers u
  3636.     where
  3637.         o.name like @sp_name
  3638.         and p.sequence = 0
  3639.         and user_name(o.uid) like @sp_owner
  3640.         and o.type = 'P'        /* Object type of Procedure */
  3641.         and p.id = o.id
  3642.         and u.uid = user_id()    /* constrain sysusers uid for use in subquery */
  3643.         and (suser_id() = 1     /* User is the System Administrator */
  3644.             or o.uid = user_id()    /* User created the object */
  3645.             /* here's the magic... select the highest precedence of permissions in the order (user,group,public)  */
  3646.             or ((select max(((sign(uid)*abs(uid-16383))*2)+(protecttype&1))
  3647.              from sysprotects p
  3648.              /* outer join to correlate with all rows in sysobjects */
  3649.              where p.id =* o.id
  3650.                  /*  get rows for public,current user,user's group */
  3651.                  and (p.uid = 0 or p.uid = user_id() or p.uid =* u.gid)
  3652.                  /* check for SELECT,EXECUTE privilege */
  3653.                  and (action in (193,224)))&1    /* more magic...normalize GRANT */
  3654.             ) = 1     /* final magic...compare Grants    */
  3655.         )
  3656.     order by 1, 2, 3
  3657. go
  3658. grant execute on sp_stored_procedures to public
  3659. go
  3660.  
  3661. dump tran master with no_log
  3662. go
  3663.  
  3664.  
  3665. print 'creating sp_table_privileges'
  3666. go
  3667.  
  3668. /*    Procedure for pre 6.50 server */
  3669. CREATE PROCEDURE sp_table_privileges (
  3670.             @table_name         varchar(90),
  3671.             @table_owner        varchar(90) = null,
  3672.             @table_qualifier    varchar(32) = null)
  3673. as
  3674.  
  3675.     if @table_qualifier is not null
  3676.     begin
  3677.         if db_name() <> @table_qualifier
  3678.         begin    /* If qualifier doesn't match current database */
  3679.             raiserror 20001 'Table qualifier must be name of current database'
  3680.             return
  3681.         end
  3682.     end
  3683.     if (@@trancount <> 0)
  3684.     begin    /* If inside a transaction */
  3685.         raiserror 20003 'The procedure ''sp_table_privileges'' cannot be executed from within a transaction.'
  3686.         return
  3687.     end
  3688.     if @table_name is null
  3689.         select @table_name = '%'
  3690.     if @table_owner is null /* If no owner supplied, force wildcard */
  3691.         select @table_owner = '%'
  3692.  
  3693.     create table #table_priv1(
  3694.         id                        int NOT NULL,
  3695.         grantor                 smallint NOT NULL,
  3696.         grantee                 smallint NOT NULL,
  3697.         select_privilege        bit,
  3698.         insert_privilege        bit,
  3699.         update_privilege        bit,
  3700.         delete_privilege        bit,
  3701.         references_privilege    bit,
  3702.         select_privilege_grant    bit,
  3703.         insert_privilege_grant    bit,
  3704.         update_privilege_grant    bit,
  3705.         delete_privilege_grant    bit,
  3706.         references_privilege_grant    bit,
  3707.         uid                     smallint NOT NULL,
  3708.         gid                     smallint NOT NULL)
  3709.  
  3710.     insert into #table_priv1
  3711.         select distinct
  3712.             o.id,
  3713.             o.uid,
  3714.             u.uid,
  3715.             0,
  3716.             0,
  3717.             0,
  3718.             0,
  3719.             0,
  3720.             0,
  3721.             0,
  3722.             0,
  3723.             0,
  3724.             0,
  3725.             u.uid,
  3726.             u.gid
  3727.         from sysusers u, sysobjects o, sysprotects p
  3728.         where
  3729.             o.name like @table_name
  3730.             and user_name(o.uid) like @table_owner
  3731.             and u.uid <> u.gid
  3732.             and u.uid *= p.uid and o.id *= p.id
  3733.             and p.protecttype in (204, 205)
  3734.             and sysstat & 0xf in (1,2,3)    /* only valid for system tables,
  3735.                                             ** user tables, and views. */
  3736.  
  3737.     /*
  3738.     ** now add/update row for table owner
  3739.     */
  3740.     if exists (
  3741.         select *
  3742.             from #table_priv1
  3743.             where grantor = grantee)
  3744.     begin
  3745.         update #table_priv1
  3746.         set
  3747.             select_privilege_grant = 1,
  3748.             update_privilege_grant = 1,
  3749.             insert_privilege_grant = 1,
  3750.             delete_privilege_grant = 1,
  3751.             references_privilege_grant = 1,
  3752.             grantor = (select uid from sysusers where suid = 1)
  3753.         where grantor = grantee
  3754.     end
  3755.     else
  3756.     begin
  3757.         insert into #table_priv1
  3758.             select
  3759.                 o.id,
  3760.                 u1.uid,
  3761.                 o.uid,
  3762.                 0,
  3763.                 0,
  3764.                 0,
  3765.                 0,
  3766.                 0,
  3767.                 1,
  3768.                 1,
  3769.                 1,
  3770.                 1,
  3771.                 1,
  3772.                 o.uid,
  3773.                 u.gid
  3774.             from sysobjects o, sysusers u, sysusers u1
  3775.             where o.name like @table_name
  3776.             and user_name(o.uid) like @table_owner
  3777.             and u.uid = o.uid
  3778.             and sysstat & 0xf in (1,2,3)    /* only valid for system tables,
  3779.                                            ** user tables, and views. */
  3780.             and u1.suid = 1        /* grantor is dbo of database */
  3781.  
  3782.     end
  3783.  
  3784.     update #table_priv1
  3785.     set select_privilege = 1
  3786.         from sysprotects p
  3787.     where
  3788.         #table_priv1.id = p.id
  3789.         and (#table_priv1.uid = p.uid
  3790.             or #table_priv1.gid = p.uid
  3791.             or p.uid = 0)
  3792.         and protecttype = 205
  3793.         and action = 193
  3794.         and not exists (
  3795.             select * from sysprotects
  3796.             where
  3797.                 #table_priv1.id = sysprotects.id
  3798.                 and (#table_priv1.uid = uid
  3799.                     or #table_priv1.gid = uid
  3800.                     or uid = 0)
  3801.                 and protecttype = 206
  3802.                 and action = 193)
  3803.  
  3804.     update #table_priv1
  3805.     set insert_privilege = 1
  3806.         from sysprotects p
  3807.     where
  3808.         #table_priv1.id = p.id
  3809.         and (#table_priv1.uid = p.uid
  3810.             or #table_priv1.gid = p.uid
  3811.             or p.uid = 0)
  3812.         and protecttype = 205
  3813.         and action = 195
  3814.         and not exists (
  3815.             select * from sysprotects
  3816.             where
  3817.                 #table_priv1.id = sysprotects.id
  3818.                 and (#table_priv1.uid = uid
  3819.                     or #table_priv1.gid = uid
  3820.                     or uid = 0)
  3821.                 and protecttype = 206
  3822.                 and action = 195)
  3823.  
  3824.     update #table_priv1
  3825.     set delete_privilege = 1
  3826.         from sysprotects p
  3827.     where
  3828.         exists (
  3829.             select * from sysprotects
  3830.             where
  3831.                 #table_priv1.id = sysprotects.id
  3832.                 and (#table_priv1.uid = uid
  3833.                     or #table_priv1.gid = uid
  3834.                     or uid = 0)
  3835.                 and protecttype = 205
  3836.                 and action = 196)
  3837.         and not exists (select * from sysprotects
  3838.             where
  3839.                 #table_priv1.id = sysprotects.id
  3840.                 and (#table_priv1.uid = uid
  3841.                     or #table_priv1.gid = uid
  3842.                     or uid = 0)
  3843.                 and protecttype = 206
  3844.                 and action = 196)
  3845.  
  3846.     update #table_priv1
  3847.     set update_privilege = 1
  3848.         from sysprotects p
  3849.     where
  3850.         #table_priv1.id = p.id
  3851.         and (#table_priv1.uid = p.uid
  3852.             or #table_priv1.gid = p.uid
  3853.             or p.uid = 0)
  3854.         and protecttype = 205
  3855.         and action = 197
  3856.         and not exists (
  3857.             select * from sysprotects
  3858.             where
  3859.                 #table_priv1.id = sysprotects.id
  3860.                 and (#table_priv1.uid = uid
  3861.                     or #table_priv1.gid = uid
  3862.                     or uid = 0)
  3863.                 and protecttype = 206
  3864.                 and action = 197)
  3865.  
  3866.     update #table_priv1
  3867.     set references_privilege = 1
  3868.         from sysprotects p
  3869.     where
  3870.         #table_priv1.id = p.id
  3871.         and (#table_priv1.uid = p.uid
  3872.             or #table_priv1.gid = p.uid
  3873.             or p.uid = 0)
  3874.         and protecttype = 205
  3875.         and action = 26
  3876.         and not exists (
  3877.             select * from sysprotects
  3878.             where
  3879.                 #table_priv1.id = sysprotects.id
  3880.                 and (#table_priv1.uid = uid
  3881.                     or #table_priv1.gid = uid
  3882.                     or uid = 0)
  3883.                 and protecttype = 206
  3884.                 and action = 26)
  3885.  
  3886.     create table #table_priv2(
  3887.         id                int NOT NULL,
  3888.         grantor         smallint NOT NULL,
  3889.         grantee         smallint NOT NULL,
  3890.         PRIVILEGE        varchar(32) NOT NULL,
  3891.         IS_GRANTABLE    varchar(3) NULL)
  3892.  
  3893.     insert into #table_priv2
  3894.         select
  3895.             id,
  3896.             grantor,
  3897.             grantee,
  3898.             'SELECT',
  3899.             'NO'
  3900.         from #table_priv1
  3901.         where select_privilege = 1 and select_privilege_grant = 0
  3902.  
  3903.     insert into #table_priv2
  3904.         select
  3905.             id,
  3906.             grantor,
  3907.             grantee,
  3908.             'INSERT',
  3909.             'NO'
  3910.         from #table_priv1
  3911.         where insert_privilege = 1 and insert_privilege_grant = 0
  3912.  
  3913.     insert into #table_priv2
  3914.         select
  3915.             id,
  3916.             grantor,
  3917.             grantee,
  3918.             'DELETE',
  3919.             'NO'
  3920.         from #table_priv1
  3921.         where delete_privilege = 1 and delete_privilege_grant = 0
  3922.  
  3923.     insert into #table_priv2
  3924.         select
  3925.             id,
  3926.             grantor,
  3927.             grantee,
  3928.             'UPDATE',
  3929.             'NO'
  3930.         from #table_priv1
  3931.         where update_privilege = 1 and update_privilege_grant = 0
  3932.  
  3933.     insert into #table_priv2
  3934.         select
  3935.             id,
  3936.             grantor,
  3937.             grantee,
  3938.             'REFERENCES',
  3939.             'NO'
  3940.         from #table_priv1
  3941.         where references_privilege = 1 and references_privilege_grant = 0
  3942.  
  3943.     insert into #table_priv2
  3944.         select
  3945.             id,
  3946.             grantor,
  3947.             grantee,
  3948.             'SELECT',
  3949.             'YES'
  3950.         from #table_priv1
  3951.         where select_privilege_grant = 1
  3952.  
  3953.     insert into #table_priv2
  3954.         select
  3955.             id,
  3956.             grantor,
  3957.             grantee,
  3958.             'INSERT',
  3959.             'YES'
  3960.         from #table_priv1
  3961.         where insert_privilege_grant = 1
  3962.  
  3963.     insert into #table_priv2
  3964.         select
  3965.             id,
  3966.             grantor,
  3967.             grantee,
  3968.             'DELETE',
  3969.             'YES'
  3970.         from #table_priv1
  3971.         where delete_privilege_grant = 1
  3972.  
  3973.     insert into #table_priv2
  3974.         select
  3975.             id,
  3976.             grantor,
  3977.             grantee,
  3978.             'UPDATE',
  3979.             'YES'
  3980.         from #table_priv1
  3981.         where update_privilege_grant = 1
  3982.  
  3983.     insert into #table_priv2
  3984.         select
  3985.             id,
  3986.             grantor,
  3987.             grantee,
  3988.             'REFERENCES',
  3989.             'YES'
  3990.         from #table_priv1
  3991.         where references_privilege_grant = 1
  3992.  
  3993.  
  3994.     select
  3995.         convert(varchar(32),db_name()) TABLE_QUALIFIER,
  3996.         convert(varchar(32),user_name(o.uid)) TABLE_OWNER,
  3997.         convert(varchar(32),o.name) TABLE_NAME,
  3998.         convert(varchar(32),user_name(grantor)) GRANTOR,
  3999.         convert(varchar(32),user_name(grantee)) GRANTEE,
  4000.         PRIVILEGE,
  4001.         IS_GRANTABLE
  4002.     from #table_priv2 t, sysobjects o where o.id = t.id
  4003.     order by 2,3,6
  4004. go
  4005.  
  4006. if    (charindex('6.50', @@version) = 0)
  4007. begin
  4008.     print ''
  4009.     print ''
  4010.     print 'Warning:'
  4011.     print 'you are installing the stored procedures '
  4012.     print 'on a pre 6.50 SQL Server.'
  4013.     print 'Ignore the following errors.'
  4014. end
  4015. else
  4016.     drop proc sp_table_privileges
  4017. go
  4018.  
  4019. /*    Procedure for 6.50 server */
  4020. CREATE PROCEDURE sp_table_privileges (
  4021.             @table_name         varchar(90),
  4022.             @table_owner        varchar(90) = null,
  4023.             @table_qualifier    varchar(32) = null)
  4024. as
  4025.  
  4026.     if @table_qualifier is not null
  4027.     begin
  4028.         if db_name() <> @table_qualifier
  4029.         begin    /* If qualifier doesn't match current database */
  4030.             raiserror 20001 'Table qualifier must be name of current database'
  4031.             return
  4032.         end
  4033.     end
  4034.     if @table_name is null
  4035.         select @table_name = '%'
  4036.     if @table_owner is null /* If no owner supplied, force wildcard */
  4037.         select @table_owner = '%'
  4038.  
  4039.     select
  4040.         convert(varchar(32),db_name()) TABLE_QUALIFIER,
  4041.         convert(varchar(32),user_name(o.uid)) TABLE_OWNER,
  4042.         convert(varchar(32),object_name(o.id)) TABLE_NAME,
  4043.         convert(varchar(32),user_name(p.grantor)) GRANTOR,
  4044.         convert(varchar(32),user_name(u.uid)) GRANTEE,
  4045.         case p.action
  4046.              when 193 then 'SELECT'
  4047.              when 195 then 'INSERT'
  4048.              when 196 then 'DELETE'
  4049.              when 197 then 'UPDATE'
  4050.              else convert(varchar(32),'REFERENCES')
  4051.         end PRIVILEGE,
  4052.         case when p.protecttype = 205 then 'NO'
  4053.             else 'YES'
  4054.         end IS_GRANTABLE
  4055.     from sysprotects p, sysobjects o, sysusers u
  4056.     where
  4057.         p.id = o.id
  4058.         and object_name(o.id) like @table_name
  4059.         and user_name(o.uid) like @table_owner
  4060.             /* expand groups */
  4061.         and ((p.uid = u.uid and u.uid <> u.gid) or
  4062.              (p.uid = u.gid and u.uid <> u.gid))
  4063.         and p.protecttype <> 206    /* only grant rows */
  4064.         and p.action in (26,193,195,196,197)
  4065.         and o.uid <> u.uid            /* no rows for owner */
  4066.         and not exists (            /* exclude revoke'd privileges */
  4067.             select *
  4068.             from sysprotects p1
  4069.             where
  4070.                 p1.protecttype = 206
  4071.                 and p1.action = p.action
  4072.                 and p1.id = p.id
  4073.                 and p1.uid = u.uid)
  4074.     union all
  4075.     select    /*    Add rows for table owner */
  4076.         convert(varchar(32),db_name()) TABLE_QUALIFIER,
  4077.         convert(varchar(32),user_name(o.uid)) TABLE_OWNER,
  4078.         convert(varchar(32),object_name(o.id)) TABLE_NAME,
  4079.         convert(varchar(32),user_name(u.uid)) GRANTOR,
  4080.         convert(varchar(32),user_name(o.uid)) GRANTEE,
  4081.         case v.number
  4082.             when 193 then 'SELECT'
  4083.             when 195 then 'INSERT'
  4084.             when 196 then 'DELETE'
  4085.             when 197 then 'UPDATE'
  4086.             else convert(varchar(32),'REFERENCES')
  4087.         end PRIVILEGE,
  4088.         convert(varchar,'YES') IS_GRANTABLE
  4089.     from sysobjects o, spt_values v, sysusers u
  4090.     where
  4091.         object_name(o.id) like @table_name
  4092.         and user_name(o.uid) like @table_owner
  4093.         and u.suid = 1        /* grantor is dbo of database */
  4094.         and v.type = 'P'    /* cross product to get all exposed privileges */
  4095.         and v.number in (26,193,195,196,197)
  4096.         and not exists (    /* exclude revoke'd privileges */
  4097.             select *
  4098.             from sysprotects p1
  4099.             where
  4100.                 p1.protecttype = 206
  4101.                 and p1.action = v.number
  4102.                 and p1.id = o.id
  4103.                 and p1.uid = o.uid)
  4104.     order by 2,3,6
  4105. go
  4106.  
  4107. grant execute on sp_table_privileges to public
  4108. go
  4109.  
  4110. dump tran master with no_log
  4111. go
  4112.  
  4113. print 'creating sp_tables'
  4114. go
  4115.  
  4116. create procedure sp_tables(
  4117.                @table_name        varchar(90)    = null,
  4118.                @table_owner     varchar(90)    = null,
  4119.                @table_qualifier varchar(90)    = null,
  4120.                @table_type        varchar(100) = null)
  4121. as
  4122.     declare @type1 varchar(3)
  4123.     declare @tableindex int
  4124.  
  4125.  
  4126.     /* Special feature #1:    enumerate databases when owner and name
  4127.          are blank but qualifier is explicitly '%'.  */
  4128.     if @table_qualifier = '%' and
  4129.         @table_owner = '' and
  4130.         @table_name = ''
  4131.     begin    /* If enumerating databases */
  4132.         select
  4133.             TABLE_QUALIFIER = convert(varchar(32),d.name),
  4134.             TABLE_OWNER = convert(varchar(32),null),
  4135.             TABLE_NAME = convert(varchar(32),null),
  4136.             TABLE_TYPE = convert(varchar(32),null),
  4137.             REMARKS = convert(varchar(254),null)    /* Remarks are NULL */
  4138.         from master..sysdatabases d
  4139.         where d.name <> 'model'    /* eliminate MODEL database */
  4140.         order by 1
  4141.     end
  4142.  
  4143.     /* Special feature #2:    enumerate owners when qualifier and name
  4144.          are blank but owner is explicitly '%'.  */
  4145.     else if @table_qualifier = '' and
  4146.         @table_owner = '%' and
  4147.         @table_name = ''
  4148.     begin    /* If enumerating owners */
  4149.         select distinct
  4150.             TABLE_QUALIFIER = convert(varchar(32),null),
  4151.             TABLE_OWNER = convert(varchar(32),user_name(uid)),
  4152.             TABLE_NAME = convert(varchar(32),null),
  4153.             TABLE_TYPE = convert(varchar(32),null),
  4154.             REMARKS = convert(varchar(254),null)    /* Remarks are NULL */
  4155.         from sysobjects
  4156.         order by 2
  4157.     end
  4158.  
  4159.     /* Special feature #3:    enumerate table types when qualifier, owner and
  4160.          name are blank but table type is explicitly '%'.    */
  4161.     else if @table_qualifier = '' and
  4162.         @table_owner = '' and
  4163.         @table_name = '' and
  4164.         @table_type = '%'
  4165.     begin    /* If enumerating table types */
  4166.         select
  4167.             TABLE_QUALIFIER = convert(varchar(32),null),
  4168.             TABLE_OWNER = convert(varchar(32),null),
  4169.             TABLE_NAME = convert(varchar(32),null),
  4170.             TABLE_TYPE = convert(varchar(32),rtrim(substring('SYSTEM TABLETABLE       VIEW',(colid-1)*12+1,12))),
  4171.             REMARKS = convert(varchar(254),null)    /* Remarks are NULL */
  4172.         from sysobjects o, syscolumns c
  4173.         where o.id=c.id and o.name='sysusers' and colid<=3
  4174.     end
  4175.  
  4176.     else
  4177.     begin /* end of special features -- do normal processing */
  4178.         if @table_qualifier is not null
  4179.         begin
  4180.             if db_name() <> @table_qualifier
  4181.             begin
  4182.                 if @table_qualifier = ''
  4183.                 begin  /* If empty qualifier supplied */
  4184.                     /* Force an empty result set */
  4185.                     select @table_name = ''
  4186.                     select @table_owner = ''
  4187.                 end
  4188.                 else
  4189.                 begin    /* If qualifier doesn't match current database */
  4190.                     raiserror 20001 'Table qualifier must be name of current database'
  4191.                     return
  4192.                 end
  4193.             end
  4194.         end
  4195.         if @table_type is null
  4196.         begin    /* Select all ODBC supported table types */
  4197.             select @type1 = 'SUV'
  4198.         end
  4199.         else
  4200.         begin
  4201.             /*    TableType is case sensitive if CS server */
  4202.             select @type1 = null
  4203.             if (charindex('''SYSTEM TABLE''',@table_type) <> 0)
  4204.                 select @type1 = @type1 + 'S'    /* Add System Tables */
  4205.             if (charindex('''TABLE''',@table_type) <> 0)
  4206.                 select @type1 = @type1 + 'U'    /* Add User Tables */
  4207.             if (charindex('''VIEW''',@table_type) <> 0)
  4208.                 select @type1 = @type1 + 'V'    /* Add Views */
  4209.         end
  4210.         if @table_name is null
  4211.         begin    /*    If table name not supplied, match all */
  4212.             select @table_name = '%'
  4213.         end
  4214.         else
  4215.         begin
  4216.             if (@table_owner is null) and (charindex('%', @table_name) = 0)
  4217.             begin    /* If owner not specified and table is specified */
  4218.                 if exists (select * from sysobjects
  4219.                     where uid = user_id()
  4220.                     and name = @table_name
  4221.                     and (type = 'U' or type = 'V' or type = 'S'))
  4222.                 begin    /* Override supplied owner w/owner of table */
  4223.                     select @table_owner = user_name()
  4224.                 end
  4225.             end
  4226.         end
  4227.         if @table_owner is null /* If no owner supplied, force wildcard */
  4228.             select @table_owner = '%'
  4229.         select
  4230.             TABLE_QUALIFIER = convert(varchar(32),db_name()),
  4231.             TABLE_OWNER = convert(varchar(32),user_name(o.uid)),
  4232.             TABLE_NAME = convert(varchar(32),o.name),    /* make nullable */
  4233.             TABLE_TYPE = convert(varchar(32),rtrim(
  4234.                 substring('SYSTEM TABLE            TABLE       VIEW       ',
  4235.                     (ascii(o.type)-83)*12+1,12))),    /* 'S'=0,'U'=2,'V'=3 */
  4236.             REMARKS = convert(varchar(254),null)    /* Remarks are NULL */
  4237.         from sysusers u, sysobjects o
  4238.         where
  4239.             o.name like @table_name
  4240.             and user_name(o.uid) like @table_owner
  4241.             and charindex(substring(o.type,1,1),@type1)! = 0 /* Only desired types */
  4242.             and u.uid = user_id() /* constrain sysusers uid for use in subquery */
  4243.             and (
  4244.                 suser_id() = 1     /* User is the System Administrator */
  4245.                 or o.uid = user_id()     /* User created the object */
  4246.                 /* here's the magic... select the highest precedence of permissions in the order (user,group,public)  */
  4247.                 or ((select max(((sign(uid)*abs(uid-16383))*2)+(protecttype&1))
  4248.                     from sysprotects p
  4249.                     /* outer join to correlate with all rows in sysobjects */
  4250.                     where p.id =* o.id
  4251.                         /* get rows for public,current user,user's group */
  4252.                         and (p.uid = 0 or p.uid = user_id() or p.uid =* u.gid)
  4253.                         /* check for SELECT,EXECUTE privilege */
  4254.                         and (action in (193,224)))&1     /* more magic...normalize GRANT */
  4255.                     ) = 1    /* final magic...compare Grants      */
  4256.             )
  4257.         order by 4, 1, 2, 3
  4258.     end
  4259. go
  4260.  
  4261. grant execute on sp_tables to public
  4262. go
  4263.  
  4264. dump tran master with no_log
  4265. go
  4266.  
  4267. if    (charindex('6.50', @@version) = 0)
  4268. begin
  4269.     print ''
  4270.     print ''
  4271.     print 'Warning:'
  4272.     print 'you are installing the stored procedures '
  4273.     print 'on a pre 6.50 SQL Server.'
  4274.     print 'Ignore the following errors.'
  4275. end
  4276.  
  4277. print 'creating sp_ddopen'
  4278. go
  4279.  
  4280. create procedure sp_ddopen(
  4281.                @handle            int output,
  4282.                @procname        sysname(30),
  4283.                @scrollopt        int output,
  4284.                @ccopt            int output,
  4285.                @rows            int output,
  4286.                @p1                varchar(255) = null,
  4287.                @p2                varchar(255) = null,
  4288.                @p3                varchar(255) = null,
  4289.                @p4                varchar(255) = null,
  4290.                @p5                varchar(255) = null,
  4291.                @p6                varchar(255) = null,
  4292.                @p7                int = null,
  4293.                @ODBCVer         int = 2)
  4294. as
  4295.     declare @ret int
  4296.  
  4297.     if @procname = 'sp_column_privileges'
  4298.     begin
  4299.         create table #spcolpriv (
  4300.             TABLE_QUALIFIER varchar(32) null,
  4301.             TABLE_OWNER varchar(32) null,
  4302.             TABLE_NAME varchar(32) not null,
  4303.             COLUMN_NAME varchar(32) not null,
  4304.             GRANTOR varchar(32) null,
  4305.             GRANTEE varchar(32) not null,
  4306.             PRIVILEGE varchar(32) not null,
  4307.             IS_GRANTABLE varchar(32) null
  4308.             )
  4309.         insert into #spcolpriv exec sp_column_privileges @p1,@p2,@p3,@p4
  4310.         exec @ret = sp_cursoropen @handle output,
  4311.             'select * from #spcolpriv',
  4312.             @scrollopt output, @ccopt output, @rows output
  4313.         drop table #spcolpriv
  4314.     end
  4315.     else if @procname = 'sp_columns'
  4316.     begin
  4317.         create table #spcolumns (
  4318.             TABLE_QUALIFIER varchar(32) null,
  4319.             TABLE_OWNER varchar(32) null,
  4320.             TABLE_NAME varchar(32) not null,
  4321.             COLUMN_NAME varchar(32) not null,
  4322.             DATA_TYPE smallint not null,
  4323.             TYPE_NAME varchar(30) not null,
  4324.             "PRECISION" int null,
  4325.             LENGTH int null,
  4326.             SCALE smallint null,
  4327.             RADIX smallint null,
  4328.             NULLABLE smallint not null,
  4329.             REMARKS varchar(254) null,
  4330.             COLUMN_DEF varchar(254) null,
  4331.             DATETIME_CODE int null,
  4332.             CHAR_OCTET_LENGTH int null,
  4333.             ORDINAL_POSITION int not null,
  4334.             IS_NULLABLE varchar(254) null,
  4335.             SS_DATA_TYPE tinyint null
  4336.             )
  4337.         insert into #spcolumns exec sp_columns @p1,@p2,@p3,@p4,@ODBCVer
  4338.         exec @ret = sp_cursoropen @handle output,
  4339.             'select * from #spcolumns',
  4340.             @scrollopt output, @ccopt output, @rows output
  4341.         drop table #spcolumns
  4342.     end
  4343.     else if @procname = 'sp_datatype_info'
  4344.     begin
  4345.         create table #spdatatypeinfo (
  4346.             TYPE_NAME            varchar(32)  not null,
  4347.             DATA_TYPE            smallint not null,
  4348.             "PRECISION"            int null,
  4349.             LITERAL_PREFIX        varchar(32)    null,
  4350.             LITERAL_SUFFIX        varchar(32)    null,
  4351.             CREATE_PARAMS        varchar(32)    null,
  4352.             NULLABLE            smallint   not null,
  4353.             CASE_SENSITIVE        smallint   not null,
  4354.             SEARCHABLE            smallint   not null,
  4355.             UNSIGNED_ATTRIBUTE    smallint   null,
  4356.             MONEY    smallint    not null,
  4357.             AUTO_INCREMENT        smallint    null,
  4358.             LOCAL_TYPE_NAME     varchar(128) null,
  4359.             MINIMUM_SCALE        smallint     null,
  4360.             MAXIMUM_SCALE        smallint   null,
  4361.             SQL_DATA_TYPE        smallint      not null,
  4362.             SQL_DATETIME_SUB    smallint   null,
  4363.             NUM_PREC_RADIX        int     null,
  4364.             USERTYPE            tinyint not null)
  4365.         insert into #spdatatypeinfo exec sp_datatype_info @p7,@ODBCVer
  4366.         exec @ret = sp_cursoropen @handle output,
  4367.             'select * from #spdatatypeinfo',
  4368.             @scrollopt output, @ccopt output, @rows output
  4369.         drop table #spdatatypeinfo
  4370.     end
  4371.     else if @procname = 'sp_fkeys'
  4372.     begin
  4373.         create table #spfkeys (
  4374.             PKTABLE_QUALIFIER varchar(32)     null,
  4375.             PKTABLE_OWNER varchar(32)    null,
  4376.             PKTABLE_NAME varchar(32)  not null,
  4377.             PKCOLUMN_NAME varchar(32)  not null,
  4378.             FKTABLE_QUALIFIER varchar(32)    null,
  4379.             FKTABLE_OWNER varchar(32)    null,
  4380.             FKTABLE_NAME varchar(32)  not null,
  4381.             FKCOLUMN_NAME varchar(32)  not null,
  4382.             KEY_SEQ smallint not null,
  4383.             UPDATE_RULE smallint null,
  4384.             DELETE_RULE smallint null,
  4385.             FK_NAME varchar(32) null,
  4386.             PK_NAME varchar(32) null
  4387.             )
  4388.         insert into #spfkeys exec sp_fkeys @p1,@p2,@p3,@p4,@p5,@p6
  4389.         exec @ret = sp_cursoropen @handle output,
  4390.             'select * from #spfkeys',
  4391.             @scrollopt output, @ccopt output, @rows output
  4392.         drop table #spfkeys
  4393.     end
  4394.     else if @procname = 'sp_pkeys'
  4395.     begin
  4396.         create table #sppkeys (
  4397.             TABLE_QUALIFIER varchar(32)   null,
  4398.             TABLE_OWNER varchar(32)   null,
  4399.             TABLE_NAME varchar(32)    not null,
  4400.             COLUMN_NAME varchar(32)  not null,
  4401.             KEY_SEQ smallint not null,
  4402.             PK_NAME varchar(32) null
  4403.             )
  4404.         insert into #sppkeys exec sp_pkeys @p1,@p2,@p3
  4405.         exec @ret = sp_cursoropen @handle output,
  4406.             'select * from #sppkeys',
  4407.             @scrollopt output, @ccopt output, @rows output
  4408.         drop table #sppkeys
  4409.     end
  4410.     else if @procname = 'sp_special_columns'
  4411.     begin
  4412.         create table #spspeccol (
  4413.             SCOPE smallint null,
  4414.             COLUMN_NAME varchar(32) not null,
  4415.             DATA_TYPE smallint not null,
  4416.             TYPE_NAME varchar(30) not null,
  4417.             "PRECISION" int null,
  4418.             LENGTH int null,
  4419.             SCALE smallint null,
  4420.             PSEUDO_COLUMN smallint null
  4421.             )
  4422.         insert into #spspeccol exec sp_special_columns @p1,@p2,@p3,@p4,@p5,@p6,@ODBCVer
  4423.         exec @ret = sp_cursoropen @handle output,
  4424.             'select * from #spspeccol',
  4425.             @scrollopt output, @ccopt output, @rows output
  4426.         drop table #spspeccol
  4427.     end
  4428.     else if @procname = 'sp_sproc_columns'
  4429.     begin
  4430.         create table #spproccol (
  4431.             PROCEDURE_QUALIFIER varchar(32)  null,
  4432.             PROCEDURE_OWNER varchar(32)  null,
  4433.             PROCEDURE_NAME varchar(32) not null,
  4434.             COLUMN_NAME varchar(32) not null,
  4435.             COLUMN_TYPE smallint not null,
  4436.             DATA_TYPE smallint not null,
  4437.             TYPE_NAME varchar(30) not null,
  4438.             "PRECISION" int null,
  4439.             LENGTH int null,
  4440.             SCALE smallint null,
  4441.             RADIX smallint null,
  4442.             NULLABLE smallint not null,
  4443.             REMARKS varchar(254) null,
  4444.             COLUMN_DEF varchar(254) null,
  4445.             SQL_DATETIME_SUB smallint null,
  4446.             CHAR_OCTET_LENGTH int null,
  4447.             ORDINAL_POSITION int not null,
  4448.             IS_NULLABLE varchar(254) null,
  4449.             SS_DATA_TYPE tinyint null
  4450.             )
  4451.         insert into #spproccol exec sp_sproc_columns @p1,@p2,@p3,@p4,@ODBCVer
  4452.         exec @ret = sp_cursoropen @handle output,
  4453.             'select * from #spproccol',
  4454.             @scrollopt output, @ccopt output, @rows output
  4455.         drop table #spproccol
  4456.     end
  4457.     else if @procname = 'sp_statistics'
  4458.     begin
  4459.         create table #spstatistics (
  4460.             TABLE_QUALIFIER varchar(32)   null,
  4461.             TABLE_OWNER varchar(32)   null,
  4462.             TABLE_NAME varchar(32)    not null,
  4463.             NON_UNIQUE smallint null,
  4464.             INDEX_QUALIFIER varchar(32) null,
  4465.             INDEX_NAME varchar(32) null,
  4466.             TYPE smallint not null,
  4467.             SEQ_IN_INDEX smallint null,
  4468.             COLUMN_NAME varchar(32) null,
  4469.             COLLATION char(1) null,
  4470.             CARDINALITY int null,
  4471.             PAGES int null,
  4472.             FILTER_CONDITION varchar(128) null
  4473.             )
  4474.         insert into #spstatistics exec sp_statistics @p1,@p2,@p3,@p4,@p5,@p6
  4475.         exec @ret = sp_cursoropen @handle output,
  4476.             'select * from #spstatistics',
  4477.             @scrollopt output, @ccopt output, @rows output
  4478.         drop table #spstatistics
  4479.     end
  4480.     else if @procname = 'sp_stored_procedures'
  4481.     begin
  4482.         create table #spprocedures (
  4483.             PROCEDURE_QUALIFIER varchar(32)  null,
  4484.             PROCEDURE_OWNER varchar(32)  null,
  4485.             PROCEDURE_NAME varchar(32) not null,
  4486.             NUM_INPUT_PARAMS int null,
  4487.             NUM_OUTPUT_PARAMS int null,
  4488.             NUM_RESULT_SETS int null,
  4489.             REMARKS varchar(254) null,
  4490.             PROCEDURE_TYPE smallint null
  4491.             )
  4492.         insert into #spprocedures exec sp_stored_procedures @p1,@p2,@p3
  4493.         exec @ret = sp_cursoropen @handle output,
  4494.             'select * from #spprocedures',
  4495.             @scrollopt output, @ccopt output, @rows output
  4496.         drop table #spprocedures
  4497.     end
  4498.     else if @procname = 'sp_table_privileges'
  4499.     begin
  4500.         create table #sptabpriv (
  4501.             TABLE_QUALIFIER varchar(32) null,
  4502.             TABLE_OWNER varchar(32) null,
  4503.             TABLE_NAME varchar(32) not null,
  4504.             GRANTOR varchar(32) null,
  4505.             GRANTEE varchar(32) not null,
  4506.             PRIVILEGE varchar(32) not null,
  4507.             IS_GRANTABLE varchar(32) null
  4508.             )
  4509.         insert into #sptabpriv exec sp_table_privileges @p1,@p2,@p3
  4510.         exec @ret = sp_cursoropen @handle output,
  4511.             'select * from #sptabpriv',
  4512.             @scrollopt output, @ccopt output, @rows output
  4513.         drop table #sptabpriv
  4514.     end
  4515.     else if @procname = 'sp_tables'
  4516.     begin
  4517.         create table #sptables (
  4518.             TABLE_QUALIFIER varchar(32) not null,
  4519.             TABLE_OWNER varchar(32) null,
  4520.             TABLE_NAME varchar(32) null,
  4521.             TABLE_TYPE    varchar(32) null,
  4522.             REMARKS varchar(254) null)
  4523.         insert into #sptables exec sp_tables @p1,@p2,@p3,@p4
  4524.         exec @ret = sp_cursoropen @handle output,
  4525.             'select * from #sptables',
  4526.             @scrollopt output, @ccopt output, @rows output
  4527.         drop table #sptables
  4528.     end
  4529.     select @ret = isnull(@ret,0)
  4530.     return isnull(@ret,0)
  4531. go
  4532.  
  4533. grant execute on sp_ddopen to public
  4534. go
  4535.  
  4536. dump tran master with no_log
  4537. go
  4538.  
  4539. if exists (select * from sysobjects where name = 'sp_configure'
  4540.             and sysstat & 0xf = 4)
  4541.     begin
  4542.         exec sp_configure 'allow updates',0
  4543.         reconfigure with override
  4544.     end
  4545. go
  4546.  
  4547. if exists (select * from sysobjects where name = 'sp_check_objects'
  4548.             and sysstat & 0xf = 4)
  4549.     begin
  4550.         /* Only supported on 6.0 servers */
  4551.         print ''
  4552.         print 'Checking objects created by instcat.sql.'
  4553.  
  4554.         exec sp_check_objects 'catalog'
  4555.     end
  4556. go
  4557.  
  4558. print ''
  4559. print 'instcat.sql completed successfully.'
  4560. go
  4561.  
  4562. set quoted_identifier off
  4563. go
  4564.  
  4565. dump tran master with no_log
  4566. go
  4567. checkpoint
  4568. go
  4569.