将多语句表值函数(TVF)更改为内联TVF

时间:2010-11-25 00:13:53

标签: sql-server tsql sql-server-2008

使用SQLServer 2008。

多语句TVF示例:

CREATE TABLE DBO.DECTEST (ID INT NOT NULL PRIMARY KEY, 
V1 DECIMAL(18,6) NOT NULL, V2 DECIMAL(18,6) NOT NULL)

INSERT DECTEST VALUES (1, 23.1234, 25.22)

GO

DROP FUNCTION DBO.F_DECTEST1
GO
CREATE FUNCTION DBO.F_DECTEST1
(
@ID INT
)
RETURNS @RESULT TABLE
(   
    V1 DECIMAL(18,6),
    V2 DECIMAL(18,6)
)
AS 
BEGIN
    DECLARE @V1 DECIMAL (18,6)
    DECLARE @V2 DECIMAL(18,6)
    SELECT @V1 = V1, @V2 = V2 FROM DBO.DECTEST WHERE ID = @ID

    INSERT @RESULT (V1, V2) VALUES (ISNULL(@V1, 0), ISNULL(@V2, 0))
    RETURN
END
GO

我想将其更改为内联TVF(出于性能原因)。请注意,结果集中始终返回一行 - 即使传递了不存在的ID。有干净的方法吗?

2 个答案:

答案 0 :(得分:1)

不知道这是否更好,但你可以尝试一下......

CREATE FUNCTION DBO.F_DECTEST1 
( 
@ID INT 
) 
RETURNS TABLE 
AS  
RETURN
(
   SELECT V1, V2 FROM DBO.DECTEST WHERE ID = @ID 
   UNION ALL
   SELECT NULL AS V1, NULL AS V2 WHERE NOT EXISTS (SELECT 1 FROM DBO.DECTEST WHERE ID = @ID)
)

另外,为什么不使用带有输出参数的存储过程?由于ID是唯一的,您只需要返回一行。

答案 1 :(得分:0)

对于任何仍然感兴趣的人,这就是我所追求的(请注意,我应该在我的原始示例中真正使列V1和V2为NULL,以便更多地反映我之后的内容):

CREATE FUNCTION DBO.F_DECTEST1
(
@ID INT
)
RETURNS TABLE
AS 
RETURN
(
    SELECT ISNULL(w.V1, 0) AS V1 , ISNULL(w.V2, 0) AS V2
    FROM 
    (SELECT @ID AS ID) s 
    OUTER APPLY
    (
        SELECT V1, V2 FROM DBO.DECTEST WHERE ID = s.ID
    ) w
)