2009-05-20 32 views
53

Tôi đang cố gắng tìm cách trích xuất thông tin về các bảng của mình trong SQL Server (2008).
Các dữ liệu tôi cần nhu cầu bao gồm các mô tả của bảng (điền từ mô tả tài sản trong cửa sổ Properties), một danh sách ruộng của bảng đó và tương ứng kiểu dữ liệu của họ.Máy chủ SQL: Trích xuất Bảng Siêu dữ liệu (mô tả, trường và kiểu dữ liệu của chúng)

Có cách nào để tôi có thể trích xuất siêu dữ liệu đó không? Tôi đoán tôi phải sử dụng một số sys sp nhưng tôi không chắc chắn cái nào.

+0

By the way ... nơi bạn có thể xem mô tả? Nó dường như không hiển thị trong các thuộc tính trong Management Studio. – Andomar

+3

Khi bạn sửa đổi một bảng (Thiết kế), nó nằm trong Cửa sổ Thuộc tính ... trong 'Tên Cơ sở dữ liệu' và trên 'Lược đồ' (trong máy chủ sql 2008) –

+0

Hãy bình luận của bạn; nó phải có được = 0 (không phải là IS NULL); nhưng nó phải được lọc để tránh bạn tìm các mô tả cột chống lại bảng –

Trả lời

74

Để có được dữ liệu mô tả, bạn không may phải sử dụng sysobjects/syscolumns để lấy id:

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 

Bạn có thể làm điều đó với lược đồ thông tin, nhưng bạn phải ghép nối v.v. để gọi OBJECT_ID() - vậy điều gì sẽ là điểm?

+0

Thông tin-lược đồ dường như dễ dàng hơn để truy xuất kiểu dữ liệu. Tôi nghĩ rằng bạn có thể lấy nó ở đây với một tham gia để systype trên c.xtype. – Andomar

+0

Tôi đồng ý với bạn ở đó; lược đồ thông tin giúp việc này trở nên dễ dàng ...có lẽ một số hợp nhất lý tưởng giữa hai. –

+0

Marc, tại sao bạn bao gồm 'td.minor_id IS NULL'? Với phần bổ sung này, nó không lấy ra được mô tả, nhưng nếu tôi xóa nó, nó sẽ hoạt động. –

29

thông tin chung về các bảng và các cột có thể được tìm thấy trong các bảng:

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

Mô tả bảng là một thuộc tính mở rộng, bạn có thể truy vấn chúng từ 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' 
+0

Bạn có thể phải cẩn thận một chút về cách bạn gọi OBJECT_ID() để phân biệt với các chủ sở hữu khác nhau –

+0

MS_Description_Table? Ngoài ra - siêu dữ liệu bảng và siêu dữ liệu cột được lưu trữ riêng; bạn cần phải xử lý các minor_id một cách thích hợp –

+0

điểm tốt tất cả các chỉnh sửa ngay bây giờ! Ngoại trừ minor_id xuất hiện không hoạt động theo nhận xét về câu trả lời của bạn. – Andomar

7

Bạn có thể thử sp_help <Name of object>

+0

Lưu ý: Tôi đang thử điều này với SQL Server 2008 Express và rất nhiều siêu dữ liệu hữu ích được bán phá giá, nhưng đối với tôi, nó không chọn bất kỳ mô tả nào cho bảng hoặc cột của bảng. – jlafay

+0

Rực rỡ. Điều này đã cho tôi tất cả mọi thứ tôi cần thiết và nhiều hơn nữa, bằng cách sử dụng SQL Server 2008 (không Express). – JMD

5

Sử dụng Object Catalogue Xem:

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’; 

Sử dụng thông tin Schema Xem

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 
0

Nếu bạn chỉ muốn xem các thông tin một cách thuận tiện , Red SQL's SQL Prompt có thể giúp bạn.

Nếu bạn di chuột qua văn bản đối tượng trong cửa sổ truy vấn, SQL Prompt sẽ hiển thị văn bản thuộc tính mở rộng MS_Description trong chú giải công cụ. Nhấp vào chú giải công cụ sẽ mở một hộp thoại hiển thị thông tin cột và cũng là DDL của đối tượng.

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

0

Nếu đó là OK để sử dụng mã NET Tôi muốn đề nghị sử dụng SMO: http://msdn.microsoft.com/en-us/library/ms162169.aspx, Trong trường hợp cụ thể của bạn nó sẽ là lớp Bảng http://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.table.aspx Đây sẽ là một giải pháp di động hơn so với sử dụng phiên bản cụ thể các khung nhìn và bảng hệ thống.

Nếu đây là một cái gì đó bạn sẽ sử dụng một cách thường xuyên - bạn có thể muốn viết một ứng dụng giao diện điều khiển đơn giản, có lẽ với một mã máy phát điện chạy T4 http://msdn.microsoft.com/en-us/library/ee844259.aspx

Nếu nó chỉ là một nhiệm vụ một lần - bạn có thể sử dụng tính năng xuất bản của LiveDoco (http://www.livedoco.com) sang XML với biến đổi XSLT tùy chọn hoặc tôi chắc chắn có các công cụ miễn phí có thể thực hiện việc này. Điều này có vẻ ổn thỏa: http://sqldbdoc.codeplex.com/ - hỗ trợ XML qua XSLT, nhưng tôi không chắc liệu bạn có thể chạy nó cho một bảng lựa chọn hay không (Với LiveDoco bạn có thể).

+0

Những công cụ này trông tuyệt vời! Tôi sẽ không làm điều đó bằng tay nếu tôi đã biết những người tồn tại: ( – TheDev6

1

Nếu bạn đang truy vấn bằng mã java, có một lớp tuyệt vời có thể được sử dụng, ResultSetMetaData, có thể truy xuất tên cột và thuộc tính của các cột (loại và độ dài).

Ví dụ

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)); 
       } 
      } 
1

tôi sử dụng mã SQL này để có được tất cả các thông tin về một cột.

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' 
0
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' 
2

Tùy thuộc vào bao nhiêu siêu dữ liệu mà bạn muốn, điều này đang làm việc cho tôi: nơi có thể là điều hoàn toàn như Northwind.dbo.Products hay chỉ là sản phẩm

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 
0
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 
5

Tôi thích câu trả lời của Andomar nhất, nhưng tôi cũng cần các mô tả cột. Đây là truy vấn của ông được sửa đổi để bao gồm cả những người cũng có. (Bỏ ghi chú phần cuối cùng của mệnh đề WHERE để chỉ trả về các hàng có mô tả là không null).

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 
0

Tôi vừa hoàn thành một thư viện .net với một vài truy vấn hữu ích trả về các đối tượng C# mạnh mẽ cho mẫu mã/t4.

nuget SqlMeta

Project Site

github source

/// <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; 
    } 

Foreign Key Metadata

Các vấn đề liên quan