我正在尝试创建一个存储过程/ ADO.NET映射机制,其中带参数的存储过程变为
object MyStoredProcedure.Execute(out returnValue, param1, param2, ...)
尝试生成实际的数据检索方法时出现问题。我可以从Information Schema视图中轻松获取我需要的大部分模式信息,但是我无法可靠地找到应该来自过程的返回类型(输出参数与SELECT / SqlDataReader相对于两者)以及是否调用ExecuteNonQuery或者ExecuteReader。
最糟糕的情况是,我可以解析程序的文本,但有各种各样的时髦的东西可能会出错。
代码生成的原因是应用程序数据库包含数百个存储过程。我们继承了这个项目,所以没有办法围绕我们没有创建的许多过程。
实际上,ADO.NET生成有两个主要目标:
1)从应用程序中删除所有字符串文字(SqlCommand创建中存储的proc名称,SqlParameter创建中的参数名称等)。这样,当过程或数据库模式发生更改时,我们可以重新生成ADO.NET包装器,并且这些更改产生的任何错误都将在编译时捕获。
2)删除了挖掘proc以确定params,返回类型等的需要。基本上,数据库本身就变成了一个API,所有内部存储过程细节都被抽象掉了。
答案 0 :(得分:3)
烨;这并不容易。对于简单的情况,您可以尝试运行sp(awooga!)为所有参数传递空值,并使用SET FMTONLY ON
- 有点冒险(例如,执行扩展的sprocs)而不是因为TSQL可以在输入上进行分支。但是一个选择。
“out”ets应该可以通过元数据获得; “旧”的方式是syscolumns
(可能有一种信息模式替代方法,以正确的方式)。
就像更新一样;如果您希望数据库将自己描述为API,可以考虑选择UDF;优点:
或者;只需使用ORM。 LINQ-to-SQL可以很好地使用这种类型的设置(包括可组合性);实体框架肯定会为您的存储过程做一切艰苦的工作。或任何其他人; NHibernate,LLBLGen Pro等等。他们都解决了这个问题。这不是微不足道的;为什么重新发明它?
答案 1 :(得分:2)
我认为你不应该担心它 提供超载并不是更好吗?让用户决定调用哪种方法?
如果我没有正确理解这个问题,请告诉我。
答案 2 :(得分:0)
假设所有存储过程都是一致的,也就是说,每个存储过程最多返回一个结果集,具有相同的列集,而不管它的参数值或数据库的数据状态,并且所有OUTPUT参数都是总是写到,..
并且还假设这是一个开发或最近的构建时工具(并且不是运行时工具)并且您可以控制Srored Procedure的内容,那么这里是我会尝试的:
制定追溯存储过程标准,要求所有sProcs都要对以下形式发表评论,这些评论必须在测试(或开发?)数据库中正常工作:
'TEST:EXEC spThisProc [,...]
编写工具以从系统目录中提取存储过程及其参数,数据类型和输出参数的列表(您可以使用INFORMATION_SCHEMA表ROUTINES和PARAMETERS)。
还检索所有sProcs的脚本(来自INFORMATION_SCHEMA.ROUTINES表的ROUTINE_DEFINITON列,一个地方),然后提取“'TEST:”命令(上面)和ExecuteReader的文本。测试数据库。然后测试返回的Resultset以查看它是否包含任何数据集(或者它是“Tables”?)。如果没有,则将此sProc标记为需要ExecuteNonQuery,否则,提取返回的数据集的列定义,并使用than为类定义生成相应的ExecuteReader代码。
答案 3 :(得分:0)
希望这有助于检索params的类型
select s.id, s.name, t.name as [type], t.length,s.isoutparam
from syscolumns s inner join systypes t
on s.xtype = t.xtype
where id = (select id from sysobjects where name = 'SP NAME')
并查看这个优秀的链接 - get the list of columns returned from the SQL select
这是一个示例查询
USE tempdb
GO
IF OBJECT_ID('dbo.TestSP') IS NOT NULL
DROP PROCEDURE dbo.TestSP;
GO
IF NOT EXISTS (SELECT * FROM sys.servers WHERE name = 'Loopback')
BEGIN
EXEC sp_addlinkedserver @server = 'Loopback', @srvproduct = '',
@provider = 'SQLOLEDB', @datasrc = @@servername
END
GO
CREATE PROC dbo.TestSP
AS
SELECT 1 as [ID], 'Name' as [Name], 'Boston' as [City]
GO
DECLARE @MyXML XML
SELECT @MyXML = (SELECT * FROM
(SELECT *
FROM OPENQUERY(Loopback,'SET FMTONLY ON;
EXEC tempdb.dbo.TestSP;
SET FMTONLY OFF')) vw FOR XML AUTO, XMLSCHEMA)
SELECT @MyXML
SET FMTONLY - >它将允许您运行SP,但只返回元数据
答案 4 :(得分:0)
此外,您可以尝试查看SqlServer SMO http://msdn.microsoft.com/en-us/library/ms162169.aspx以查询有关数据库的信息,而无需直接针对信息架构编写查询。