【问题标题】:Is it possible to use both a filter and a view functions in the same query?是否可以在同一个查询中同时使用过滤器和视图函数?
【发布时间】:2016-06-23 16:35:53
【问题描述】:

我的表格有点像这样(请原谅不准确的定义):

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 - 返回给定 Concrete2IDConcrete2 行的属性。

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 最多只返回一行(在这种情况下,它肯定应该返回一行,因为我已经设置了适当的外键。)

所以最后我想运行以下查询:

SELECT ConcreteID1, ConcreteID2, [dbo].SomeViewOfConcrete2(Concrete2ID)
FROM [dbo].FilterJunction()

但是得到以下错误:

“找不到列“dbo”或用户定义的函数或 聚合“dbo.SomeViewOfConcrete2”,或者名称不明确。”

尽管如果我尝试单独运行 SomeViewOfConcrete2 和特定的 ConcreteID2,该查询运行得非常好。 (例如SELECT * FROM [dbo].SomeViewOfConcrete2(1)

我认为问题在于我无法告诉 SQL 函数只返回一行,所以它不知道如何给出预期的结果集ConcreteID1, ConcreteID2, Prop2, Prop4,但该错误消息肯定不会很好地说明这一点。

我可以解决这个问题的一种方法是:

SELECT ConcreteID1, ConcreteID2, Prop2, Prop4
FROM [dbo].FilterJunction() F
JOIN CONCRETE2 C
ON F.ConcreteID2 = C.ID

但这不使用SomeViewOfConcrete2 函数,因此不鼓励代码重用。

所以我很抱歉,但我的问题有点双重:

  1. 是否可以以鼓励代码重用过滤器和查看功能的方式设计查询?
  2. 为什么 SQL 抛出它给出的错误而不说其他内容?

谢谢。

【问题讨论】:

    标签: sql sql-server user-defined-functions


    【解决方案1】:

    这是因为表值函数旨在返回任意数量的行。你不能只把这样的表格作为一列。但是,您可以在此处非常有效地使用 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
    

    【讨论】:

    • 耶!谢谢!
    • 只要确保您了解交叉应用和外部应用之间的区别。 :) 很高兴您能够为您完成这项工作。
    • 更多金块信息。对于这种情况,给定外键,两者都是可以接受的。但是,我认为如果不是在这种情况下我会想要外部连接的键。谢谢!第一个谷歌结果很有用:mssqltips.com/sqlservertip/1958/…
    猜你喜欢
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 2021-08-11
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多