복붙노트

[SQL] SQL 서버 : 추출 테이블 메타 데이터 (설명, 필드 및 데이터 유형)

SQL

SQL 서버 : 추출 테이블 메타 데이터 (설명, 필드 및 데이터 유형)

나는 SQL 서버 (2008) 내 테이블에 대한 정보를 추출 할 수있는 방법을 찾기 위해 노력하고있다. 내가 요구 사항을 필요로하는 데이터 (속성 창에서 설명 속성에서 작성) 테이블의 설명, 해당 테이블의 필드와 해당 데이터 유형의 목록을 포함합니다.

나는 그런 메타 데이터를 추출 할 수있는 방법이 있습니까? 나는 I'n하지 않도록하는 일을 몇 가지 SYS SP를 사용할 필요하지만 가정.

해결법

  1. ==============================

    1.설명 데이터를 얻으려면, 당신은 불행하게도 ID를 얻기 위해 / SYSCOLUMNS을 sysobjects를 사용해야합니다 :

    설명 데이터를 얻으려면, 당신은 불행하게도 ID를 얻기 위해 / SYSCOLUMNS을 sysobjects를 사용해야합니다 :

    SELECT      u.name + '.' + t.name AS [table],
                td.value AS [table_desc],
                c.name AS [column],
                cd.value AS [column_desc]
    FROM        sysobjects t
    INNER JOIN  sysusers u
        ON      u.uid = t.uid
    LEFT OUTER JOIN sys.extended_properties td
        ON      td.major_id = t.id
        AND     td.minor_id = 0
        AND     td.name = 'MS_Description'
    INNER JOIN  syscolumns c
        ON      c.id = t.id
    LEFT OUTER JOIN sys.extended_properties cd
        ON      cd.major_id = c.id
        AND     cd.minor_id = c.colid
        AND     cd.name = 'MS_Description'
    WHERE t.type = 'u'
    ORDER BY    t.name, c.colorder
    

    당신은 정보 스키마와 함께 할 수 있지만 OBJECT_ID ()를 호출 CONCATENATE 등해야 할 것 - 어떤 포인트가 될 것입니다 그래서?

  2. ==============================

    2.테이블과 컬럼에 대한 일반 정보는이 테이블에서 찾을 수 있습니다 :

    테이블과 컬럼에 대한 일반 정보는이 테이블에서 찾을 수 있습니다 :

    select * from INFORMATION_SCHEMA.TABLES
    select * from INFORMATION_SCHEMA.COLUMNS
    

    테이블 설명은 sys.extended_properties에서이를 조회 할 수 있습니다, 확장 된 속성입니다 :

    select 
        TableName = tbl.table_schema + '.' + tbl.table_name, 
        TableDescription = prop.value,
        ColumnName = col.column_name, 
        ColumnDataType = col.data_type
    FROM information_schema.tables tbl
    INNER JOIN information_schema.columns col 
        ON col.table_name = tbl.table_name
        AND col.table_schema = tbl.table_schema
    LEFT JOIN sys.extended_properties prop 
        ON prop.major_id = object_id(tbl.table_schema + '.' + tbl.table_name) 
        AND prop.minor_id = 0
        AND prop.name = 'MS_Description' 
    WHERE tbl.table_type = 'base table'
    
  3. ==============================

    3.당신은 sp_help는 시도해 볼 수도 있습니다 <개체의 이름>

    당신은 sp_help는 시도해 볼 수도 있습니다 <개체의 이름>

  4. ==============================

    4.내가 Andomar의 대답 최고의 @ 좋아하지만, 나는 또한 열 설명이 필요했습니다. 여기에 또한 사람들을 포함하도록 수정 자신의 쿼리입니다. (어느 설명 널이 아닌 곳의 주석이 WHERE 절의 마지막 부분은 행을 리턴하기 위해).

    내가 Andomar의 대답 최고의 @ 좋아하지만, 나는 또한 열 설명이 필요했습니다. 여기에 또한 사람들을 포함하도록 수정 자신의 쿼리입니다. (어느 설명 널이 아닌 곳의 주석이 WHERE 절의 마지막 부분은 행을 리턴하기 위해).

    SELECT
        TableName = tbl.table_schema + '.' + tbl.table_name, 
        TableDescription = tableProp.value,
        ColumnName = col.column_name, 
        ColumnDataType = col.data_type,
        ColumnDescription = colDesc.ColumnDescription
    FROM information_schema.tables tbl
    INNER JOIN information_schema.columns col 
        ON col.table_name = tbl.table_name
    LEFT JOIN sys.extended_properties tableProp 
        ON tableProp.major_id = object_id(tbl.table_schema + '.' + tbl.table_name) 
            AND tableProp.minor_id = 0
            AND tableProp.name = 'MS_Description' 
    LEFT JOIN (
        SELECT sc.object_id, sc.column_id, sc.name, colProp.[value] AS ColumnDescription
        FROM sys.columns sc
        INNER JOIN sys.extended_properties colProp
            ON colProp.major_id = sc.object_id
                AND colProp.minor_id = sc.column_id
                AND colProp.name = 'MS_Description' 
    ) colDesc
        ON colDesc.object_id = object_id(tbl.table_schema + '.' + tbl.table_name)
            AND colDesc.name = col.COLUMN_NAME
    WHERE tbl.table_type = 'base table'
    --AND tableProp.[value] IS NOT NULL OR colDesc.ColumnDescription IS NOT null
    
  5. ==============================

    5.개체 카탈로그 뷰를 사용하여 :

    개체 카탈로그 뷰를 사용하여 :

    SELECT  T.NAME AS [TABLE NAME], C.NAME AS [COLUMN NAME], P.NAME AS [DATA TYPE], P.MAX_LENGTH AS[SIZE],   CAST(P.PRECISION AS VARCHAR) +‘/’+ CAST(P.SCALE AS VARCHAR) AS [PRECISION/SCALE]
    FROM ADVENTUREWORKS.SYS.OBJECTS AS T
    JOIN ADVENTUREWORKS.SYS.COLUMNS AS C
    ON T.OBJECT_ID=C.OBJECT_ID
    JOIN ADVENTUREWORKS.SYS.TYPES AS P
    ON C.SYSTEM_TYPE_ID=P.SYSTEM_TYPE_ID
    WHERE T.TYPE_DESC=‘USER_TABLE’;
    

    정보 스키마 뷰를 사용하여

    SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, ORDINAL_POSITION,
           COLUMN_DEFAULT, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH,
           NUMERIC_PRECISION, NUMERIC_PRECISION_RADIX, NUMERIC_SCALE,
           DATETIME_PRECISION
    FROM ADVENTUREWORKS.INFORMATION_SCHEMA.COLUMNS
    
  6. ==============================

    6.당신이 나를 위해 일하고 싶어 얼마나 많은 메타 데이터에 따라 : 어디 Northwind.dbo.Products하거나 제품처럼 모든 일이 될 수

    당신이 나를 위해 일하고 싶어 얼마나 많은 메타 데이터에 따라 : 어디 Northwind.dbo.Products하거나 제품처럼 모든 일이 될 수

    SELECT c.name Field, 
        t.name Type,
        c.Precision, 
        c.Scale,
        c.is_nullable,
        c.collation_name 
    FROM sys.columns c 
    INNER JOIN sys.types t ON t.system_type_id=c.system_type_id
    WHERE object_id=object_id('<table to inspect>')
    ORDER BY column_id
    
  7. ==============================

    7.당신은 자바 코드를 사용하여 쿼리를 당기는 경우, 열 이름과 열 (종류 및 길이)의 속성을 검색 할 수 ResultSetMetaData에 사용할 수있는 좋은 수업이있다.

    당신은 자바 코드를 사용하여 쿼리를 당기는 경우, 열 이름과 열 (종류 및 길이)의 속성을 검색 할 수 ResultSetMetaData에 사용할 수있는 좋은 수업이있다.

    ResultSet rs = null;
    
            rs = sql.executeQuery();
    
            if (rs != null) {
                if (rs.next()) {
                    ResultSetMetaData rsmd = rs.getMetaData();
                    for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                        System.out.println("column name: "
                                + rsmd.getColumnName(i));
                        System.out.println("column size: "
                                + rsmd.getColumnDisplaySize(i));
                    }
                }
    
  8. ==============================

    8.이것 좀 봐:

    이것 좀 봐:

    SELECT TABLE_SCHEMA ,
           TABLE_NAME ,
           COLUMN_NAME ,
           ORDINAL_POSITION ,
           COLUMN_DEFAULT ,
           DATA_TYPE ,
           CHARACTER_MAXIMUM_LENGTH ,
           NUMERIC_PRECISION ,
           NUMERIC_PRECISION_RADIX ,
           NUMERIC_SCALE ,
           DATETIME_PRECISION
    FROM   INFORMATION_SCHEMA.COLUMNS
    where TABLE_SCHEMA in ('dbo','meta')
    and table_name in (select name from sys.tables)
    order by TABLE_SCHEMA ,       TABLE_NAME ,ORDINAL_POSITION
    

  9. ==============================

    9.나는 컬럼에 대한 모든 정보를 얻을이 SQL 코드를 사용합니다.

    나는 컬럼에 대한 모든 정보를 얻을이 SQL 코드를 사용합니다.

    SELECT
    COL.COLUMN_NAME,
    ORDINAL_POSITION,
    DATA_TYPE,
    CHARACTER_MAXIMUM_LENGTH,
    NUMERIC_PRECISION,
    NUMERIC_PRECISION_RADIX,
    NUMERIC_SCALE,
    DATETIME_PRECISION,
    IS_NULLABLE,
    CONSTRAINT_TYPE,
    COLUMNPROPERTY(object_id(COL.TABLE_NAME), COL.COLUMN_NAME, 'IsIdentity') IS_IDENTITY,
    COLUMNPROPERTY(object_id(COL.TABLE_NAME), COL.COLUMN_NAME, 'IsComputed') IS_COMPUTED
    
    FROM INFORMATION_SCHEMA.COLUMNS COL 
    LEFT OUTER JOIN 
    (
        SELECT COLUMN_NAME, CONSTRAINT_TYPE 
        FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE A
        INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS B 
        ON A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
        WHERE A.TABLE_NAME = 'User'
    ) CONS
    ON COL.COLUMN_NAME = CONS.COLUMN_NAME
    WHERE COL.TABLE_NAME = 'User'
    
  10. ==============================

    10.기본 메타 데이터 요약을 얻을 수있는 가장 쉬운 방법은 임시 테이블을 사용하고 EXEC 기능을 사용하는 것입니다 :

    기본 메타 데이터 요약을 얻을 수있는 가장 쉬운 방법은 임시 테이블을 사용하고 EXEC 기능을 사용하는 것입니다 :

    SELECT * INTO #TempTable FROM TableName
    EXEC [tempdb].[dbo].[sp_help] N'#TempTable'
    

    테이블의 모든 컬럼의 경우, 이것은 당신에게 줄 것이다 열 이름, 데이터 형식, 계산 된 길이, PREC, 규모, Null 허용, TrimTrailingBlanks, FixedLenNullInSource, 데이터 정렬 유형

  11. ==============================

    11.당신은 단순히 편리한 방법, 레드 게이트의 SQL 프롬프트 힘 도움말의 정보를 확인하십시오.

    당신은 단순히 편리한 방법, 레드 게이트의 SQL 프롬프트 힘 도움말의 정보를 확인하십시오.

    당신이 MS_Description 표시됩니다 프롬프트 쿼리 창 SQL에서 개체의 텍스트 위로 마우스를 올려 놓으면 툴팁의 속성 문자를 확장했다. 툴팁을 클릭하면 열 정보 또한 객체의 DDL을 표시하는 대화 상자가 열립니다.

    http://www.red-gate.com/products/sql-development/sql-prompt/

  12. ==============================

    12.이 테이블 클래스 HTTP 될 특정 경우에, http://msdn.microsoft.com/en-us/library/ms162169.aspx : 그것을 사용 .NET 코드에 OK 인 경우 I는 SMO를 사용하는 것이 좋습니다 것입니다 // msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.table.aspx 이 버전의 특정 시스템 뷰와 테이블을 사용하는 것보다 더 휴대용 솔루션이 될 것입니다.

    이 테이블 클래스 HTTP 될 특정 경우에, http://msdn.microsoft.com/en-us/library/ms162169.aspx : 그것을 사용 .NET 코드에 OK 인 경우 I는 SMO를 사용하는 것이 좋습니다 것입니다 // msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.table.aspx 이 버전의 특정 시스템 뷰와 테이블을 사용하는 것보다 더 휴대용 솔루션이 될 것입니다.

    이것은 당신이 정기적으로 사용하려는 어떤 경우 - 당신은 런타임 T4 코드 생성기 http://msdn.microsoft.com/en-us/library/ee844259.aspx으로 아마도 간단한 콘솔 응용 프로그램을 작성 할 수 있습니다

    그냥 작업 한 떨어져 있다면 - 당신은 변환 옵션 XSLT와 XML 기능에 내 LiveDoco의 (http://www.livedoco.com) 수출을 사용할 수 있습니다 또는 난 반드시이 작업을 수행 할 수 있습니다 거기 무료 도구가 있습니다. XSLT를 통해 지원의 XML,하지만 당신은하지만 (당신이 할 수있는 LiveDoco와) 테이블의 선택을 실행할 수 있는지 확실하지 않습니다 - http://sqldbdoc.codeplex.com/ :를이 사람은 좋아 보인다.

  13. ==============================

    13.

      SELECT
        sc.name AS ColumnName
       ,ep.*
      FROM
        sys.columns AS sc
        INNER JOIN sys.extended_properties AS ep
          ON ep.major_id = sc.[object_id]
             AND ep.minor_id = sc.column_id
      WHERE
    
    --here put your desired table
        sc.[object_id] = OBJECT_ID('[Northwind].[dbo].[Products]')
    
    -- this is optional, remove this and you get all extended props
        AND ep.name = 'MS_Description'
    
  14. ==============================

    14.

    select Col.name Columnname,prop.Value Description, tbl.name Tablename, sch.name schemaname
        from sys.columns col  left outer join  sys.extended_properties prop
                        on prop.major_id =  col.object_id and prop.minor_id = col.column_id
                        inner join sys.tables tbl on col.object_id =  tbl.object_id
                        Left outer join sys.schemas sch on sch.schema_id = tbl.schema_id
    
  15. ==============================

    15.난 그냥 강하게 코드 세대 / T4 템플릿에 대한 C #을 객체를 입력 돌려주는 몇 가지 유용한 쿼리와 .NET 라이브러리를 마쳤다.

    난 그냥 강하게 코드 세대 / T4 템플릿에 대한 C #을 객체를 입력 돌려주는 몇 가지 유용한 쿼리와 .NET 라이브러리를 마쳤다.

    덩어리 SqlMeta

    프로젝트 사이트

    github의 소스

    /// <summary>
        ///     Get All Table Names
        /// </summary>
        /// <returns></returns>
        public List<string> GetTableNames()
        {
            var sql = @"SELECT name
                        FROM dbo.sysobjects
                        WHERE xtype = 'U' 
                        AND name <> 'sysdiagrams'
                        order by name asc";
    
            return databaseWrapper.Call(connection => connection.Query<string>(
                sql: sql))
                .ToList();
        }
    
        /// <summary>
        ///     Get table info by schema and table or null for all
        /// </summary>
        /// <param name="schema"></param>
        /// <param name="table"></param>
        /// <returns></returns>
        public List<SqlTableInfo> GetTableInfo(string schema = null, string table = null)
        {
            var result = new List<SqlTableInfo>();
    
            var sql = @"SELECT
                        c.TABLE_CATALOG AS [TableCatalog]
                    ,   c.TABLE_SCHEMA AS [Schema]
                    ,   c.TABLE_NAME AS [TableName]
                    ,   c.COLUMN_NAME AS [ColumnName]
                    ,   c.ORDINAL_POSITION AS [OrdinalPosition]
                    ,   c.COLUMN_DEFAULT AS [ColumnDefault]
                    ,   c.IS_NULLABLE AS [Nullable]
                    ,   c.DATA_TYPE AS [DataType]
                    ,   c.CHARACTER_MAXIMUM_LENGTH AS [CharacterMaxLength]
                    ,   c.CHARACTER_OCTET_LENGTH AS [CharacterOctetLenth]
                    ,   c.NUMERIC_PRECISION AS [NumericPrecision]
                    ,   c.NUMERIC_PRECISION_RADIX AS [NumericPrecisionRadix]
                    ,   c.NUMERIC_SCALE AS [NumericScale]
                    ,   c.DATETIME_PRECISION AS [DatTimePrecision]
                    ,   c.CHARACTER_SET_CATALOG AS [CharacterSetCatalog]
                    ,   c.CHARACTER_SET_SCHEMA AS [CharacterSetSchema]
                    ,   c.CHARACTER_SET_NAME AS [CharacterSetName]
                    ,   c.COLLATION_CATALOG AS [CollationCatalog]
                    ,   c.COLLATION_SCHEMA AS [CollationSchema]
                    ,   c.COLLATION_NAME AS [CollationName]
                    ,   c.DOMAIN_CATALOG AS [DomainCatalog]
                    ,   c.DOMAIN_SCHEMA AS [DomainSchema]
                    ,   c.DOMAIN_NAME AS [DomainName]
                    ,   IsPrimaryKey = CONVERT(BIT, (SELECT
                                COUNT(*)
                            FROM    INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
                                ,   INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE cu
                            WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
                            AND tc.CONSTRAINT_NAME = cu.CONSTRAINT_NAME
                            AND tc.TABLE_NAME = c.TABLE_NAME
                            AND cu.TABLE_SCHEMA = c.TABLE_SCHEMA
                            AND cu.COLUMN_NAME = c.COLUMN_NAME)
                        )
                    ,   IsIdentity = CONVERT(BIT, (SELECT
                                COUNT(*)
                            FROM sys.objects obj
                            INNER JOIN sys.COLUMNS col
                                ON obj.object_id = col.object_id
                            WHERE obj.type = 'U'
                            AND obj.Name = c.TABLE_NAME
                            AND col.Name = c.COLUMN_NAME
                            AND col.is_identity = 1)
                        )
                    FROM INFORMATION_SCHEMA.COLUMNS c
                    WHERE (@Schema IS NULL
                            OR c.TABLE_SCHEMA = @Schema)
                        AND (@TableName IS NULL
                            OR c.TABLE_NAME = @TableName)
                        ";
    
            var columns = databaseWrapper.Call(connection => connection.Query<SqlColumnInfo>(
                sql: sql,
                param: new { Schema = schema, TableName = table },
                commandType: CommandType.Text)
                .ToList());
    
            var refs = this.GetReferentialConstraints(table: table, schema: schema);
    
            foreach (var tableName in columns.Select(info => info.TableName).Distinct())
            {
                var tableColumns = columns.Where(info => info.TableName == tableName).ToList();
                var children = refs.Where(c => c.UniqueTableName == tableName).ToList();
                var parents = refs.Where(c => c.TableName == tableName).ToList();
                result.Add(new SqlTableInfo
                {
                    TableName = tableName,
                    Columns = tableColumns,
                    ChildConstraints = children,
                    ParentConstraints = parents
                });
    
            }
    
            return result;
        }
    
        public List<SqlReferentialConstraint> GetReferentialConstraints(string table = null, string schema = null)
        {
            //https://technet.microsoft.com/en-us/library/aa175805%28v=sql.80%29.aspx
            //https://technet.microsoft.com/en-us/library/Aa175805.312ron1%28l=en-us,v=sql.80%29.jpg
            //https://msdn.microsoft.com/en-us/library/ms186778.aspx
    
            var sql = @"
                        SELECT
                            KCU1.CONSTRAINT_NAME AS [ConstraintName]
                        ,   KCU1.TABLE_NAME AS [TableName]
                        ,   KCU1.COLUMN_NAME AS [ColumnName]
                        ,   KCU2.CONSTRAINT_NAME AS [UniqueConstraintName]
                        ,   KCU2.TABLE_NAME AS [UniqueTableName]
                        ,   KCU2.COLUMN_NAME AS [UniqueColumnName]
                        ,   RC.MATCH_OPTION AS [MatchOption]
                        ,   RC.UPDATE_RULE AS [UpdateRule]
                        ,   RC.DELETE_RULE AS [DeleteRule]
                        FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
                        LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1 ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
                            AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
                            AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
                        LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2 ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG
                            AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA
                            AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME
                        WHERE KCU1.ORDINAL_POSITION = KCU2.ORDINAL_POSITION
                                AND (@Table IS NULL
                                    OR KCU1.TABLE_NAME = @Table
                                    OR KCU2.TABLE_NAME = @Table)
                                AND (@Schema IS NULL
                                    OR KCU1.TABLE_SCHEMA = @Schema
                                    OR KCU2.TABLE_SCHEMA = @Schema)
                        ";
    
            return databaseWrapper.Call(connection => connection.Query<SqlReferentialConstraint>(
                sql: sql,
                param: new { Table = table, Schema = schema },
                commandType: CommandType.Text))
                .ToList();
        }
    
        /// <summary>
        ///     Get Primary Key Column by schema and table name
        /// </summary>
        /// <param name="schema"></param>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public string GetPrimaryKeyColumnName(string schema, string tableName)
        {
            var sql = @"SELECT
                        B.COLUMN_NAME
                    FROM    INFORMATION_SCHEMA.TABLE_CONSTRAINTS A
                        ,   INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE B
                    WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
                        AND A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
                        AND A.TABLE_NAME = @TableName
                        AND A.TABLE_SCHEMA = @Schema";
    
            return databaseWrapper.Call(connection => connection.Query<string>(
                sql: sql,
                param: new { TableName = tableName, Schema = schema },
                commandType: CommandType.Text))
                .SingleOrDefault();
        }
    
        /// <summary>
        ///     Get Identity Column by table name
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public string GetIdentityColumnName(string tableName)
        {
            var sql = @"SELECT
                        c.Name
                    FROM sys.objects o
                    INNER JOIN sys.columns c ON o.object_id = c.object_id
                    WHERE o.type = 'U'
                        AND c.is_identity = 1
                        AND o.Name = @TableName";
    
            return databaseWrapper.Call(connection => connection.Query<string>(
                sql: sql,
                param: new { TableName = tableName },
                commandType: CommandType.Text))
                .SingleOrDefault();
        }
    
        /// <summary>
        ///     Get All Stored Procedures by schema
        /// </summary>
        /// <param name="schema"></param>
        /// <param name="procName"></param>
        /// <returns></returns>
        public List<SqlStoredProcedureInfo> GetStoredProcedureInfo(string schema = null, string procName = null)
        {
            var result = new List<SqlStoredProcedureInfo>();
    
            var sql = @"SELECT
                            SPECIFIC_NAME AS [Name]
                        ,   SPECIFIC_SCHEMA AS [Schema]
                        ,   Created AS [Created]
                        ,   LAST_ALTERED AS [LastAltered]
                        FROM INFORMATION_SCHEMA.ROUTINES
                        WHERE ROUTINE_TYPE = 'PROCEDURE'
                            AND (SPECIFIC_SCHEMA = @Schema
                                OR @Schema IS NULL)
                            AND (SPECIFIC_NAME = @ProcName
                                OR @ProcName IS NULL)
                            AND ((SPECIFIC_NAME NOT LIKE 'sp_%'
                                    AND SPECIFIC_NAME NOT LIKE 'procUtils_GenerateClass'
                                    AND (SPECIFIC_SCHEMA = @Schema
                                        OR @Schema IS NULL))
                                OR SPECIFIC_SCHEMA <> @Schema)";
    
            var sprocs = databaseWrapper.Call(connection => connection.Query<SqlStoredProcedureInfo>(
                sql: sql,
                param: new { Schema = schema, ProcName = procName },
                commandType: CommandType.Text).ToList());
    
            foreach (var s in sprocs)
            {
                s.Parameters = GetStoredProcedureInputParameters(sprocName: s.Name, schema: schema);
                s.ResultColumns = GetColumnInfoFromStoredProcResult(storedProcName: s.Name, schema: schema);
                result.Add(s);
            }
    
            return result;
        }
    
        /// <summary>
        ///     Get Column info from Stored procedure result set
        /// </summary>
        /// <param name="schema"></param>
        /// <param name="storedProcName"></param>
        /// <returns></returns>
        public List<DataColumn> GetColumnInfoFromStoredProcResult(string schema, string storedProcName)
        {
            //this one actually needs to use the dataset because it has the only accurate information about columns and if they can be null or not.
            var sb = new StringBuilder();
            if (!String.IsNullOrEmpty(schema))
            {
                sb.Append(String.Format("exec [{0}].[{1}] ", schema, storedProcName));
            }
            else
            {
                sb.Append(String.Format("exec [{0}] ", storedProcName));
            }
    
            var prms = GetStoredProcedureInputParameters(schema, storedProcName);
    
            var count = 1;
            foreach (var param in prms)
            {
                sb.Append(String.Format("{0}=null", param.Name));
                if (count < prms.Count)
                {
                    sb.Append(", ");
                }
                count++;
            }
    
            var ds = new DataSet();
            using (var sqlConnection = (SqlConnection)databaseWrapper.GetOpenDbConnection())
            {
                using (var sqlAdapter = new SqlDataAdapter(sb.ToString(), sqlConnection))
                {
                    if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open();
    
                    sqlAdapter.SelectCommand.ExecuteReader(CommandBehavior.SchemaOnly);
    
                    sqlConnection.Close();
    
                    sqlAdapter.FillSchema(ds, SchemaType.Source, "MyTable");
                }
            }
    
            var list = new List<DataColumn>();
            if (ds.Tables.Count > 0)
            {
                list = ds.Tables["MyTable"].Columns.Cast<DataColumn>().ToList();
            }
    
            return list;
        }
    
        /// <summary>
        ///     Get the input parameters for a stored procedure
        /// </summary>
        /// <param name="schema"></param>
        /// <param name="sprocName"></param>
        /// <returns></returns>
        public List<SqlParameterInfo> GetStoredProcedureInputParameters(string schema = null, string sprocName = null)
        {
            var sql = @"SELECT
                        SCHEMA_NAME(schema_id) AS [Schema]
                    ,   P.Name AS Name
                    ,   @ProcName AS ProcedureName
                    ,   TYPE_NAME(P.user_type_id) AS [ParameterDataType]
                    ,   P.max_length AS [MaxLength]
                    ,   P.Precision AS [Precision]
                    ,   P.Scale AS Scale
                    ,   P.has_default_value AS HasDefaultValue
                    ,   P.default_value AS DefaultValue
                    ,   P.object_id AS ObjectId
                    ,   P.parameter_id AS ParameterId
                    ,   P.system_type_id AS SystemTypeId
                    ,   P.user_type_id AS UserTypeId
                    ,   P.is_output AS IsOutput
                    ,   P.is_cursor_ref AS IsCursor
                    ,   P.is_xml_document AS IsXmlDocument
                    ,   P.xml_collection_id AS XmlCollectionId
                    ,   P.is_readonly AS IsReadOnly
                    FROM sys.objects AS SO
                    INNER JOIN sys.parameters AS P ON SO.object_id = P.object_id
                    WHERE SO.object_id IN (SELECT
                                object_id
                            FROM sys.objects
                            WHERE type IN ('P', 'FN'))
                        AND (SO.Name = @ProcName
                            OR @ProcName IS NULL)
                        AND (SCHEMA_NAME(schema_id) = @Schema
                            OR @Schema IS NULL)
                    ORDER BY P.parameter_id ASC";
    
            var result = databaseWrapper.Call(connection => connection.Query<SqlParameterInfo>(
                sql: sql,
                param: new { Schema = schema, ProcName = sprocName },
                commandType: CommandType.Text))
                .ToList();
    
            return result;
        }
    

    외래 키 메타 데이터

  16. from https://stackoverflow.com/questions/887370/sql-server-extract-table-meta-data-description-fields-and-their-data-types by cc-by-sa and MIT license