在游标内使用游标进行更新,它显示没有受影响的行,当我手动尝试时逻辑正在工作
Used Cursor inside cursor for update it is showing o rows effected, logic is working when i tried manually
存储过程
在游标内使用游标进行更新,它显示 0 行受到影响,当我手动尝试时逻辑正在工作,正确地声明和关闭。
我需要做什么更改
或游标以外的任何替代品。
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
ALTER PROCEDURE [dbo].[POS_Discount_Report]
@OutletId INT = NULL,
@FromDate DATE = NULL,
@ToDate DATE = NULL,
@DiscountPercent DECIMAL = NULL
AS
begin
SELECT @CutOffInvoiceAmount = AVG(InvoiceAmount) FROM POS_SalesReceiptMaster WHERE StampDate BETWEEN @FromDate AND @ToDate
DECLARE Receipt_cursor CURSOR FOR
SELECT Id FROM POS_SalesReceiptMaster WHERE StampDate BETWEEN @FromDate AND @ToDate AND InvoiceAmount <= @CutOffInvoiceAmount
OPEN Receipt_cursor
FETCH NEXT FROM Receipt_cursor
INTO @ReceiptId
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE Item_cursor CURSOR FOR
SELECT Id FROM Updated_SalesReceiptItems WHERE ReceiptId = @ReceiptId
OPEN Item_cursor
FETCH NEXT FROM Item_cursor
INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @Percentage = Percentage, @ItemPrice = Price FROM
Updated_SalesReceiptItems WHERE Id = @ID
IF @Percentage = 5
BEGIN
SELECT @UpdatePercentage = Tax5 FROM Updated_Master
Where Percentage = @DiscountPercent
END
ELSE
BEGIN
@UpdatePercentage = 5
END
UPDATE Updated_SalesReceiptItems
SET ProductId = Product.ProductId,
Actualprice = Product.Actualprice,
Quantity = Product.Qty,
ProductName = Product.ProductName,
unit = Product.unit,
CategoryName= Product.CategoryName,
Percentage= Product.Percentage,
Amount = Product.Amount FROM
(SELECT TOP 1 PM.ProductId, ProductCode,
dbo.fn_Get_ProductPrice_By_Outlet(ProductId,@OutletId)
AS
Actualprice,
(CASE WHEN ( dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId) != 0)
THEN (@ItemPrice / dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId))
ELSE 0
END) AS Qty,
ProductName, Unit, CategoryName, @UpdatePercentage AS Percentage,
dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId) * (@UpdatePercentage/100) AS TaxAmount
FROM dbo.Products_Master PM
INNER JOIN ProductCategory_Master CM ON PM.CategoryId = CM.CategoryId
INNER JOIN tax_master TM ON PM.TaxId = TM.Id
WHERE (@ItemPrice) % nullif(dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId),0) = 0
AND Percentage = @UpdatePercentage) Product
WHERE Id = @ID
end
FETCH NEXT FROM Item_cursor
INTO @ID
END
CLOSE Item_cursor;
DEALLOCATE Item_cursor;
FETCH NEXT FROM Receipt_cursor
INTO @ReceiptId
END
CLOSE Receipt_cursor;
DEALLOCATE Receipt_cursor;
END
好吧,这很乱,如果不进行一些修复可能无法工作,但它应该为您提供在单个查询中执行所有这些操作的一般模式?
ALTER PROCEDURE POS_Discount_Report (
@OutletId INT = NULL,
@FromDate DATE = NULL,
@ToDate DATE = NULL,
@DiscountPercent DECIMAL = NULL)
AS
BEGIN
DECLARE @CutOffInvoiceAmount NUMERIC(19,2); --?? seems to be missing from original procedure
SELECT @CutOffInvoiceAmount = AVG(InvoiceAmount) FROM POS_SalesReceiptMaster WHERE StampDate BETWEEN @FromDate AND @ToDate; --What happens if one or both of these is NULL?
--CTEs
WITH Receipt AS (
SELECT Id FROM POS_SalesReceiptMaster WHERE StampDate BETWEEN @FromDate AND @ToDate AND InvoiceAmount <= @CutOffInvoiceAmount),
Item AS (
SELECT Id FROM Updated_SalesReceiptItems s INNER JOIN Receipt r ON s.ReceiptId = r.Id),
PercentQuery AS (
SELECT i.Id, u.[Percentage], u.Price FROM Updated_SalesReceiptItems u INNER JOIN Item i ON u.Id = i.Id),
UpdatePercent AS (
SELECT p.Id, p.[Percentage], p.Price, CASE WHEN p.[Percentage] = 5 THEN u.Tax5 ELSE 5 END AS UpdatePercentage FROM PercentQuery p INNER JOIN Updated_Master u ON u.[Percentage] = @DiscountPercent)
UPDATE
u
SET
ProductId = pm.ProductId,
Actualprice = dbo.fn_Get_ProductPrice_By_Outlet(ProductId, @OutletId),
Quantity =
CASE
WHEN (dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId) != 0)
THEN (@ItemPrice / dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId))
ELSE 0
END,
ProductName = pm.ProductName,
unit = pm.unit, --not sure on the alias here, as it's missing in the original query
CategoryName = pm.CategoryName,
[Percentage] = u.UpdatePercentage,
Amount = dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId) * (u.UpdatePercentage / 100) --although this was TaxAmount originally??!
FROM
dbo.Products_Master pm
INNER JOIN ProductCategory_Master cm ON cm.CategoryId = pm.CategoryId
INNER JOIN tax_master tm ON tm.Id = pm.TaxId
INNER JOIN UpdatePercent up ON up.Id = pm.Id
INNER JOIN Updated_SalesReceiptItems u ON u.Id = up.Id
WHERE
(p.Price) % NULLIF(dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, pm.ProductId), 0) = 0
AND [Percentage] = UpdatePercentage;
END;
基本上,我使用嵌套的 common-table 表达式来执行与原始游标相同的操作,但这些现在是基于集合的。这意味着我可以将结果加入要更新的 table 并一次性执行所有更新。
我几乎可以肯定其中有一些是错误的,因为我可以看到您原始查询中的许多部分似乎不正确?
存储过程 在游标内使用游标进行更新,它显示 0 行受到影响,当我手动尝试时逻辑正在工作,正确地声明和关闭。
我需要做什么更改
或游标以外的任何替代品。
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
ALTER PROCEDURE [dbo].[POS_Discount_Report]
@OutletId INT = NULL,
@FromDate DATE = NULL,
@ToDate DATE = NULL,
@DiscountPercent DECIMAL = NULL
AS
begin
SELECT @CutOffInvoiceAmount = AVG(InvoiceAmount) FROM POS_SalesReceiptMaster WHERE StampDate BETWEEN @FromDate AND @ToDate
DECLARE Receipt_cursor CURSOR FOR
SELECT Id FROM POS_SalesReceiptMaster WHERE StampDate BETWEEN @FromDate AND @ToDate AND InvoiceAmount <= @CutOffInvoiceAmount
OPEN Receipt_cursor
FETCH NEXT FROM Receipt_cursor
INTO @ReceiptId
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE Item_cursor CURSOR FOR
SELECT Id FROM Updated_SalesReceiptItems WHERE ReceiptId = @ReceiptId
OPEN Item_cursor
FETCH NEXT FROM Item_cursor
INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @Percentage = Percentage, @ItemPrice = Price FROM
Updated_SalesReceiptItems WHERE Id = @ID
IF @Percentage = 5
BEGIN
SELECT @UpdatePercentage = Tax5 FROM Updated_Master
Where Percentage = @DiscountPercent
END
ELSE
BEGIN
@UpdatePercentage = 5
END
UPDATE Updated_SalesReceiptItems
SET ProductId = Product.ProductId,
Actualprice = Product.Actualprice,
Quantity = Product.Qty,
ProductName = Product.ProductName,
unit = Product.unit,
CategoryName= Product.CategoryName,
Percentage= Product.Percentage,
Amount = Product.Amount FROM
(SELECT TOP 1 PM.ProductId, ProductCode,
dbo.fn_Get_ProductPrice_By_Outlet(ProductId,@OutletId)
AS
Actualprice,
(CASE WHEN ( dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId) != 0)
THEN (@ItemPrice / dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId))
ELSE 0
END) AS Qty,
ProductName, Unit, CategoryName, @UpdatePercentage AS Percentage,
dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId) * (@UpdatePercentage/100) AS TaxAmount
FROM dbo.Products_Master PM
INNER JOIN ProductCategory_Master CM ON PM.CategoryId = CM.CategoryId
INNER JOIN tax_master TM ON PM.TaxId = TM.Id
WHERE (@ItemPrice) % nullif(dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId),0) = 0
AND Percentage = @UpdatePercentage) Product
WHERE Id = @ID
end
FETCH NEXT FROM Item_cursor
INTO @ID
END
CLOSE Item_cursor;
DEALLOCATE Item_cursor;
FETCH NEXT FROM Receipt_cursor
INTO @ReceiptId
END
CLOSE Receipt_cursor;
DEALLOCATE Receipt_cursor;
END
好吧,这很乱,如果不进行一些修复可能无法工作,但它应该为您提供在单个查询中执行所有这些操作的一般模式?
ALTER PROCEDURE POS_Discount_Report (
@OutletId INT = NULL,
@FromDate DATE = NULL,
@ToDate DATE = NULL,
@DiscountPercent DECIMAL = NULL)
AS
BEGIN
DECLARE @CutOffInvoiceAmount NUMERIC(19,2); --?? seems to be missing from original procedure
SELECT @CutOffInvoiceAmount = AVG(InvoiceAmount) FROM POS_SalesReceiptMaster WHERE StampDate BETWEEN @FromDate AND @ToDate; --What happens if one or both of these is NULL?
--CTEs
WITH Receipt AS (
SELECT Id FROM POS_SalesReceiptMaster WHERE StampDate BETWEEN @FromDate AND @ToDate AND InvoiceAmount <= @CutOffInvoiceAmount),
Item AS (
SELECT Id FROM Updated_SalesReceiptItems s INNER JOIN Receipt r ON s.ReceiptId = r.Id),
PercentQuery AS (
SELECT i.Id, u.[Percentage], u.Price FROM Updated_SalesReceiptItems u INNER JOIN Item i ON u.Id = i.Id),
UpdatePercent AS (
SELECT p.Id, p.[Percentage], p.Price, CASE WHEN p.[Percentage] = 5 THEN u.Tax5 ELSE 5 END AS UpdatePercentage FROM PercentQuery p INNER JOIN Updated_Master u ON u.[Percentage] = @DiscountPercent)
UPDATE
u
SET
ProductId = pm.ProductId,
Actualprice = dbo.fn_Get_ProductPrice_By_Outlet(ProductId, @OutletId),
Quantity =
CASE
WHEN (dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId) != 0)
THEN (@ItemPrice / dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId))
ELSE 0
END,
ProductName = pm.ProductName,
unit = pm.unit, --not sure on the alias here, as it's missing in the original query
CategoryName = pm.CategoryName,
[Percentage] = u.UpdatePercentage,
Amount = dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, ProductId) * (u.UpdatePercentage / 100) --although this was TaxAmount originally??!
FROM
dbo.Products_Master pm
INNER JOIN ProductCategory_Master cm ON cm.CategoryId = pm.CategoryId
INNER JOIN tax_master tm ON tm.Id = pm.TaxId
INNER JOIN UpdatePercent up ON up.Id = pm.Id
INNER JOIN Updated_SalesReceiptItems u ON u.Id = up.Id
WHERE
(p.Price) % NULLIF(dbo.fn_Get_ProductPrice_By_Outlet(@OutletId, pm.ProductId), 0) = 0
AND [Percentage] = UpdatePercentage;
END;
基本上,我使用嵌套的 common-table 表达式来执行与原始游标相同的操作,但这些现在是基于集合的。这意味着我可以将结果加入要更新的 table 并一次性执行所有更新。
我几乎可以肯定其中有一些是错误的,因为我可以看到您原始查询中的许多部分似乎不正确?