将扩展属性附加到存储过程结果集

时间:2014-07-08 05:15:19

标签: sql-server sql-server-2008 sqlclr

我正在尝试将元数据附加到存储过程的结果集。该过程将返回一个表,作为SELECT查询的结果,或者在过程本身中构建的临时表。我想用其他信息来装饰它的列,以模拟.NET的属性。然后,在使用ADO.NET执行过程时,我想评估此元数据。

据我所知,这不容易做到。我可以通过创建一个全局临时表(##前缀),然后在tempdb中手动将扩展属性附加到它来解决它。有什么想法吗?

2 个答案:

答案 0 :(得分:3)

为什么不从SP返回2个结果集?一个是实际结果集,您现在拥有的结果集,另一个是元数据。

元数据表可以是在SP中创建的表变量,具有以下结构:

DECLARE @ResultsMetadata AS TABLE
(
  Id INT NOT NULL IDENTITY(1,1),
  ColumnName VARCHAR(128) NOT NULL,
  ColumnMetadata VARCHAR(128) NOT NULL
)

你可以在我认为是CLR(因为标签)中读到这个。使用SqlDataReader可以轻松阅读多个结果集。如果您还需要在SQL中进一步处理结果,那么也许您可以切换到具有两个顶级元素(主结果集和元数据)的XML输出。

修改

实际上只是注意到您正在使用ADO.NET阅读此内容,因此您不应该对多个结果集有任何问题。您可以使用SqlDataReader.NextResult将阅读器推进到第二个(元数据)结果集。

答案 1 :(得分:3)

建议方法1:

首先创建元数据类型:

CREATE TYPE MetaData AS TABLE
(
  Name VARCHAR(128) NOT NULL,
  Property NVARCHAR(Max)
)

在每个存储过程中,在存储过程的结果集之后返回元数据:

CREATE PROCEDURE YourProcedure 
AS BEGIN
    --FIRST Result Set
    --Your Stored Procedure code here
    ...


    --Second Result Set
    DECLARE @MetaData dbo.MetaData 
    INSERT INTO @MetaData(Name, Property)VALUES(...)
    SELECT * FROM @MetaData
END

您可以单独在代码中阅读结果集。以下代码是C#代码,以便从一个存储过程中获取多个结果集。

SqlConnection oConn = null;
DataSet dsReturn = null;
try
{
    getConnection(ref oConn, 1);

    using (SqlStoredProcedure sspObj = new SqlStoredProcedure("dbo.YourStoredProcedure", oConn, CommandType.StoredProcedure))
    {
        sspObj.AddParameterWithValue("@Parameter", SqlDbType.Int, Parametervalue, ParameterDirection.Input, type);
        dsReturn = sspObj.ExecuteDataSet();
        //You don't need Dispose() - because the using will do that on sspObj
    }

    closeConnection(ref oConn);
}
catch (Exception xObj)
{
    dsReturn = new DataSet("Empty");
}

在上面的代码dsReturn.Tables[0]中是存储过程的结果集,dsReturn.Tables[1]是存储过程的元数据的结果集。

建议方法2:

添加要存储过程的扩展属性的每个元数据:

EXEC sys.sp_addextendedproperty @name=N'MetaDataColumn1', @value=N'value1' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'YourProcedure'
GO
EXEC sys.sp_addextendedproperty @name=N'MetaDataColumn2', @value=N'value2' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'PROCEDURE',@level1name=N'YourProcedure'
GO

在查询之后,返回存储过程的元数据:

SELECT ep.name, ep.value
FROM sys.extended_properties ep
INNER JOIN sys.procedures p ON p.object_id = ep.major_id
WHERE p.name = 'YourProcedure'
    AND ep.name LIKE 'MetaData%'

您可以从代码中执行上述查询(C#示例):

connetionString = "Data Source=ServerName;Initial Catalog=DatabaseName;User ID=UserName;Password=Password";
sql = "AboveQuery";
sqlCnn = new SqlConnection(connetionString);
sqlCnn.Open();
sqlCmd = new SqlCommand(sql, sqlCnn);
SqlDataReader sqlReader = sqlCmd.ExecuteReader();