前言: 在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
   
SETANSI_NULLSON;
GO


SETQUOTED_IDENTIFIERON
GO


  IF  EXISTS(SELECT 1 FROMsysobjectsWHEREid=OBJECT_ID(N'sp_desc')
                      ANDOBJECTPROPERTY(id,'IsProcedure')=1)
    DROPPROCEDUREsp_desc;
GO


--==================================================================================================
--            ProcedureName            :            sp_desc
--            Author                   :            Kerry
--            CreateDate               :            2013-05-13
--            Blog                     :            www.cnblogs.com/kerrycode/
--            Description              :            模仿ORACLE的SQLPLUS命令DESC,并且参考sp_help相关
--                                                  增强功能
/***************************************************************************************************
        Parameters                    :             参数说明
****************************************************************************************************
            @ObjName                  :            需要查看的对象名称,例如表名、视图等
****************************************************************************************************
        Modified Date            Modified User     Version            Modified Reason
****************************************************************************************************
       2013-05-19                Kerry             V01.00.01        增加Print信息,提示输出内容
***************************************************************************************************/
--==================================================================================================
CREATEPROCEDUREsp_desc
(
    @ObjName        VARCHAR(32)
)
AS


SETNOCOUNTON;


DECLARE@ObjectId        INT;
DECLARE@Sysobj_Type    CHAR(2);


IF@ObjNameISNULL
    BEGIN
        PRINT'you must assign the parameter @ObjNam';
        
        RETURN 0;
    END




SELECT@ObjectId=object_id,@Sysobj_Type=typeFROMsys.all_objects
    WHEREobject_id=OBJECT_ID(@ObjName);
    
IF@Sysobj_Type='U'AND@ObjectId> 0
BEGIN
    
                
        SELECTN'************表的功能描述信息**********'ASN'表的功能描述信息';
        
        --表的功能描述信息
        SELECT    ISNULL(value,'麻烦补齐表的功能描述信息')ASTable_Desc
        FROM      sys.extended_properties
        WHERE     major_id=@ObjectId
            AND minor_id = 0
         
        SELECTN'************表结构基本信息************'ASN'表结构基本信息';
           
        --列出表结构的基本信息
        SELECT  C.NameASColumn_Nam,
                CASEWHENT.Name='nvarchar'
                     THENT.name+'('+CAST(C.max_length/ 2 ASVARCHAR)+')'
                     ELSET.name
                ENDASData_Type,
                CASEWHENC.Max_Length=-1 THEN'Max'
                     ELSECAST(C.Max_LengthASVARCHAR)
                ENDASMax_Length,
                C.Precision,
                C.Scale     ,
                CASEWHENC.is_nullable= 0 THEN'×'
                     ELSE'√'
                ENDASIs_Nullable,
                ISNULL(CAST(I.seed_valueASVARCHAR)+'-'
                       +CAST(I.increment_valueASVARCHAR),'')ASIs_Identity,
                ISNULL(M.text,'')ASDefault_Value,
                ISNULL(P.value,'')ASColumn_Comments
        FROM    sys.columnsC
                INNERJOINsys.typesTONC.system_type_id=T.user_type_id
                LEFT  JOINdbo.syscommentsMONM.id=C.default_object_id
                LEFT  JOINsys.extended_propertiesPONP.major_id=C.object_id
                                                        ANDC.column_id=P.minor_id
                LEFT  JOINsys.identity_columnsIONI.column_id=C.column_id
                                                     ANDC.object_id=I.object_id
        WHERE   C.[object_id]=@ObjectId
        ORDERBYC.Column_IdASC;
        
        SELECTN'**********表约束基本信息************'ASN'表约束基本信息';
        
        --表的约束信息
          SELECT    name,
                    type
          FROM      sys.objects
          WHERE     parent_object_id=@ObjectId
                    ANDtypeIN('C ','PK','UQ','F ','D ');
        
        
        SELECTN'********表的索引基本信息********'ASN'表的索引基本信息';
        
          --±表的索引信息
          SELECT    i.index_id,
                    i.data_space_id,
                    i.name,
                    CASEWHENtype= 0 THEN'堆'
                         WHENtype= 1 THEN'聚集索引'
                         WHENtype= 2 THEN'非聚集索引'
                         WHENtype= 3 THEN'XML'
                         WHENTYPE= 4 THEN'空间'
                    ENDAS[type],
                    i.ignore_dup_key,
                    i.is_unique,
                    i.is_hypothetical,
                    i.is_primary_key,
                    i.is_unique_constraint,
                    s.auto_created,
                    s.no_recompute
          FROM      sys.indexesi
                    JOINsys.statssONi.object_id=s.object_id
                                        ANDi.index_id=s.stats_id
          WHERE     i.object_id=@ObjectId;
  
          SELECTN'********索引包含那些字段********'AS'索引字段信息';
            
          SELECT  d.name,i.index_id,c.name
            FROM   sys.indexesd
                INNERJOIN    sys.index_columnsiONd.object_id=i.object_id
                    LEFTJOINsys.columnscONi.object_id=c.object_id
                                               ANDi.index_column_id=c.column_id
            WHERE   d.object_id=@ObjectId;
        
        
         SELECTN'********表的触发器基本信息********'ASN'触发器信息';
        --表的触发器信息
        
        SELECT  trigger_name=name,
                trigger_owner=USER_NAME(OBJECTPROPERTY(object_id,'ownerid')),
                isupdate=OBJECTPROPERTY(object_id,'ExecIsUpdateTrigger'),
                isdelete=OBJECTPROPERTY(object_id,'ExecIsDeleteTrigger'),
                isinsert=OBJECTPROPERTY(object_id,'ExecIsInsertTrigger'),
                isafter=OBJECTPROPERTY(object_id,'ExecIsAfterTrigger'),
                isinsteadof=OBJECTPROPERTY(object_id,'ExecIsInsteadOfTrigger'),
                trigger_schema=SCHEMA_NAME(schema_id)
        FROM      sys.objects
        WHERE     parent_object_id=@ObjectId
                ANDtypeIN('TR','TA');
    
