将参数传递给 SQL Server 中的视图
Posted
技术标签:
【中文标题】将参数传递给 SQL Server 中的视图【英文标题】:Passing arguments to views in SQL Server 【发布时间】:2010-01-08 13:16:01 【问题描述】:假设我有一个通过GROUP BY
子句汇总数据的视图:
CREATE VIEW InvoiceAmountsByCustomer AS
SELECT
Customer.CustomerID,
SUM(Invoice.TotalAmount) AS TotalInvoiceAmount
FROM
Customer LEFT OUTER JOIN Invoice ON Customer.CustomerID = Invoice.CustomerID
GROUP BY Customer.CustomerID
现在,假设我希望视图根据日期范围限制总数中包含哪些发票。为了说明(假装From Date
和To Date
包含日期范围):
CREATE VIEW InvoiceAmountsByCustomer AS
SELECT
Customer.CustomerID,
SUM(Invoice.TotalAmount) AS TotalInvoiceAmount
FROM
Customer LEFT OUTER JOIN Invoice ON Customer.CustomerID = Invoice.CustomerID
WHERE
Invoice.Date BETWEEN From Date AND To Date
GROUP BY Customer.CustomerID
我应该用什么替换 From Date
和 To Date
以便将它们的值(直接或间接)传递给视图?例如,是否可以将这些值与当前会话相关联?
CREATE VIEW InvoiceAmountsByCustomer AS
SELECT
Customer.CustomerID,
SUM(Invoice.TotalAmount) AS TotalInvoiceAmount
FROM
Customer LEFT OUTER JOIN Invoice ON Customer.CustomerID = Invoice.CustomerID
WHERE
Invoice.Date BETWEEN GetUserDefinedSessionValue('From Date') AND GetUserDefinedSessionValue('To Date')
GROUP BY Customer.CustomerID
其中GetUserDefinedSessionValue
是一个虚构函数,它返回与当前会话关联的值。另一个虚构的函数 SetUserDefinedSessionValue
将在查询视图之前被客户端调用:
SetUserDefinedSessionValue('From Date', ...)
SetUserDefinedSessionValue('To Date', ...)
SELECT * FROM InvoiceAmountsByCustomer
我的虚构示例只是为了说明我设想将这些值传递给视图的一种方式。
注意:这是一个简单的例子,实际情况要复杂得多,导致我无法直接由客户端执行GROUP BY
查询。
【问题讨论】:
【参考方案1】:可以在视图中调用用户定义的函数,是的,但我更愿意使用用户定义的表函数,您可以在其中传入所需的参数,然后这又会返回您想要的数据。
User Defined Functions
【讨论】:
内联表值函数与参数化视图完全一样,但多语句表值函数是另一种生物。如果可能的话,您想使用 INLINE TVF。【参考方案2】:一个旧线程,但我正在浏览我自己的这个特殊困境的答案,当我突然想到,也许最简单的方法是最好的。
解决方案 1:完全跳过视图并在代码中编写完整的 sql。然后,您可以根据需要声明参数。除非您使用索引视图,否则 select * from 'view' 和带有声明选项的整个 select 语句之间没有太大区别。
解决方案 2:不使用视图,为什么不直接创建一个过程?这不太灵活,但如果您打算使用 select * from ' view ' 它会做同样的事情。
示例:
CREATE proc dbo.ViewDates @from_date datetime, @to_date datetime AS
SELECT
Customer.CustomerID,
SUM(Invoice.TotalAmount) AS TotalInvoiceAmount FROM
Customer LEFT OUTER JOIN Invoice ON Customer.CustomerID = Invoice.CustomerID
WHERE
Invoice.Date BETWEEN @from_date AND @to_date GROUP BY Customer.CustomerID
然后,而不是选择 * :
exec dbo.ViewDates @from_date = '20120101', @to_date = '20120930'
您可能需要使用 @from_date = convert(datetime,'想要的日期字符串',想要的日期格式)
即
exec dbo.ViewDates @from_date = convert(datetime, '20120101',112), @to_date = convert(datetime,'20120930',112)
【讨论】:
【参考方案3】:这是一种解决方案:
CREATE TABLE dbo.ViewDates (theDate DATETIME)
查询数据库:
TRUNCATE TABLE viewDates
INSERT INTO viewDates VALUES (@fromDate)
INSERT INTO viewDates VALUES (@toDate)
调整视图
JOIN (select min(thedate) as StDate,max(theDate) as EnDate ) dt
ON invoice.date BETWEEN dt.StDate and dt.EndDate
请注意,这一次仅适用于一个用户,如果您需要多个用户,则需要将用户 ID 添加到表中,填充它,并稍微调整查询...
【讨论】:
以上是关于将参数传递给 SQL Server 中的视图的主要内容,如果未能解决你的问题,请参考以下文章
拆分逗号分隔参数传递给SQL Server 2008 R2中的存储过程
将 xml 字符串参数传递给 SQL Server 存储过程