Tom
Tom

Reputation: 1373

SQL Table valued function

I have a Table Valued Function as following. But it is giving a error. That is saying "Msg 156, Level 15, State 1, Procedure GetOpeningByRepAcc, Line 36 Incorrect syntax near the keyword 'begin'."

But I didn't able to fix this. Any idea please?

create FUNCTION [dbo].[GetOpeningByRepAcc]
(
 @Date datetime,@AccId int,@CenterId datetime,@ItemId int
)
RETURNS @ReturnData TABLE
(
Opening decimal(10,3),
Topup decimal(10,3),
Returnsv decimal(10,3)
)
as
begin   
declare @opening decimal(10,3)
declare @topup decimal(10,3)
declare @returns decimal(10,3)

set @opening = (SELECT sum(OpeningQty)
FROM DailyItemStock
WHERE DistributionCenterId = @CenterId AND 
SalesRepAccId = @AccId AND ItemMasterId = @ItemId
and convert(varchar(10),StockDate,111) = convert(varchar(10),@Date,111))

set @topup = (SELECT     sum(Qty)
FROM         DailyItemStockTopUp
WHERE     
convert(varchar(10),TopupDate,111) = CONVERT(varchar(10), getdate(), 111)
AND DistributionCenterId = @CenterId AND SalesRepAccId = @AccId 
AND ItemMasterId =      @ItemId)

set @returns = (SELECT sum(TotReturns)
FROM DailyItemStock
WHERE DistributionCenterId = @CenterId AND 
SalesRepAccId = @AccId AND ItemMasterId = @ItemId
and convert(varchar(10),StockDate,111) = convert(varchar(10),@Date,111))
end

begin
insert @ReturnData
select @opening,@topup,@returns

return 
end

Upvotes: 2

Views: 2449

Answers (3)

GarethD
GarethD

Reputation: 69749

You have two lots of BEGIN... END in your function this is causing the error. Looking at your function though it can be simplified hugely, you are performing pretty much the same query 3 times, just summing different columns, two of them are:

SET @Topup = (  SELECT  SUM(Qty)
                FROM    DailyItemStock
                WHERE   DistributionCenterId = @CenterId 
                AND     SalesRepAccId = @AccId 
                AND     ItemMasterId = @ItemId
                AND     CONVERT(VARCHAR(10),TopupDate,111) = CONVERT(VARCHAR(10), GETDATE(), 111)
            );

SET @returns = (SELECT  SUM(TotReturns)
                FROM    DailyItemStock
                WHERE   DistributionCenterId = @CenterId 
                AND     SalesRepAccId = @AccId 
                AND     ItemMasterId = @ItemId
                AND     CONVERT(VARCHAR(10),TopupDate,111) = CONVERT(VARCHAR(10), GETDATE(), 111)
            );

You can do this in a single statement:

SELECT  @Topup = SUM(Qty),
        @returns = SUM(TotReturns)
FROM    DailyItemStock
WHERE   DistributionCenterId = @CenterId 
AND     SalesRepAccId = @AccId 
AND     ItemMasterId = @ItemId
AND     CAST(StockDate AS DATE) = CAST(GETDATE() AS DATE);

n.b. I have changed your predicate converting dates to varchars to compare them (I assume to remove the time) as this is awful practice, it performs terribly and can't use any indexes on the date columns

With the above in mind, I would be inclined to make this an inline TVF, it will perform much better:

CREATE FUNCTION [dbo].[GetOpeningByRepAcc]
(
    @Date       DATETIME,
    @AccId      INT,
    @CenterId   DATETIME,
    @ItemId     INT
)
RETURNS TABLE 
AS
RETURN
(   SELECT  Opening = SUM(OpeningQty),
            Topup = SUM(Qty),
            Returnsv = SUM(TotReturns)
    FROM    DailyItemStock
    WHERE   DistributionCenterId = @CenterId 
    AND     SalesRepAccId = @AccId 
    AND     ItemMasterId = @ItemId
    AND     CAST(StockDate AS DATE) = CAST(GETDATE() AS DATE)
);

