MS SQL 模仿ORACLE的DESC

Posted 张英爱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MS SQL 模仿ORACLE的DESC相关的知识,希望对你有一定的参考价值。

       前言: 在ORACLE数据库的SQL*PLUS里面有个DES(DESCRIBE)命令,它可以返回数据库所存储对象的描述,如下所示 

SQL> DESC STUDENT_SCORE
 
Name             Type       Nullable Default Comments
 
---------------- ---------- -------- ------- --------
 
STUDENT_NO       NUMBER(10)                  学号    
 
CHINESE_SCORE    NUMBER     Y                语文成绩
 
ENGLISH_SCORE    NUMBER     Y                英语成绩
 
MATH_SOCRE       NUMBER     Y                数学成绩
 
PHYSICAL_SCORE   NUMBER     Y                物理成绩
 
SPORTS_SCORE     NUMBER     Y                体育成绩
 
CHEMICAL_SCORE   NUMBER     Y                化学成绩
 
BIOLOGICAL_SCORE NUMBER     Y                生物成绩

DESC可以获取表、视图等的字段名、字段类型、以及字段注释等信息。在开发过程中,这个命令非常实用,方便,也是使用频率比较高的命令,在MS SQL中没有这个命令,倒是有个sp_help命令,也比较方便,获取的信息甚至比DESC命令还多,但是它有个缺陷,不能获取字段的注释信息,有时候给你来一堆你不想关注的信息。下面我们我们来创建一个存储过程,模拟实现DESC命令的功能以及定制一些你想要的功能。希望这个存储过程能方便大家的工作。初版代码如下: 

