【发布时间】:2015-08-26 15:17:07
【问题描述】:
在 SQL Server 中,如果我有一个采用表值参数参数的标量值函数,定义如下(简化示例):
CREATE TYPE IntTableType AS TABLE(Value INT);
CREATE FUNCTION dbo.MeetsCustomRequirements
(
@TypeIDs IntTableType READONLY
)
RETURNS TINYINT AS
BEGIN
-- (Function logic here; returns either 0 or 1 based on the specified @TypeIDs values)
END
我希望能够从视图中调用该函数,其中视图的表值参数是从内联查询生成的,例如:
CREATE VIEW dbo.vEligibleItems AS
SELECT i.ItemID
FROM tItems i
WHERE dbo.MeetsCustomRequirements (
(SELECT TypeID FROM tItemTypes WHERE ItemID = i.ItemID)
);
但是,这不起作用,因为该嵌套 SELECT 查询的结果不是IntTableType(尽管它是INT 值的列表)。 (生成的具体错误为Error 206: Operand type clash: int is incompatible with IntTableType。)
我的两部分问题:有没有办法调用从视图中获取表值参数参数的函数?如果不是,有哪些替代方法可以完成同样的事情?
数据库是 SQL Server 2008。
(将函数中的逻辑内联到视图中并不理想,因为函数是从几个不同的地方调用的,而不仅仅是从这个视图中。)
【问题讨论】:
-
也许你需要交叉申请
-
你能把标量函数改成内联表值函数吗?请注意,这意味着单个选择语句。如果您有多个语句,这将无济于事,实际上性能可能会更差。那么交叉应用是一种更好的方法。仔细看看你的 where 谓词。你有一个标量函数,但你试图传递一整列,你也需要一些条件。
-
是的,直接在 tItems 和 tItemTypes 之间进行内部连接似乎更好。
dbo.MeetsCustomRequirements中的逻辑是什么? -
在我的真实代码中,标量值函数还需要几个其他参数。该逻辑本质上是一个带有多个 WHEN 子句的大型 CASE 语句,这些子句查看输入参数值并针对各种组合返回 1,如果没有命中任何组合则返回 0。
-
CASE 块是只检查表值参数中的一行还是所有行?
标签: sql sql-server table-valued-parameters