Since somebody asked for an cursor example, here is one. :-) Nobody won't like this example, since it's too long. You don't have to read through the SPROC if you don't want. If the moderator think it's not proper, just delete it. :-)
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Asset_ShoppingCartSubmit]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[Asset_ShoppingCartSubmit]
GO
CREATE Procedure Asset_ShoppingCartSubmit
(
@CartID nvarchar(50),
@UserID int,
@OrderTypeID int,
@OrderStatusID int,
@ShippingMethodID int,
@FromSLXLocationID nvarchar(12),
@ToSLXLocationID nvarchar(12),
@TrackingNumber char(25),
@PONumber char(25),
@NumberOfBox int,
@PortalID int,
@UserRegionCodeID int,
@Succeeded bit output,
@AssetOrderID int output
)
AS
-- User Begin Tran and Save Tran to simulate Begin New Transaction
-- The rollback in this sp won't affect outer transactions since it only rollback to save point
declare @Trancount int
select @Trancount = @@Trancount
if @TranCount = 0
Begin Tran SubmitTran
else
Save Tran SubmitTran
declare @RegionCodeID int
declare @ShippingAccountCode varchar(25)
select @RegionCodeID = RegionCodeID from Users where UserID = @UserID
select @ShippingAccountCode = ShippingAccountCode from AssetRegionCodes where @UserRegionCodeID = RegionCodeID
select @Succeeded = 1
EXEC [AssetOrder_Insert]
@UserID,
@OrderTypeID,
@OrderStatusID,
@ShippingMethodID ,
@FromSLXLocationID,
@ToSLXLocationID,
@TrackingNumber,
@PONumber,
@NumberOfBox,
@RegionCodeID,
@ShippingAccountCode,
@UserRegionCodeID,
@AssetOrderID OUTPUT
if @@error > 0 goto errorlabel
--reset @RegionCodeID
select @RegionCodeID = @UserRegionCodeID
-- Move to Order table
declare @CartOrderType as Varchar(30)
select @CartOrderType = substring(@CartID, charindex(':',@CartID) + 1, 100)
-- Update KitID, KitQuantity for Kit Orders
-- It's useful only for Make Kit Reader orders
-- Might be used for other order types in future
declare @KitID int
declare @KitQuantity int
select @KitID = max(KitID),
@KitQuantity = max(KitQuantity)
from Asset_ShoppingCart
where CartID = @CartID
select @KitID = isnull(@KitID,0),
@KitQuantity = isnull(@KitQuantity,0)
if @CartOrderType = 'TFWKIT'
begin
-- @KitID is actually Make Bundle Ready Order ID , see Asset_ShoppingCartAddKitToLocation
-- The logic is too complicated, maybe need to clean up code in future
-- Calvin Guo #05/20/2003
update AssetOrder
set KitID = (select KitID from AssetOrder where AssetOrderID = @KitID), --Get the actual KitID
KitQuantity = @KitQuantity
where AssetOrderID = @AssetOrderID
if @@error > 0 goto errorlabel
-- Update Old Order, take away its Kit Quantity and its status
update AssetOrder
set KitQuantity = KitQuantity - @KitQuantity
where AssetOrderID = @KitID
if @@error > 0 goto errorlabel
update AssetOrder
set OrderStatusID = aos.OrderStatusID
from AssetOrder ao,
AssetOrderStatuses aos
where AssetOrderID = @KitID
and KitQuantity = 0
and ao.OrderStatusID = aos.OrderStatusID
and aos.Abrev = 'Comp&Tran'
if @@error > 0 goto errorlabel
end
else
begin
update AssetOrder
set KitID = @KitID,
KitQuantity = @KitQuantity
where AssetOrderID = @AssetOrderID
if @@error > 0 goto errorlabel
end
--=========================================
if @CartOrderType = 'ADDKIT'
or @CartOrderType = 'TBLKIT'
or @CartOrderType = 'TTWKIT'
or @CartOrderType = 'TFW'
or @CartOrderType = 'MR'
or @CartOrderType = 'TFWKIT'
or @CartOrderType = 'PRECONFIG'
or @CartOrderType = 'COMMONORDERED'
INSERT [dbo].[AssetOrderDetail]
(
[AssetOrderID],
[AssetID],
[Quantity],
[StatusID],
[AssetPartNoID],
[CategoryID],
[Charge]
)
select @AssetOrderID,
asp.ProductID,
asp.Quantity,
asp.StatusID,
asp.ProductID, --It's actually PartNoID
asp.CategoryID,
asp.Value
FROM
Asset_ShoppingCart asp
WHERE
asp.CartID = @CartID
else
INSERT [dbo].[AssetOrderDetail]
(
[AssetOrderID],
[AssetID],
[Quantity],
[StatusID],
[AssetPartNoID],
[CategoryID],
[Charge]
)
select @AssetOrderID,
asp.ProductID,
asp.Quantity,
asp.StatusID,
a.PartNoID,
asp.CategoryID,
asp.Value
FROM
Asset_ShoppingCart asp,
Assets a
WHERE
asp.CartID = @CartID
AND
A.AssetID = asp.ProductID
-- Clean up the Shopping cart
delete
Asset_ShoppingCart
WHERE
CartID = @CartID
if @@error > 0 goto errorlabel
if @CartOrderType = 'PRECONFIG' or @CartOrderType = 'COMMONORDERED'
goto EndProcess
--Mark Asset table as assets are not available for query since they are in order now
--Get Audit Number
declare @AuditNum as int
declare @AssetID as int
declare @Quantity as int
declare @StatusID as int
declare @Charge as money
declare @NewAssetID as int
declare @CategoryID as int
declare @OrderTypeAbrev as nvarchar(25)
declare @AssetOrderDetailID as int
EXEC [GetAssetAuditNumber] @UserID,@AuditNum output
if @@error > 0 goto errorlabel
select @OrderTypeAbrev = Abrev from AssetorderTypes where OrderTypeID = @OrderTypeID
DECLARE order_cursor insensitive CURSOR FOR
SELECT AssetOrderDetailID, AssetID, Quantity, StatusID, Charge, CategoryID
from AssetOrderDetail
Where AssetOrderID = @AssetOrderID
For Read Only
OPEN order_cursor
FETCH NEXT FROM order_cursor
INTO @AssetOrderDetailID, @AssetID, @Quantity, @StatusID, @Charge, @CategoryID
WHILE @@FETCH_STATUS = 0
BEGIN
if @Quantity <= 0
begin
-- Delete the original Order Detail
delete AssetOrderDetail Where AssetOrderDetailID = @AssetOrderDetailID
FETCH NEXT FROM order_cursor
INTO @AssetOrderDetailID, @AssetID, @Quantity, @StatusID, @Charge, @CategoryID
continue
end
if @CartOrderType <> 'ADDKIT'
and @CartOrderType <> 'TBLKIT'
and @CartOrderType <> 'TTWKIT'
and @CartOrderType <> 'TFW'
and @CartOrderType <> 'MR'
and @CartOrderType <> 'TFWKIT'
begin
-- When Transfer to warehouse/disposal, the original location should retain
if @OrderTypeAbrev = 'TTID' or @OrderTypeAbrev = 'TTW' or @OrderTypeAbrev = 'MRKIT'
select @ToSLXLocationID = SLXLocationID from Assets where AssetID = @AssetID
EXEC [UpdateAsset] @PortalID=@PortalID,
@UserID = @UserID,
@AssetID = @AssetID,
@AuditNum = @AuditNum,
@newStatusID = @StatusID,
@newSLXLocationID = @ToSLXLocationID,
@QuantityToMove = @Quantity,
@CostPerItem = @Charge,
@newAssetID = @NewAssetID OUTPUT
if @Quantity = (select Quantity From Assets where AssetID = @NewAssetID)
Update Assets set OrderNumber = @AssetOrderID where AssetID = @NewAssetID
else
goto ErrorLabel
end
else
-- Kit order, or the asset id actually recorded as PartNoID
begin
-- need to make sure there're enough assets with the same PartNoID to transfer
Declare @OrderAssetID int
Declare @OrderQuantity int
select @Charge = @Charge / @Quantity
-- When Transfer from warehouse, whould not care it's from location, since it's probably from any where.
if @OrderTypeAbrev = 'TFW' or @OrderTypeAbrev = 'TFWKIT' or @OrderTypeAbrev = 'MR'
select @FromSLXLocationID = null
DECLARE partno_cursor CURSOR FOR
SELECT a.AssetID , a.Quantity
from Assets a left outer join Location L on a.SLXLocationID = L.LocationID, AssetStatuses ast
Where PartNoID = @AssetID -- @AssetID is ProductID in shopping cart!!! which actually recorded PartNoID for TFW orders
and a.StatusID = ast.StatusID
and a.PortalID = @PortalID
and a.SLXLocationID = isnull(@FromSLXLocationID,a.SLXLocationID)
and case @OrderTypeAbrev
when 'TFW' then
case when @RegionCodeID =0 or L.RegionCodeID = @RegionCodeID
then ' RGNEW RGREF '
else ''
end
when 'MR' then ' OSS DEFST '
else ' RGNEW RGREF OSS DEFST FSNEW FSREF IS '
end
like '% ' + ast.Abrev + ' %'
and a.OrderNumber = case @OrderTypeAbrev
when 'TFWKIT' then @KitID -- It's actual the Make Bundle Ready Order ID
else 0 end
order by
case
when @OrderTypeAbrev <> 'TFW' and @OrderTypeAbrev <> 'MR' then 1
when @RegionCodeID = 0 then 1
when @RegionCodeID = L.RegionCodeID then 1
else 2
end asc,
case ast.Abrev when 'RGNEW' then 1
when 'RGREF' then 2
when 'OSS' then 3
when 'DEFST' then 4
when 'FSNEW' then 5
when 'FSREF' then 6
when 'IS' then 7
end
asc
OPEN partno_cursor
FETCH NEXT FROM partno_cursor
INTO @OrderAssetID, @OrderQuantity
-- Delete the original Order Detail
delete AssetOrderDetail Where AssetOrderDetailID = @AssetOrderDetailID
WHILE @@FETCH_STATUS = 0 and @Quantity > 0
BEGIN
if @OrderQuantity > @Quantity
select @OrderQuantity = @Quantity
select @Quantity = @Quantity - @OrderQuantity
if @OrderQuantity > 0
begin
EXEC [UpdateAsset] @PortalID=@PortalID,
@UserID = @UserID,
@AssetID = @OrderAssetID,
@AuditNum = @AuditNum,
@newStatusID = @StatusID,
@newSLXLocationID = @ToSLXLocationID,
@QuantityToMove = @OrderQuantity,
@CostPerItem = @Charge,
@newAssetID = @NewAssetID OUTPUT
Update Assets set OrderNumber = @AssetOrderID
where AssetID = @NewAssetID
INSERT [dbo].[AssetOrderDetail]
(
[AssetOrderID],
[AssetID],
[Quantity],
[StatusID],
[AssetPartNoID],
[CategoryID],
[Charge]
)
select @AssetOrderID,
@newAssetID,
@OrderQuantity,
@StatusID,
PartNoID,
CategoryID,
0
from Assets
where AssetID = @newAssetID
end
if @Quantity > 0
FETCH NEXT FROM partno_cursor
INTO @OrderAssetID, @OrderQuantity
else
break
end
CLOSE partno_cursor
DEALLOCATE partno_cursor
if @Quantity > 0
begin
select @Succeeded = 0
break
end
end
FETCH NEXT FROM order_cursor
INTO @AssetOrderDetailID, @AssetID, @Quantity, @StatusID, @Charge, @CategoryID
END
CLOSE order_cursor
DEALLOCATE order_cursor
goto EndProcess
errorlabel:
Select @Succeeded = 0
EndProcess:
if @Succeeded = 0
rollback tran SubmitTran
else
if @Trancount = 0
commit tran SubmitTran
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
cklein
Participant
1561 Points
363 Posts
Re: Again, SPROC VS Dynamic SQL, performance wise
Aug 29, 2003 01:11 AM|LINK
SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Asset_ShoppingCartSubmit]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) drop procedure [dbo].[Asset_ShoppingCartSubmit] GO CREATE Procedure Asset_ShoppingCartSubmit ( @CartID nvarchar(50), @UserID int, @OrderTypeID int, @OrderStatusID int, @ShippingMethodID int, @FromSLXLocationID nvarchar(12), @ToSLXLocationID nvarchar(12), @TrackingNumber char(25), @PONumber char(25), @NumberOfBox int, @PortalID int, @UserRegionCodeID int, @Succeeded bit output, @AssetOrderID int output ) AS -- User Begin Tran and Save Tran to simulate Begin New Transaction -- The rollback in this sp won't affect outer transactions since it only rollback to save point declare @Trancount int select @Trancount = @@Trancount if @TranCount = 0 Begin Tran SubmitTran else Save Tran SubmitTran declare @RegionCodeID int declare @ShippingAccountCode varchar(25) select @RegionCodeID = RegionCodeID from Users where UserID = @UserID select @ShippingAccountCode = ShippingAccountCode from AssetRegionCodes where @UserRegionCodeID = RegionCodeID select @Succeeded = 1 EXEC [AssetOrder_Insert] @UserID, @OrderTypeID, @OrderStatusID, @ShippingMethodID , @FromSLXLocationID, @ToSLXLocationID, @TrackingNumber, @PONumber, @NumberOfBox, @RegionCodeID, @ShippingAccountCode, @UserRegionCodeID, @AssetOrderID OUTPUT if @@error > 0 goto errorlabel --reset @RegionCodeID select @RegionCodeID = @UserRegionCodeID -- Move to Order table declare @CartOrderType as Varchar(30) select @CartOrderType = substring(@CartID, charindex(':',@CartID) + 1, 100) -- Update KitID, KitQuantity for Kit Orders -- It's useful only for Make Kit Reader orders -- Might be used for other order types in future declare @KitID int declare @KitQuantity int select @KitID = max(KitID), @KitQuantity = max(KitQuantity) from Asset_ShoppingCart where CartID = @CartID select @KitID = isnull(@KitID,0), @KitQuantity = isnull(@KitQuantity,0) if @CartOrderType = 'TFWKIT' begin -- @KitID is actually Make Bundle Ready Order ID , see Asset_ShoppingCartAddKitToLocation -- The logic is too complicated, maybe need to clean up code in future -- Calvin Guo #05/20/2003 update AssetOrder set KitID = (select KitID from AssetOrder where AssetOrderID = @KitID), --Get the actual KitID KitQuantity = @KitQuantity where AssetOrderID = @AssetOrderID if @@error > 0 goto errorlabel -- Update Old Order, take away its Kit Quantity and its status update AssetOrder set KitQuantity = KitQuantity - @KitQuantity where AssetOrderID = @KitID if @@error > 0 goto errorlabel update AssetOrder set OrderStatusID = aos.OrderStatusID from AssetOrder ao, AssetOrderStatuses aos where AssetOrderID = @KitID and KitQuantity = 0 and ao.OrderStatusID = aos.OrderStatusID and aos.Abrev = 'Comp&Tran' if @@error > 0 goto errorlabel end else begin update AssetOrder set KitID = @KitID, KitQuantity = @KitQuantity where AssetOrderID = @AssetOrderID if @@error > 0 goto errorlabel end --========================================= if @CartOrderType = 'ADDKIT' or @CartOrderType = 'TBLKIT' or @CartOrderType = 'TTWKIT' or @CartOrderType = 'TFW' or @CartOrderType = 'MR' or @CartOrderType = 'TFWKIT' or @CartOrderType = 'PRECONFIG' or @CartOrderType = 'COMMONORDERED' INSERT [dbo].[AssetOrderDetail] ( [AssetOrderID], [AssetID], [Quantity], [StatusID], [AssetPartNoID], [CategoryID], [Charge] ) select @AssetOrderID, asp.ProductID, asp.Quantity, asp.StatusID, asp.ProductID, --It's actually PartNoID asp.CategoryID, asp.Value FROM Asset_ShoppingCart asp WHERE asp.CartID = @CartID else INSERT [dbo].[AssetOrderDetail] ( [AssetOrderID], [AssetID], [Quantity], [StatusID], [AssetPartNoID], [CategoryID], [Charge] ) select @AssetOrderID, asp.ProductID, asp.Quantity, asp.StatusID, a.PartNoID, asp.CategoryID, asp.Value FROM Asset_ShoppingCart asp, Assets a WHERE asp.CartID = @CartID AND A.AssetID = asp.ProductID -- Clean up the Shopping cart delete Asset_ShoppingCart WHERE CartID = @CartID if @@error > 0 goto errorlabel if @CartOrderType = 'PRECONFIG' or @CartOrderType = 'COMMONORDERED' goto EndProcess --Mark Asset table as assets are not available for query since they are in order now --Get Audit Number declare @AuditNum as int declare @AssetID as int declare @Quantity as int declare @StatusID as int declare @Charge as money declare @NewAssetID as int declare @CategoryID as int declare @OrderTypeAbrev as nvarchar(25) declare @AssetOrderDetailID as int EXEC [GetAssetAuditNumber] @UserID,@AuditNum output if @@error > 0 goto errorlabel select @OrderTypeAbrev = Abrev from AssetorderTypes where OrderTypeID = @OrderTypeID DECLARE order_cursor insensitive CURSOR FOR SELECT AssetOrderDetailID, AssetID, Quantity, StatusID, Charge, CategoryID from AssetOrderDetail Where AssetOrderID = @AssetOrderID For Read Only OPEN order_cursor FETCH NEXT FROM order_cursor INTO @AssetOrderDetailID, @AssetID, @Quantity, @StatusID, @Charge, @CategoryID WHILE @@FETCH_STATUS = 0 BEGIN if @Quantity <= 0 begin -- Delete the original Order Detail delete AssetOrderDetail Where AssetOrderDetailID = @AssetOrderDetailID FETCH NEXT FROM order_cursor INTO @AssetOrderDetailID, @AssetID, @Quantity, @StatusID, @Charge, @CategoryID continue end if @CartOrderType <> 'ADDKIT' and @CartOrderType <> 'TBLKIT' and @CartOrderType <> 'TTWKIT' and @CartOrderType <> 'TFW' and @CartOrderType <> 'MR' and @CartOrderType <> 'TFWKIT' begin -- When Transfer to warehouse/disposal, the original location should retain if @OrderTypeAbrev = 'TTID' or @OrderTypeAbrev = 'TTW' or @OrderTypeAbrev = 'MRKIT' select @ToSLXLocationID = SLXLocationID from Assets where AssetID = @AssetID EXEC [UpdateAsset] @PortalID=@PortalID, @UserID = @UserID, @AssetID = @AssetID, @AuditNum = @AuditNum, @newStatusID = @StatusID, @newSLXLocationID = @ToSLXLocationID, @QuantityToMove = @Quantity, @CostPerItem = @Charge, @newAssetID = @NewAssetID OUTPUT if @Quantity = (select Quantity From Assets where AssetID = @NewAssetID) Update Assets set OrderNumber = @AssetOrderID where AssetID = @NewAssetID else goto ErrorLabel end else -- Kit order, or the asset id actually recorded as PartNoID begin -- need to make sure there're enough assets with the same PartNoID to transfer Declare @OrderAssetID int Declare @OrderQuantity int select @Charge = @Charge / @Quantity -- When Transfer from warehouse, whould not care it's from location, since it's probably from any where. if @OrderTypeAbrev = 'TFW' or @OrderTypeAbrev = 'TFWKIT' or @OrderTypeAbrev = 'MR' select @FromSLXLocationID = null DECLARE partno_cursor CURSOR FOR SELECT a.AssetID , a.Quantity from Assets a left outer join Location L on a.SLXLocationID = L.LocationID, AssetStatuses ast Where PartNoID = @AssetID -- @AssetID is ProductID in shopping cart!!! which actually recorded PartNoID for TFW orders and a.StatusID = ast.StatusID and a.PortalID = @PortalID and a.SLXLocationID = isnull(@FromSLXLocationID,a.SLXLocationID) and case @OrderTypeAbrev when 'TFW' then case when @RegionCodeID =0 or L.RegionCodeID = @RegionCodeID then ' RGNEW RGREF ' else '' end when 'MR' then ' OSS DEFST ' else ' RGNEW RGREF OSS DEFST FSNEW FSREF IS ' end like '% ' + ast.Abrev + ' %' and a.OrderNumber = case @OrderTypeAbrev when 'TFWKIT' then @KitID -- It's actual the Make Bundle Ready Order ID else 0 end order by case when @OrderTypeAbrev <> 'TFW' and @OrderTypeAbrev <> 'MR' then 1 when @RegionCodeID = 0 then 1 when @RegionCodeID = L.RegionCodeID then 1 else 2 end asc, case ast.Abrev when 'RGNEW' then 1 when 'RGREF' then 2 when 'OSS' then 3 when 'DEFST' then 4 when 'FSNEW' then 5 when 'FSREF' then 6 when 'IS' then 7 end asc OPEN partno_cursor FETCH NEXT FROM partno_cursor INTO @OrderAssetID, @OrderQuantity -- Delete the original Order Detail delete AssetOrderDetail Where AssetOrderDetailID = @AssetOrderDetailID WHILE @@FETCH_STATUS = 0 and @Quantity > 0 BEGIN if @OrderQuantity > @Quantity select @OrderQuantity = @Quantity select @Quantity = @Quantity - @OrderQuantity if @OrderQuantity > 0 begin EXEC [UpdateAsset] @PortalID=@PortalID, @UserID = @UserID, @AssetID = @OrderAssetID, @AuditNum = @AuditNum, @newStatusID = @StatusID, @newSLXLocationID = @ToSLXLocationID, @QuantityToMove = @OrderQuantity, @CostPerItem = @Charge, @newAssetID = @NewAssetID OUTPUT Update Assets set OrderNumber = @AssetOrderID where AssetID = @NewAssetID INSERT [dbo].[AssetOrderDetail] ( [AssetOrderID], [AssetID], [Quantity], [StatusID], [AssetPartNoID], [CategoryID], [Charge] ) select @AssetOrderID, @newAssetID, @OrderQuantity, @StatusID, PartNoID, CategoryID, 0 from Assets where AssetID = @newAssetID end if @Quantity > 0 FETCH NEXT FROM partno_cursor INTO @OrderAssetID, @OrderQuantity else break end CLOSE partno_cursor DEALLOCATE partno_cursor if @Quantity > 0 begin select @Succeeded = 0 break end end FETCH NEXT FROM order_cursor INTO @AssetOrderDetailID, @AssetID, @Quantity, @StatusID, @Charge, @CategoryID END CLOSE order_cursor DEALLOCATE order_cursor goto EndProcess errorlabel: Select @Succeeded = 0 EndProcess: if @Succeeded = 0 rollback tran SubmitTran else if @Trancount = 0 commit tran SubmitTran GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GOhttp://www.raincoder.com
Equal parts art and science
Email: cguo@raincoder.com