sp_desc
  1.    
  2. SET ANSI_NULLS ON;
  3. GO
  4.  
  5. SET QUOTED_IDENTIFIER ON
  6. GO
  7.  
  8.   IF  EXISTS(SELECT 1 FROM sysobjects WHEREid=OBJECT_ID(N\'sp_desc\')
  9.                       AND OBJECTPROPERTY(id, \'IsProcedure\') =1)
  10.     DROP PROCEDURE sp_desc;
  11. GO
  12.  
  13. --==================================================================================================
  14. --            ProcedureName            :            sp_desc
  15. --            Author                   :            Kerry
  16. --            CreateDate               :            2013-05-13
  17. --            Blog                     :            www.cnblogs.com/kerrycode/
  18. --            Description              :            模仿ORACLE的SQLPLUS命令DESC,并且参考sp_help相关
  19. --                                                  增强功能
  20. /***************************************************************************************************
  21.         Parameters                    :             参数说明
  22. ****************************************************************************************************
  23.             @ObjName                  :            需要查看的对象名称,例如表名、视图等
  24. ****************************************************************************************************
  25.         Modified Date            Modified User     Version            Modified Reason
  26. ****************************************************************************************************
  27.        2013-05-19                Kerry             V01.00.01        增加Print信息,提示输出内容
  28. ***************************************************************************************************/
  29. --==================================================================================================
  30. CREATE PROCEDURE sp_desc
  31. (
  32.     @ObjName        VARCHAR(32)
  33. )
  34. AS
  35.  
  36. SET NOCOUNT ON;
  37.  
  38. DECLARE @ObjectId        INT;
  39. DECLARE @Sysobj_Type    CHAR(2);
  40.  
  41. IF @ObjName IS NULL
  42.     BEGIN
  43.         PRINT \'you must assign the parameter @ObjNam\';
  44.         
  45.         RETURN 0;
  46.     END
  47.  
  48.  
  49. SELECT @ObjectId = object_id, @Sysobj_Type=type FROM sys.all_objects
  50.     WHERE object_id =OBJECT_ID(@ObjName);
  51.     
  52. IF @Sysobj_Type =\'U\' AND @ObjectId > 0
  53. BEGIN
  54.     
  55.                 
  56.         SELECT N\'************表的功能描述信息**********\' AS N\'表的功能描述信息\';
  57.         
  58.         --表的功能描述信息
  59.         SELECT    ISNULL(value, \'麻烦补齐表的功能描述信息\') AS Table_Desc
  60.         FROM      sys.extended_properties
  61.         WHERE     major_id = @ObjectId
  62.             AND minor_id = 0
  63.          
  64.         SELECT N\'************表结构基本信息************\' AS N\'表结构基本信息\';
  65.            
  66.         --列出表结构的基本信息
  67.         SELECT  C.Name AS Column_Nam ,
  68.                 CASE WHEN T.Name = \'nvarchar\'
  69.                      THEN T.name + \'(\' + CAST(C.max_length / 2 AS VARCHAR) + \')\'
  70.                      ELSE T.name
  71.                 END AS Data_Type ,
  72.                 CASE WHEN C.Max_Length = -1 THEN \'Max\'
  73.                      ELSE CAST(C.Max_Length AS VARCHAR)
  74.                 END AS Max_Length ,
  75.                 C.Precision ,
  76.                 C.Scale     ,
  77.                 CASE WHEN C.is_nullable = 0 THEN \'×\'
  78.                      ELSE \'√\'
  79.                 END AS Is_Nullable ,
  80.                 ISNULL(CAST(I.seed_value AS VARCHAR) + \'-\'
  81.                        + CAST(I.increment_value AS VARCHAR), \'\') AS Is_Identity ,
  82.                 ISNULL(M.text, \'\') AS Default_Value ,
  83.                 ISNULL(P.value, \'\') AS Column_Comments
  84.         FROM    sys.columns C
  85.                 INNER JOIN sys.types T ON C.system_type_id = T.user_type_id
  86.                 LEFT  JOIN dbo.syscomments M ON M.id = C.default_object_id
  87.                 LEFT  JOIN sys.extended_properties P ON P.major_id = C.object_id
  88.                                                         AND C.column_id = P.minor_id
  89.                 LEFT  JOIN sys.identity_columns I ON I.column_id = C.column_id
  90.                                                      AND C.object_id = I.object_id
  91.         WHERE   C.[object_id] = @ObjectId
  92.         ORDER BY C.Column_Id ASC;
  93.         
  94.         SELECT N\'**********表约束基本信息************\' AS N\'表约束基本信息\';
  95.         
  96.         --表的约束信息
  97.           SELECT    name ,
  98.                     type
  99.           FROM      sys.objects
  100.           WHERE     parent_object_id = @ObjectId
  101.                     AND type IN( \'C \', \'PK\', \'UQ\', \'F \', \'D \' ) ;
  102.         
  103.         
  104.         SELECT N\'********表的索引基本信息********\' AS N\'表的索引基本信息\';
  105.         
  106.           --±表的索引信息
  107.           SELECT    i.index_id ,
  108.                     i.data_space_id ,
  109.                     i.name ,
  110.                     CASE WHEN type = 0 THEN \'堆\'
  111.                          WHEN type = 1 THEN \'聚集索引\'
  112.                          WHEN type = 2 THEN \'非聚集索引\'
  113.                          WHEN type = 3 THEN \'XML\'
  114.                          WHEN TYPE = 4 THEN \'空间\'
  115.                     END AS [type] ,
  116.                     i.ignore_dup_key ,
  117.                     i.is_unique ,
  118.                     i.is_hypothetical ,
  119.                     i.is_primary_key ,
  120.                     i.is_unique_constraint ,
  121.                     s.auto_created ,
  122.                     s.no_recompute
  123.           FROM      sys.indexes i
  124.                     JOIN sys.stats s ON i.object_id = s.object_id
  125.                                         AND i.index_id = s.stats_id
  126.           WHERE     i.object_id = @ObjectId;
  127.   
  128.           SELECT N\'********索引包含那些字段********\' AS \'索引字段信息\';
  129.             
  130.           SELECT  d.name, i.index_id, c.name
  131.             FROM   sys.indexes d
  132.                 INNER JOIN    sys.index_columns i ON d.object_id = i.object_id
  133.                     LEFT JOIN sys.columns c ON i.object_id = c.object_id
  134.                                                AND i.index_column_id = c.column_id
  135.             WHERE   d.object_id = @ObjectId;
  136.         
  137.         
  138.          SELECT N\'********表的触发器基本信息********\' AS N\'触发器信息\';
  139.         --表的触发器信息
  140.         
  141.         SELECT  trigger_name = name ,
  142.                 trigger_owner = USER_NAME(OBJECTPROPERTY(object_id, \'ownerid\')) ,
  143.                 isupdate = OBJECTPROPERTY(object_id, \'ExecIsUpdateTrigger\') ,
  144.                 isdelete = OBJECTPROPERTY(object_id, \'ExecIsDeleteTrigger\') ,
  145.                 isinsert = OBJECTPROPERTY(object_id, \'ExecIsInsertTrigger\') ,
  146.                 isafter = OBJECTPROPERTY(object_id, \'ExecIsAfterTrigger\') ,
  147.                 isinsteadof = OBJECTPROPERTY(object_id, \'ExecIsInsteadOfTrigger\') ,
  148.                 trigger_schema = SCHEMA_NAME(schema_id)
  149.         FROM      sys.objects
  150.         WHERE     parent_object_id = @ObjectId
  151.                 AND type IN( \'TR\', \'TA\' ) ;
  152.     
  153. END
  154. ELSE IF @Sysobj_Type =\'V\' AND @ObjectId > 0
  155. BEGIN
  156.  
  157.     SELECT N\'*********视图的功能描述信息**********\'  AS N\'视图的功能描述信息\';
  158.     
  159.     --视图的功能描述信息
  160.     SELECT    ISNULL(value, N\'麻烦补齐描述该视图功能的信息\') AS View_Desc
  161.     FROM      sys.extended_properties
  162.     WHERE     major_id = @ObjectId
  163.         AND minor_id = 0
  164.             
  165.     SELECT \'*************视图基本信息*****************\' AS N\'视图基本信息\';
  166.     
  167.     SELECT  C.Name AS Column_Nam ,
  168.             CASE WHEN T.Name = \'nvarchar\'
  169.                  THEN T.name + \'(\' + CAST(C.max_length / 2 AS VARCHAR) + \')\'
  170.                  ELSE T.name
  171.             END AS Data_Type ,
  172.             CASE WHEN C.Max_Length = -1 THEN \'Max\'
  173.                  ELSE CAST(C.Max_Length AS VARCHAR)
  174.             END AS Max_Length ,
  175.             C.Precision ,
  176.             C.Scale     ,
  177.             CASE WHEN C.is_nullable = 0 THEN \'×\'
  178.                  ELSE \'√\'
  179.             END AS Is_Nullable ,
  180.             ISNULL(CAST(I.seed_value AS VARCHAR) + \'-\'
  181.                    + CAST(I.increment_value AS VARCHAR), \'\') AS Is_Identity ,
  182.             ISNULL(M.text, \'\') AS Default_Value ,
  183.             ISNULL(P.value, \'\') AS Column_Comments
  184.     FROM    sys.columns C
  185.             INNER JOIN sys.types T ON C.system_type_id = T.user_type_id
  186.             LEFT  JOIN dbo.syscomments M ON M.id = C.default_object_id
  187.             LEFT  JOIN sys.extended_properties P ON P.major_id = C.object_id
  188.                                                     AND C.column_id = P.minor_id 
  189.             LEFT  JOIN sys.identity_columns I ON I.column_id = C.column_id
  190.                                                  AND C.object_id = I.object_id
  191.     WHERE   C.[object_id] = @ObjectId
  192.     ORDER BY C.Column_Id ASC;
  193.     
  194.     SELECT \'**********视图脚本***********\' AS \'视图脚本\';
  195.     
  196.     EXEC sp_helptext @ObjName;
  197.     
  198.     
  199. END
  200. ELSE IF @Sysobj_Type =\'P\' AND @ObjectId > 0
  201. BEGIN
  202.     SELECT N\'*********描述存储过程功能信息**********\'  AS N\'描述存储过程功能信息\';
  203.     
  204.     --存储过程的功能描述信息
  205.     SELECT    ISNULL(value, N\'麻烦补齐描述该存储过程功能的信息\') AS View_Desc
  206.     FROM      sys.extended_properties
  207.     WHERE     major_id = @ObjectId
  208.         AND minor_id = 0;
  209.         
  210.     EXEC sp_help  @ObjName;
  211. END
  212.  
  213. ELSE IF @Sysobj_Type IN(\'IF\') AND @ObjectId > 0
  214. BEGIN
  215.  
  216.         SELECT N\'*********描述自定义函数功能信息**********\'  AS N\'描述自定义函数功能信息\';
  217.     
  218.         --描述自定义函数功能信息
  219.         SELECT    ISNULL(value, N\'麻烦补齐描述该自定义函数功能的信息\') AS View_Desc
  220.         FROM      sys.extended_properties
  221.         WHERE     major_id = @ObjectId
  222.             AND minor_id = 0;
  223.         
  224.         
  225.         SELECT  \'Name\' = o.name ,
  226.                 \'Owner\' = USER_NAME(OBJECTPROPERTY(object_id, \'ownerid\')) ,
  227.                 \'Object_type\' = SUBSTRING(v.name, 5, 31)
  228.         FROM    sys.all_objects o ,
  229.                 master.dbo.spt_values v
  230.         WHERE  o.object_id =@ObjectId AND  o.type = SUBSTRING(v.name, 1, 2) COLLATE database_default
  231.                 AND v.type = \'O9T\'
  232.         ORDER BY [Owner] ASC ,
  233.                 Object_type DESC ,
  234.                 Name ASC
  235. END
  236.  
  237. GO

 

接下来,我们新建一张表来看看效果如何,视图,存储过程、自定义函数就不大战篇幅去展示了,一个例子就OK了,有兴趣的,自己试试

 
SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
 
IF EXISTS(SELECT * FROM sysobjects WHERE id=OBJECT_ID(N\'Employee\') AND type=\'U\')
 
    DROP TABLE dbo.Employee;
 
GO 
 
CREATE TABLE Employee
 
(
 
    Employee_ID          INT  IDENTITY(1,1) ,
    Employee_Name        NVARCHAR(12)        ,
    Sex                     SMALLINT DEFAULT(1),
    Department_ID         INT                ,
    Salary                 FLOAT                ,
    WorkYear             INT                ,
    CONSTRAINT PK_Employee PRIMARY KEY(Employee_ID)
 
);
 
EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'员工编号\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'Employee\', @level2type=N\'COLUMN\',@level2name=N\'Employee_ID\'
GO
 
EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'员工姓名\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'Employee\', @level2type=N\'COLUMN\',@level2name=N\'Employee_Name\'
GO
 
EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'性别\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'Employee\', @level2type=N\'COLUMN\',@level2name=N\'Sex\'
GO
 
EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'部门编号\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'Employee\', @level2type=N\'COLUMN\',@level2name=N\'Department_ID\'
GO
 
EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'薪水\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'Employee\', @level2type=N\'COLUMN\',@level2name=N\'Salary\'
GO
 
EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'工龄\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'Employee\', @level2type=N\'COLUMN\',@level2name=N\'WorkYear\'
GO
 
 
EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'员工信息表\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'TABLE\',@level1name=N\'Employee\'
 
 
CREATE TRIGGER TR_Employee_Salary ON Employee
 AFTER INSERT
AS
 
DECLARE @Salary FLOAT;
 
    SELECT @Salary = Salary FROM INSERTED;
    
 IF (@Salary < 0) 
    BEGIN
        RAISERROR(\'The Salary  Small than 0 \',10,1);
        ROLLBACK TRANSACTION;
 
    END
        
GO
 
 
CREATE VIEW V_Employee
AS 
    SELECT Employee_ID, Employee_Name, WorkYear FROM Employee
 
EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'员工信息表\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'VIEW\',@level1name=N\'V_Employee\'
 
 
 
EXEC sys.sp_addextendedproperty @name=N\'MS_Description\', @value=N\'给用户批量赋权限的存储过程\' , @level0type=N\'SCHEMA\',@level0name=N\'dbo\', @level1type=N\'PROCEDURE\',@level1name=N\'sp_authorize_right\'

执行存储过程,你可以获取表Employee的基本信息了,如下所示

image

以上是关于MS SQL 模仿ORACLE的DESC的主要内容,如果未能解决你的问题,请参考以下文章

将片段添加到片段中(嵌套片段)

oracle中与mysql中的命令 show databases, show tables, desc table类似的命令集

SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase(代码片

oracle 如何获取表的结构,就像mysql里的desc命令一样的功能,

Oracle-05-SQL语句概述分类&amp;SQL*PLUS概述(初识insert,desc,list,r,del,a,c,n等命令)

Oracle SQL更新视图