The benefit of inline Table valued functions is that they behave more like views, in that their definition can be expanded out into the outer query and subsequently optimised, and are not executed RBAR like functions that use BEGIN...END

Upvotes: 3

knkarthick24
knkarthick24

Reputation: 3216

BEGIN and END are not properly closed:

CREATE FUNCTION [dbo].[Getopeningbyrepacc] (@Date     DATETIME,
                                            @AccId    INT,
                                            @CenterId DATETIME,
                                            @ItemId   INT)
RETURNS @ReturnData TABLE (
  Opening  DECIMAL(10, 3),
  Topup    DECIMAL(10, 3),
  Returnsv DECIMAL(10, 3))
AS
  BEGIN
      DECLARE @opening DECIMAL(10, 3)
      DECLARE @topup DECIMAL(10, 3)
      DECLARE @returns DECIMAL(10, 3)

      SET @opening = (SELECT Sum(OpeningQty)
                      FROM   DailyItemStock
                      WHERE  DistributionCenterId = @CenterId
                             AND SalesRepAccId = @AccId
                             AND ItemMasterId = @ItemId
                             AND CONVERT(VARCHAR(10), StockDate, 111) = CONVERT(VARCHAR(10), @Date, 111))
      SET @topup = (SELECT Sum(Qty)
                    FROM   DailyItemStockTopUp
                    WHERE  CONVERT(VARCHAR(10), TopupDate, 111) = CONVERT(VARCHAR(10), Getdate(), 111)
                           AND DistributionCenterId = @CenterId
                           AND SalesRepAccId = @AccId
                           AND ItemMasterId = @ItemId)
      SET @returns = (SELECT Sum(TotReturns)
                      FROM   DailyItemStock
                      WHERE  DistributionCenterId = @CenterId
                             AND SalesRepAccId = @AccId
                             AND ItemMasterId = @ItemId
                             AND CONVERT(VARCHAR(10), StockDate, 111) = CONVERT(VARCHAR(10), @Date, 111))

      BEGIN
          INSERT @ReturnData
          SELECT @opening,
                 @topup,
                 @returns

          RETURN
      END
  END 

Upvotes: 0

user2941651
user2941651

Reputation:

I think that you have one extra end ... begin. Please try the following version of you function:

create FUNCTION [dbo].[GetOpeningByRepAcc]
(
 @Date datetime,@AccId int,@CenterId datetime,@ItemId int
)
RETURNS @ReturnData TABLE
(
Opening decimal(10,3),
Topup decimal(10,3),
Returnsv decimal(10,3)
)
as
begin   
    declare @opening decimal(10,3)
    declare @topup decimal(10,3)
    declare @returns decimal(10,3)

    set @opening = (SELECT sum(OpeningQty)
    FROM DailyItemStock
    WHERE DistributionCenterId = @CenterId AND 
    SalesRepAccId = @AccId AND ItemMasterId = @ItemId
    and convert(varchar(10),StockDate,111) = convert(varchar(10),@Date,111))

    set @topup = (SELECT     sum(Qty)
    FROM         DailyItemStockTopUp
    WHERE     
    convert(varchar(10),TopupDate,111) = CONVERT(varchar(10), getdate(), 111)
    AND DistributionCenterId = @CenterId AND SalesRepAccId = @AccId 
    AND ItemMasterId =      @ItemId)

    set @returns = (SELECT sum(TotReturns)
    FROM DailyItemStock
    WHERE DistributionCenterId = @CenterId AND 
    SalesRepAccId = @AccId AND ItemMasterId = @ItemId
    and convert(varchar(10),StockDate,111) = convert(varchar(10),@Date,111))

    insert into @ReturnData
    select @opening,@topup,@returns

    return 
end

Upvotes: 0

Related Questions