SQL Table 值函数
SQL Table valued function
我有一个 Table 值函数如下。但它给出了一个错误。那就是说“消息 156,级别 15,状态 1,过程 GetOpeningByRepAcc,第 36 行
关键字 'begin'."
附近的语法不正确
但我没能解决这个问题。有什么想法吗?
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
我想你多了一个end ... begin
。请尝试以下版本的函数:
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
BEGIN 和 END 未正确关闭:
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
您的函数中有两批 BEGIN... END
这是导致错误的原因。查看您的函数,尽管它可以大大简化,但您执行了几乎相同的查询 3 次,只是对不同的列求和,其中两个是:
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)
);
您可以在一条语句中完成此操作:
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。我已经将你的谓词转换日期更改为 varchars 以比较它们(我假设删除时间)因为这是糟糕的做法,它执行得非常糟糕并且不能在日期列上使用任何索引
考虑到以上几点,我倾向于将其设为内联 TVF,它的性能会好得多:
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)
);
内联 Table 值函数的好处是它们的行为更像视图,因为它们的定义可以扩展到外部查询并随后进行优化,并且不会像 RBAR 那样执行使用 BEGIN...END
的函数
我有一个 Table 值函数如下。但它给出了一个错误。那就是说“消息 156,级别 15,状态 1,过程 GetOpeningByRepAcc,第 36 行 关键字 'begin'."
附近的语法不正确但我没能解决这个问题。有什么想法吗?
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
我想你多了一个end ... begin
。请尝试以下版本的函数:
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
BEGIN 和 END 未正确关闭:
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
您的函数中有两批 BEGIN... END
这是导致错误的原因。查看您的函数,尽管它可以大大简化,但您执行了几乎相同的查询 3 次,只是对不同的列求和,其中两个是:
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)
);
您可以在一条语句中完成此操作:
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。我已经将你的谓词转换日期更改为 varchars 以比较它们(我假设删除时间)因为这是糟糕的做法,它执行得非常糟糕并且不能在日期列上使用任何索引
考虑到以上几点,我倾向于将其设为内联 TVF,它的性能会好得多:
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)
);
内联 Table 值函数的好处是它们的行为更像视图,因为它们的定义可以扩展到外部查询并随后进行优化,并且不会像 RBAR 那样执行使用 BEGIN...END