END
ELSEIF@Sysobj_Type='V'AND@ObjectId> 0
BEGIN


    SELECTN'*********视图的功能描述信息**********'  ASN'视图的功能描述信息';
    
    --视图的功能描述信息
    SELECT    ISNULL(value,N'麻烦补齐描述该视图功能的信息')ASView_Desc
    FROM      sys.extended_properties
    WHERE     major_id=@ObjectId
        AND minor_id = 0
            
    SELECT'*************视图基本信息*****************'ASN'视图基本信息';
    
    SELECT  C.NameASColumn_Nam,
            CASEWHENT.Name='nvarchar'
                 THENT.name+'('+CAST(C.max_length/ 2 ASVARCHAR)+')'
                 ELSET.name
            ENDASData_Type,
            CASEWHENC.Max_Length=-1 THEN'Max'
                 ELSECAST(C.Max_LengthASVARCHAR)
            ENDASMax_Length,
            C.Precision,
            C.Scale     ,
            CASEWHENC.is_nullable= 0 THEN'×'
                 ELSE'√'
            ENDASIs_Nullable,
            ISNULL(CAST(I.seed_valueASVARCHAR)+'-'
                   +CAST(I.increment_valueASVARCHAR),'')ASIs_Identity,
            ISNULL(M.text,'')ASDefault_Value,
            ISNULL(P.value,'')ASColumn_Comments
    FROM    sys.columnsC
            INNERJOINsys.typesTONC.system_type_id=T.user_type_id
            LEFT  JOINdbo.syscommentsMONM.id=C.default_object_id
            LEFT  JOINsys.extended_propertiesPONP.major_id=C.object_id
                                                    ANDC.column_id=P.minor_id
            LEFT  JOINsys.identity_columnsIONI.column_id=C.column_id
                                                 ANDC.object_id=I.object_id
    WHERE   C.[object_id]=@ObjectId
    ORDERBYC.Column_IdASC;
    
    SELECT'**********视图脚本***********'AS'视图脚本';
    
    EXECsp_helptext @ObjName;
    
    
END
ELSEIF@Sysobj_Type='P'AND@ObjectId> 0
BEGIN
    SELECTN'*********描述存储过程功能信息**********'  ASN'描述存储过程功能信息';
    
    --存储过程的功能描述信息
    SELECT    ISNULL(value,N'麻烦补齐描述该存储过程功能的信息')ASView_Desc
    FROM      sys.extended_properties
    WHERE     major_id=@ObjectId
        ANDminor_id= 0;
        
    EXECsp_help  @ObjName;
END


ELSEIF@Sysobj_TypeIN('IF')AND@ObjectId> 0
BEGIN


        SELECTN'*********描述自定义函数功能信息**********'  ASN'描述自定义函数功能信息';
    
        --描述自定义函数功能信息
        SELECT    ISNULL(value,N'麻烦补齐描述该自定义函数功能的信息')ASView_Desc
        FROM      sys.extended_properties
        WHERE     major_id=@ObjectId
            ANDminor_id= 0;
        
        
        SELECT  'Name'=o.name,
                'Owner'=USER_NAME(OBJECTPROPERTY(object_id,'ownerid')),
                'Object_type'=SUBSTRING(v.name, 5, 31)
        FROM    sys.all_objectso,
                master.dbo.spt_valuesv
        WHERE  o.object_id=@ObjectIdAND  o.type=SUBSTRING(v.name, 1, 2)COLLATEdatabase_default
                ANDv.type='O9T'
        ORDERBY[Owner]ASC,
                Object_typeDESC,
                NameASC
END


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的基本信息了,如下所示

MS SQL 模仿ORACLE的DESC_存储过程