我正在尝试将元数据附加到存储过程的结果集。该过程将返回一个表,作为SELECT查询的结果,或者在过程本身中构建的临时表。我想用其他信息来装饰它的列,以模拟.NET的属性。然后,在使用ADO.NET
执行过程时,我想评估此元数据。
据我所知,这不容易做到。我可以通过创建一个全局临时表(##
前缀),然后在tempdb
中手动将扩展属性附加到它来解决它。有什么想法吗?
答案 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();