当用作IN子查询时,T-SQL表函数不返回行

时间:2014-01-23 07:25:26

标签: sql sql-server function tsql

我有以下TSQL表函数,当它本身用作查询时,它完全按照要求工作:

-- ================================================
-- Template generated from Template Explorer using:
-- Create Multi-Statement Function (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the function.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER FUNCTION dbo.GetReplacements 
(
    -- Add the parameters for the function here
    @ProductId int
)
RETURNS @AvailableReplacements TABLE 
(
    prod_id INT NOT NULL
)
AS
BEGIN
    -- Fill the table variable with the rows for your result set
    DECLARE @tmpKey int
    DECLARE @getReplacementId cursor 
    DECLARE @replacementProductId int = 0
    DECLARE @lastReplacementProductId int = 0
    DECLARE @findAgain bit = 1
    DECLARE @done bit = 0

    BEGIN
        DECLARE @tmpProdIDs TABLE (prod_id int, prep_id int)  
        DECLARE @prod_id_test int

        INSERT INTO @tmpProdIDs (prod_id, prep_id)  

        SELECT  p.prod_id, pr.prep_id FROM Product p INNER JOIN Product_Replacement pr ON p.prod_id = pr.prep_prod_id2 WHERE pr.prep_prod_id1 = @ProductId      

        WHILE @done = 0  

            BEGIN  

                SET @done = 1    
                DECLARE ProductCursor CURSOR  

                FOR SELECT prod_id FROM @tmpProdIDs  

                    OPEN ProductCursor    
                    FETCH ProductCursor INTO @prod_id_test  

                    WHILE @@FETCH_STATUS = 0  

                    BEGIN  

                        INSERT INTO @tmpProdIDs (prod_id, prep_id)        
                        SELECT  p.prod_id,  pr.prep_id FROM Product p INNER JOIN Product_Replacement pr ON p.prod_id = pr.prep_prod_id2 WHERE  pr.prep_prod_id1 = @prod_id_test    

                        IF @@ROWCOUNT > 0  

                        BEGIN    
                            DELETE FROM @tmpProdIDs WHERE prod_id = @prod_id_test    
                            SET @done = 0  

                        END         

                        FETCH ProductCursor INTO @prod_id_test  

                    END  

                    CLOSE ProductCursor    
                    DEALLOCATE ProductCursor 

                END
            END

            INSERT @AvailableReplacements SELECT prep_id FROM @tmpProdIDs
    RETURN 

END
GO

...作为基本查询执行时:

declare @productId int = 869725
SELECT prod_id FROM [dbo].[GetReplacements](@productId)

prod_id
91332
91333

....但是当我尝试将该函数用作子查询的一部分时,即使是一个非常简单的查询,它也不会返回任何行。任何人都可以解释为什么?

declare @productId int = 869725
SELECT *
FROM product p
WHERE p.prod_id IN (SELECT prod_id FROM [dbo].[GetReplacements](@productId))

我不明白在IN子查询中有什么不同意味着它不起作用?

1 个答案:

答案 0 :(得分:0)

所以这里有两个问题!

1)确保子查询所涉及的源表中存在关联的行(感谢Naveen Kumar)

2)确保该功能也返回正确类型的ID。在这种情况下,它返回一个Identity列,而不是Product Id,使得子查询返回值对于IN语句无效!