是否可以在同一个查询中同时使用过滤器和视图函数?
Is it possible to use both a filter and a view functions in the same query?
我的表格有点像这样(定义不准确请见谅):
CREATE TABLE JunctionTable( int Concrete1ID, int Concrete2ID, int someProperty)
CREATE TABLE Concrete1 ( int ID, int Prop1, int Prop2)
CREATE TABLE Concrete2 ( int ID, int Prop1, int Prop2, int Prop3, int Prop4)
每个具体表都有外键。
而且我有一些功能。一个函数 - FilterJunction
- 获取 JunctionTable
中满足特定条件的东西,另一个函数 - SomeViewofConcrete2
- 给定 Concrete2
行的 return 属性Concrete2ID
.
CREATE FUNCTION [dbo].FilterJunction() Returns Table AS
BEGIN RETURN (SELECT * FROM JunctionTable WHERE someProperty < 5)
END
CREATE FUNCTION [dbo].SomeViewOfConcrete2(@ID int) RETURNS TABLE
BEGIN
Return (SELECT Prop2, Prop4 FROM Concrete2 WHERE ID = @ID)
END
请注意,SomeViewOfConcrete2
预计最多 return 一行(在这种情况下,它绝对应该 return 一行,因为我已经设置了适当的外国键。)
所以最后我想运行下面的查询:
SELECT ConcreteID1, ConcreteID2, [dbo].SomeViewOfConcrete2(Concrete2ID)
FROM [dbo].FilterJunction()
但是得到如下错误:
"Cannot find either column "dbo" or the user-defined function or
aggregate "dbo.SomeViewOfConcrete2", or the name is ambiguous."
尽管如果我尝试 运行 SomeViewOfConcrete2
与特定 ConcreteID2
分开,该查询 运行 完全没问题。 (例如 SELECT * FROM [dbo].SomeViewOfConcrete2(1)
我认为问题在于我无法告诉 SQL 函数 return 恰好是一行,因此它不知道如何给出预期的结果集 ConcreteID1, ConcreteID2, Prop2, Prop4
,但该错误消息肯定不能很好地表明这一点。
我可以解决这个问题的一种方法是:
SELECT ConcreteID1, ConcreteID2, Prop2, Prop4
FROM [dbo].FilterJunction() F
JOIN CONCRETE2 C
ON F.ConcreteID2 = C.ID
但这并没有使用 SomeViewOfConcrete2
函数,因此不鼓励代码重用。
所以我很抱歉,但我的问题有点双重:
- 是否可以以鼓励过滤器和查看函数的代码重用的方式设计查询?
- 为什么 SQL 抛出它给出的错误而不说别的?
谢谢。
这是因为 table 值函数被设计为 return 任意数量的行。您不能像这样将 table 作为列进行推送。但是,您可以在此处非常有效地使用 APPLY。
SELECT ConcreteID1
, ConcreteID2
, svc.Prop2 --or whatever columns from that function
, svc.Prop4
FROM [dbo].FilterJunction() fj
cross apply [dbo].SomeViewOfConcrete2(fj.Concrete2ID) svc
我的表格有点像这样(定义不准确请见谅):
CREATE TABLE JunctionTable( int Concrete1ID, int Concrete2ID, int someProperty)
CREATE TABLE Concrete1 ( int ID, int Prop1, int Prop2)
CREATE TABLE Concrete2 ( int ID, int Prop1, int Prop2, int Prop3, int Prop4)
每个具体表都有外键。
而且我有一些功能。一个函数 - FilterJunction
- 获取 JunctionTable
中满足特定条件的东西,另一个函数 - SomeViewofConcrete2
- 给定 Concrete2
行的 return 属性Concrete2ID
.
CREATE FUNCTION [dbo].FilterJunction() Returns Table AS
BEGIN RETURN (SELECT * FROM JunctionTable WHERE someProperty < 5)
END
CREATE FUNCTION [dbo].SomeViewOfConcrete2(@ID int) RETURNS TABLE
BEGIN
Return (SELECT Prop2, Prop4 FROM Concrete2 WHERE ID = @ID)
END
请注意,SomeViewOfConcrete2
预计最多 return 一行(在这种情况下,它绝对应该 return 一行,因为我已经设置了适当的外国键。)
所以最后我想运行下面的查询:
SELECT ConcreteID1, ConcreteID2, [dbo].SomeViewOfConcrete2(Concrete2ID)
FROM [dbo].FilterJunction()
但是得到如下错误:
"Cannot find either column "dbo" or the user-defined function or aggregate "dbo.SomeViewOfConcrete2", or the name is ambiguous."
尽管如果我尝试 运行 SomeViewOfConcrete2
与特定 ConcreteID2
分开,该查询 运行 完全没问题。 (例如 SELECT * FROM [dbo].SomeViewOfConcrete2(1)
我认为问题在于我无法告诉 SQL 函数 return 恰好是一行,因此它不知道如何给出预期的结果集 ConcreteID1, ConcreteID2, Prop2, Prop4
,但该错误消息肯定不能很好地表明这一点。
我可以解决这个问题的一种方法是:
SELECT ConcreteID1, ConcreteID2, Prop2, Prop4
FROM [dbo].FilterJunction() F
JOIN CONCRETE2 C
ON F.ConcreteID2 = C.ID
但这并没有使用 SomeViewOfConcrete2
函数,因此不鼓励代码重用。
所以我很抱歉,但我的问题有点双重:
- 是否可以以鼓励过滤器和查看函数的代码重用的方式设计查询?
- 为什么 SQL 抛出它给出的错误而不说别的?
谢谢。
这是因为 table 值函数被设计为 return 任意数量的行。您不能像这样将 table 作为列进行推送。但是,您可以在此处非常有效地使用 APPLY。
SELECT ConcreteID1
, ConcreteID2
, svc.Prop2 --or whatever columns from that function
, svc.Prop4
FROM [dbo].FilterJunction() fj
cross apply [dbo].SomeViewOfConcrete2(fj.Concrete2ID) svc