Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Vấn đề về hàm Sql Câu lệnh cuối cùng được bao gồm trong một hàm phải là câu lệnh trả về

Như lỗi gợi ý, câu lệnh cuối cùng phải là câu lệnh trả về. Không giống như một số ngôn ngữ khác, luồng của IF/ELSE câu lệnh không được kiểm tra trong quá trình biên dịch, vì vậy SQL Server không biết rằng một trong các nhánh là bắt buộc (thậm chí ELSE ). Vì điều này không được kiểm tra nên không có cách nào để biết liệu hàm có trả về giá trị hay không trừ khi câu lệnh cuối cùng là câu lệnh trả về. Ngay cả một chức năng đơn giản như thế này cũng sẽ thất bại:

CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
    IF 1 = 1
    BEGIN
        RETURN 1;
    END
    ELSE
    BEGIN
        RETURN 0;
    END
END

Giải pháp là chỉ cần loại bỏ ELSE :

CREATE FUNCTION dbo.FlowTest()
RETURNS INT
AS
BEGIN
    IF 1 = 1
    BEGIN
        RETURN 1;
    END
    -- ELSE REMOVED
    RETURN 0;

END

Hàm sẽ ngừng thực thi khi đạt đến RETURN đầu tiên , vì vậy ELSE không bắt buộc.

Vì vậy, hàm của bạn sẽ trở thành:

ALTER FUNCTION [dbo].[GetBatchReleaseQuantity]   
(
@i_LocationID VARCHAR(50),
    @i_ProductID INT,
    @i_StartDate VARCHAR(50),  
    @i_EndDate VARCHAR(50),  
    @i_ProductInFlow int
)  
RETURNS numeric(18,3)  
 --WITH ENCRYPTION     
AS  
BEGIN  

  IF (@i_ProductInFlow ='2')
  BEGIN

    RETURN (SElECT  ISNULL( SUM( BatchReleaseQuantity),0.00)  
            FROM    BatchReleaseDetails BRD
                    LEFT OUTER JOIN BatchRelease BR 
                        ON BR.BatchReleaseID=BRD.BatchReleaseID
            WHERE   ProductId = @i_ProductID  
            AND     LocationID = @i_LocationID 
            AND     BRD.CreatedOn >= CONVERT(DATETIME, @i_StartDate+' 00:00:00') 
            AND     BRD.CreatedOn <= CONVERT(DATETIME,@i_EndDate + ' 23:59:59')
        )
  END

  RETURN (  SELECT  ISNULL( SUM( AcceptedQuantity),0.00)  
            FROM    GoodsReceivedNoteDetail GRND
                    LEFT OUTER JOIN GoodsReceivedNote GRN 
                        ON [email protected]_LocationID
            WHERE   ProductId = @i_ProductID  
            AND     GRN.LocationID = @i_LocationID 
            AND     GRND.CreatedOn >= CONVERT(DATETIME, @i_StartDate+' 00:00:00') 
            AND     GRND.CreatedOn <= CONVERT(DATETIME, @i_EndDate+' 23:59:59')
        )
  END 

END

Mặc dù vậy, tôi không thể thấy hàm sẽ hoạt động tốt như thế nào và tại sao bạn lại chuyển ngày dưới dạng varchar nằm ngoài tôi. Bạn không quan tâm đến những thứ được tạo ra từ 23:59:59 đến nửa đêm?

Tôi sẽ có xu hướng cấu trúc lại nó như một hàm được định giá trong bảng nội tuyến và sử dụng ngày tháng đúng cách, ví dụ:

CREATE FUNCTION [dbo].[GetBatchReleaseQuantityTVP]   
(
    @i_LocationID VARCHAR(50),
    @i_ProductID INT,
    @i_StartDate DATE,  
    @i_EndDate DATE,  
    @i_ProductInFlow int
)  
RETURNS TABLE
 --WITH ENCRYPTION     
AS  
RETURN 
(   SElECT  ReturnValue = ISNULL( SUM( BatchReleaseQuantity),0.00)  
    FROM    BatchReleaseDetails BRD
            LEFT OUTER JOIN BatchRelease BR 
                ON BR.BatchReleaseID=BRD.BatchReleaseID
    WHERE   ProductId = @i_ProductID  
    AND     LocationID = @i_LocationID 
    AND     BRD.CreatedOn >= @i_StartDate
    AND     BRD.CreatedOn < DATEADD(DAY, 1, @i_EndDate)
    AND     @i_ProductInFlow ='2'
    UNION ALL
    SELECT  ISNULL(SUM( AcceptedQuantity),0.00)  
    FROM    GoodsReceivedNoteDetail GRND
            LEFT OUTER JOIN GoodsReceivedNote GRN 
                ON [email protected]_LocationID
    WHERE   ProductId = @i_ProductID  
    AND     GRN.LocationID = @i_LocationID 
    AND     GRND.CreatedOn >= @i_StartDate
    AND     GRND.CreatedOn < DATEADD(DAY, 1, @i_EndDate)
    AND     ISNULL(@i_ProductInFlow, '') != '2'
);

Sau đó, bất cứ khi nào bạn gọi dbo.GetBatchReleaseQuantity(...) chỉ cần gọi (SELECT ReturnValue FROM dbo.GetBatchReleaseQuantityTVP(...)) . Điều này sẽ hoạt động tốt hơn đáng kể và cũng sẽ tránh mọi người chuyển ngày không hợp lệ sang tham số varchar.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Không thể tìm thấy đối tượng vì nó không tồn tại hoặc bạn không có quyền. Lỗi trong máy chủ SQL

  2. SQL Server 2016:Tạo một dạng xem

  3. xem các giá trị đã thay đổi sau một tuyên bố cập nhật

  4. khóa duy nhất dựa trên 2 cột trong SQl Server 2008?

  5. Đính kèm nhiều cơ sở dữ liệu bằng T-SQL