Looping a Delete SP - tsql

I need to some help trying to create some handling for this SP I'm creating which currently looks like this...
alter PROCEDURE ArchiveCampaignData
#CampaignId INT,
#DeleteBatchOf INT
AS
BEGIN
BEGIN
DECLARE #Rowcount INT = 1
WHILE #Rowcount > 0
DELETE TOP (#DeleteBatchOf)FROM dbo.u_activity
OUTPUT DELETED.* INTO u_activity_archive
WHERE campaignId = #CampaignId
SET #Rowcount = ##ROWCOUNT
END
BEGIN
DECLARE #Rowcount2 INT = 1
WHILE #Rowcount2 > 0
DELETE TOP (#DeleteBatchOf) C
OUTPUT DELETED.* INTO dbo.u_contact_archive
FROM dbo.U_contact AS C
INNER JOIN dbo.U_Campaigncontact AS CON WITH(NOLOCK)ON C.id = CON.contactId
WHERE CON.campaignId = #CampaignId
SET #Rowcount2 = ##ROWCOUNT
END
BEGIN
DECLARE #Rowcount3 INT = 1
WHILE #Rowcount3 > 0
DELETE TOP (#DeleteBatchOf) FROM u_campaignContact
OUTPUT Deleted.* INTO u_campaignContact_archive
WHERE campaignId = #CampaignId
SET #Rowcount3 = ##ROWCOUNT
END
BEGIN
DECLARE #Rowcount4 INT = 1
WHILE #Rowcount4 > 0
DELETE TOP (#DeleteBatchOf) L
OUTPUT DELETED.* INTO dbo.dxi_CDRLog_Archive
FROM dbo.dxi_CDRLog AS L
INNER JOIN dbo.u_campaignHdr AS H WITH(NOLOCK)ON L.qid = H.diallerCampaignId
WHERE H.parentId = #CampaignId
SET #Rowcount4 = ##ROWCOUNT
END
BEGIN
DECLARE #Rowcount5 INT = 1
WHILE #Rowcount5 > 0
DELETE TOP(#DeleteBatchOf) T
OUTPUT Deleted.* INTO dxi_diallerStatsSmall_archive
FROM dbo.dxi_diallerStatsSmall AS T
INNER JOIN dbo.u_campaignHdr AS G WITH (NOLOCK) ON G.diallerCampaignId = T.campaign
WHERE G.id = #CampaignId
SET #Rowcount5 = ##ROWCOUNT
END
BEGIN
DECLARE #Rowcount6 INT = 1
WHILE #Rowcount6 > 0
DELETE TOP(#DeleteBatchOf) FROM dbo.u_campaignHdr
OUTPUT Deleted.* INTO u_campaignHdr_archive
WHERE Id = #CampaignId OR parentId = #CampaignId
SET #Rowcount6 = ##ROWCOUNT
END
END
the goal is for each block to loop in the SP to run at a time and once each block is completed that block will stop its transaction and it will move on to the next block as well as printing 'Completed' after each successful delete.
Any recommendations/Enhancements will be appreciated .

Related

Optimize very long stored procedure

I have stored procedure like this. I am posting body of procedure it has too many parameters and I have to many control for cheking warehouse activities.
And it becomes huge and I cant control it. What ll be the best aproach for optimizing this.
DECLARE #ORDERFICHEREF INT =488
DECLARE #STFICHEREF INT =560
DECLARE #CLIENTREF INT =608
DECLARE #BARCODE VARCHAR(50)='1536011000010'
DECLARE #ISPARTIAL BIT=0
DECLARE #TERMINALREF INT=1
DECLARE #PARAMETERREF INT=0
DECLARE #PARTIALAMOUNT FLOAT=1
DECLARE #PARTIALUOMREF INT=59
DECLARE #PARTIALCONVFACT1 INT =1
DECLARE #PARTIALCONVFACT2 INT =50
DECLARE #RESULT INT
DECLARE #FICHENO VARCHAR(20)
DECLARE #STATUS SMALLINT
DECLARE #BRANCH SMALLINT
DECLARE #SOURCEINDEX SMALLINT
DECLARE #BARCODEREF INT
DECLARE #ITEMREF INT
DECLARE #VARIANTREF INT
DECLARE #USREF INT
DECLARE #UOMREF INT
DECLARE #CONVFACT1 FLOAT
DECLARE #CONVFACT2 FLOAT
DECLARE #LSTAMOUNT FLOAT
DECLARE #USELABELUNITA INT
DECLARE #CHECKTYPE INT
DECLARE #ISEAN BIT
DECLARE #BARCODESPECODE VARCHAR(50)
DECLARE #PRICE FLOAT
SET #ISEAN=0
SET #CHECKTYPE =-1
SET #RESULT=0
DECLARE #SHIPINFOREF INT
SELECT #FICHENO =ORF.FICHENO,#STATUS=ORF.[STATUS],#BRANCH=ORF.BRANCH,#SOURCEINDEX=ORF.SOURCEINDEX
FROM ORDERFICHE ORF
INNER JOIN ORDERFICHE_TERMINAL ORFT ON ORF.LOGICALREF=ORFT.ORDERFICHEREF
WHERE ORF.LOGICALREF=#ORDERFICHEREF AND ORFT.TERMINALREF=#TERMINALREF
IF (#STATUS IS NULL OR (#STATUS NOT IN (0,1,6)))
BEGIN
SET #RESULT=14 --Fişe terminal atanmış ve fiş statusu tamamlandıdan küçük olacak
GOTO RESULT
END
SELECT
#BARCODEREF=LBL.LOGICALREF,
#ITEMREF=LBL.ITEMREF,
#VARIANTREF=LBL.VARIANTREF,
#UOMREF=LBL.UOMREF,
#USREF=LBL.USREF,
#CONVFACT1 = LBL.CONVFACT1,
#CONVFACT2 = LBL.CONVFACT2,
#LSTAMOUNT=SUM(CAST(CAST(STL.AMOUNT*STL.CONVFACT2/STL.CONVFACT1*(2-IOCODE)/ABS(2-IOCODE) AS NUMERIC(28,6)) AS FLOAT)),
#BARCODESPECODE = LBL.SPECODE
FROM LABEL_CARD LBL
LEFT OUTER JOIN STLINE STL ON LBL.LOGICALREF=STL.BARCODEREF AND STL.BRANCH=#BRANCH AND STL.SOURCEINDEX=#SOURCEINDEX
WHERE LBL.BARCODE=#BARCODE
GROUP BY LBL.LOGICALREF,LBL.ITEMREF,LBL.VARIANTREF,LBL.USREF,LBL.UOMREF,LBL.CONVFACT2,LBL.CONVFACT1,LBL.AMOUNT,STL.BRANCH,STL.SOURCEINDEX,LBL.SPECODE
--BARKOD - CARİ,SEVKİYAT ADRES KONTROLU
DECLARE #LABELCLINETREF INT
DECLARE #LABELLGORFICHEREF INT
DECLARE #LABELLGORFLINEREF INT
DECLARE #LABELSHIPINFOREF INT
IF(#BARCODEREF IS NOT NULL AND (SELECT CONVERT(BIT,VALUE) FROM ORDER_PARAMETER WHERE PARAMETERREF=86)=0) --Cari hesap için yazdırılmış etiket farklı cariye satılsın mı?
BEGIN
SELECT #SHIPINFOREF=SHIPINFOREF FROM STFICHE WHERE LOGICALREF=#STFICHEREF
SELECT #LABELCLINETREF=CLIENTREF,#LABELLGORFICHEREF=LGORFICHEREF,#LABELLGORFLINEREF=LGORFLINEREF,#LABELSHIPINFOREF=SHIPINFOREF
FROM LABEL_CARD_LGREFERENCE WHERE BARCODEREF=#BARCODEREF AND ISCANCELLED=0
IF(#LABELCLINETREF<>#CLIENTREF)
BEGIN
SET #RESULT=57 -- BAŞKA CARİ İÇİN YAZDIRILMIŞ ETİKET
GOTO RESULT
END
IF (ISNULL(#LABELSHIPINFOREF,0)>0)
BEGIN
IF(ISNULL(#LABELSHIPINFOREF,0)<>ISNULL(#SHIPINFOREF,0))
BEGIN
SET #RESULT=58 -- SEVKİYAT ADRESLERİ FARKLI
GOTO RESULT
END
END
END
IF (#BARCODEREF IS NULL )
BEGIN
DECLARE #EANCHARCOUNT INT
SELECT #EANCHARCOUNT=ISNULL(VALUE,0) FROM ORDER_PARAMETER WHERE PARAMETERREF=60
IF #EANCHARCOUNT>0
BEGIN
SET #BARCODE=LEFT(#BARCODE,#EANCHARCOUNT)
END
SELECT #ITEMREF=UB.ITEMREF,#VARIANTREF=ISNULL(UB.VARIANTREF,0),#UOMREF=UB.UNITLINEREF,#USREF=ITM.UNITSETREF,#CONVFACT1 = IUA.CONVFACT1,#CONVFACT2 =IUA.CONVFACT2
FROM {0}..LG_{1}_UNITBARCODE UB
JOIN {0}..LG_{1}_ITEMS ITM ON ITM.LOGICALREF=UB.ITEMREF
JOIN {0}..LG_{1}_ITMUNITA IUA ON IUA.UNITLINEREF=UB.UNITLINEREF AND IUA.LOGICALREF=UB.ITMUNITAREF AND UB.VARIANTREF=IUA.VARIANTREF
WHERE UB.TYP IN (0,1) AND UB.BARCODE=#BARCODE
IF ISNULL(#ITEMREF,0)=0
BEGIN
SET #RESULT=1 -- #ITEMREF NULL GELİYORSA EAN BARKOD YOK --Barkod LABEL_CARD'da ya sa UNITBARCODE da olmalı
GOTO RESULT
END
SET #ISEAN=1
SELECT #CHECKTYPE=CONVERT(INT,VALUE) FROM ORDER_PARAMETER WHERE PARAMETERREF=53
IF(#CHECKTYPE=0)
BEGIN
SELECT #LSTAMOUNT=SUM(CAST(CAST(AMOUNT*CONVFACT2/CONVFACT1*(2-IOCODE)/ABS(2-IOCODE) AS NUMERIC(28,6)) AS FLOAT))
FROM STLINE
WHERE BRANCH=#BRANCH AND SOURCEINDEX=#SOURCEINDEX AND ITEMREF=#ITEMREF AND VARIANTREF=#VARIANTREF AND BARCODEREF IS NULL
END
IF(#CHECKTYPE=1)
BEGIN
SELECT #LSTAMOUNT=SUM(CAST(CAST(AMOUNT*(2.5-IOCODE)/ABS(2.5-IOCODE)*(UINFO2/UINFO1) AS NUMERIC(28,6)) AS FLOAT))
FROM {0}..LG_{1}_{2}_STLINE
WHERE SOURCEINDEX=#SOURCEINDEX AND STOCKREF=#ITEMREF AND VARIANTREF=#VARIANTREF AND CANCELLED=0 AND LPRODSTAT = 0 AND UINFO1>0 AND UINFO2>0
END
IF((SELECT CONVERT(BIT,VALUE) FROM ORDER_PARAMETER WHERE PARAMETERREF=54)=1)
BEGIN
SET #PARTIALAMOUNT=1
SET #PARTIALUOMREF = #UOMREF
SET #PARTIALCONVFACT1 = #CONVFACT1
SET #PARTIALCONVFACT2 = #CONVFACT2
END
IF(#CHECKTYPE=1)
BEGIN
DECLARE #BACKAMOUNT FLOAT
SELECT #BACKAMOUNT=ISNULL(CAST(CAST(SUM(STL.AMOUNT*STL.CONVFACT2/STL.CONVFACT1) AS NUMERIC(28,6)) AS FLOAT) ,0)
FROM STLINE STL
INNER JOIN ORDERFICHE ORF ON ORF.LOGICALREF=STL.ORDERFICHEREF
WHERE ORF.STATUS<>3 AND STL.IOCODE=4 AND ITEMREF=#ITEMREF AND VARIANTREF=#VARIANTREF AND BARCODEREF IS NULL AND ORF.SOURCEINDEX=#SOURCEINDEX
SET #LSTAMOUNT=#LSTAMOUNT-#BACKAMOUNT
END
END
ELSE
BEGIN
--PARAMETEREREF=44
IF((SELECT DBO.FNC_EXPIRATIONDATE (#BARCODEREF,44))=1)
BEGIN
SET #RESULT=46
GOTO RESULT
END
END
IF(#CHECKTYPE<>2)
BEGIN
IF (#LSTAMOUNT IS NULL )
BEGIN
IF #CHECKTYPE=-1 AND EXISTS (SELECT NULL
FROM STLINE
WHERE BARCODEREF=#BARCODEREF AND (BRANCH<>#BRANCH OR SOURCEINDEX <> #SOURCEINDEX)
GROUP BY BARCODEREF
HAVING SUM(CAST(CAST(AMOUNT*(2-IOCODE)/ABS(2-IOCODE)*(CONVFACT2/CONVFACT1) AS NUMERIC(28,6)) AS FLOAT))>0)
BEGIN
SET #RESULT=55 --Barkod başka bir ambarda
GOTO RESULT
END
IF #CHECKTYPE=0 AND EXISTS (SELECT NULL
FROM STLINE
WHERE ITEMREF=#ITEMREF AND VARIANTREF=#VARIANTREF AND BARCODEREF IS NULL AND (BRANCH<>#BRANCH OR SOURCEINDEX <> #SOURCEINDEX)
GROUP BY ITEMREF,VARIANTREF,USREF
HAVING SUM(CAST(CAST(AMOUNT*(2-IOCODE)/ABS(2-IOCODE)*(CONVFACT2/CONVFACT1) AS NUMERIC(28,6)) AS FLOAT))>0)
BEGIN
SET #RESULT=55 --Barkod başka bir ambarda
GOTO RESULT
END
IF #CHECKTYPE=1 AND EXISTS (SELECT NULL
FROM {0}..LG_{1}_{2}_STLINE
WHERE STOCKREF=#ITEMREF AND VARIANTREF=#VARIANTREF AND CANCELLED=0 AND LPRODSTAT = 0 AND UINFO1>0 AND UINFO2>0 AND SOURCEINDEX <> #SOURCEINDEX
GROUP BY STOCKREF,VARIANTREF,USREF
HAVING SUM(CAST(CAST(AMOUNT*(2.5-IOCODE)/ABS(2.5-IOCODE)*(UINFO2/UINFO1) AS NUMERIC(28,6)) AS FLOAT))>0)
BEGIN
SET #RESULT=55 --Barkod başka bir ambarda
GOTO RESULT
END
SET #RESULT=2 --Barkod Stokta olmalı - Girişi yapılmamış ürün
GOTO RESULT
END
IF (#LSTAMOUNT<=0)
BEGIN
IF EXISTS (SELECT 1 FROM STLINE WHERE STFICHEREF=#STFICHEREF AND BARCODEREF=#BARCODEREF)
BEGIN
SET #RESULT=15 --Barkod Stokta olmalı - Mevcut emirde okutulmuş
GOTO RESULT
END
ELSE
BEGIN
SET #RESULT=3 --Barkod Stokta olmalı - Çıkışı yapılmış
GOTO RESULT
END
END
END
IF((#ISPARTIAL=0 OR #ISEAN=1) AND #PARTIALAMOUNT IS NOT NULL)
BEGIN
SET #LSTAMOUNT=#PARTIALAMOUNT
SET #UOMREF = #PARTIALUOMREF
SET #CONVFACT1 = #PARTIALCONVFACT1
SET #CONVFACT2 = #PARTIALCONVFACT2
END
IF EXISTS (SELECT 1 FROM ORDERLINE WHERE ORDERFICHEREF=#ORDERFICHEREF AND STFICHEREF=#STFICHEREF)
BEGIN
DECLARE #ORLCOUNT INT
SELECT #USELABELUNITA=USELABELCARDUNITA FROM LABEL_PARAMETERS WHERE LOGICALREF=1
SELECT #ORLCOUNT=COUNT(LOGICALREF) FROM ORDERLINE WHERE STFICHEREF=#STFICHEREF AND ITEMREF=#ITEMREF AND VARIANTREF=#VARIANTREF AND USREF = #USREF
IF (ISNULL(#ORLCOUNT,0)=0)
BEGIN
SET #RESULT=13 --ITEMREF emirde olmalı
GOTO RESULT
END
IF (#ISEAN=1 AND ISNULL(#PARTIALAMOUNT,0)=0)
BEGIN
SET #RESULT=11
GOTO RESULT
END
IF(#ISPARTIAL=0 AND #ISEAN=0)
BEGIN
IF NOT EXISTS(SELECT NULL FROM ORDERLINE ORL
INNER JOIN LABEL_CARD_UNITA LBLA ON LBLA.BARCODEREF = #BARCODEREF AND ORL.UOMREF = LBLA.UOMREF
WHERE ORL.STFICHEREF=#STFICHEREF AND ORL.ITEMREF=#ITEMREF AND ORL.VARIANTREF=#VARIANTREF)
BEGIN
IF #USELABELUNITA=1
BEGIN
SET #RESULT=54 --etiket birim miktarı girilmelidir.
GOTO RESULT
END
END
DECLARE #TOAMOUNT FLOAT
DECLARE #TSAMOUNT FLOAT
SELECT #TOAMOUNT=CAST(CAST(SUM(ORL.AMOUNT*CASE WHEN LCU.LOGICALREF IS NULL THEN CASE WHEN #USELABELUNITA =1 THEN 0 ELSE ORL.CONVFACT2/ORL.CONVFACT1 END ELSE LCU.CONVFACT2/LCU.CONVFACT1 END)AS NUMERIC(28,6)) AS FLOAT)
FROM ORDERLINE ORL
LEFT OUTER JOIN LABEL_CARD_UNITA LCU ON LCU.BARCODEREF = #BARCODEREF AND ORL.UOMREF = LCU.UOMREF
WHERE ORL.STFICHEREF=#STFICHEREF AND ORL.ITEMREF=#ITEMREF AND ORL.VARIANTREF=#VARIANTREF
SELECT #TSAMOUNT=CAST(CAST(SUM(STL.AMOUNT*(STL.CONVFACT2/STL.CONVFACT1))AS NUMERIC(28,6)) AS FLOAT)
FROM ORDERLINE ORL
INNER JOIN STLINE STL ON ORL.LOGICALREF = STL.ORDERLINEREF
WHERE ORL.STFICHEREF=#STFICHEREF AND ORL.ITEMREF=#ITEMREF AND ORL.VARIANTREF=#VARIANTREF
--Parçalı seri barkod emir miktar aşımı kontrolü için parçalı miktar ana birime çevriliyor.
DECLARE #MAINAMOUNT FLOAT
SET #MAINAMOUNT=#LSTAMOUNT
IF(#ISPARTIAL=0 AND #ISEAN=0 AND #PARTIALAMOUNT IS NOT NULL)
BEGIN
SET #MAINAMOUNT=#MAINAMOUNT*#CONVFACT2/#CONVFACT1
END
--IF (#MAINAMOUNT+ ISNULL(#TSAMOUNT,0)> ISNULL(#TOAMOUNT,0))
IF EXISTS(SELECT * FROM ORDER_PARAMETER WHERE PARAMETERREF=118 AND VALUE=0)
BEGIN
IF (CAST(CAST((ISNULL(#MAINAMOUNT,0)+ISNULL(#TSAMOUNT,0))AS NUMERIC(28,6))AS FLOAT)> ISNULL(CAST(CAST(#TOAMOUNT AS NUMERIC(28,6)) AS FLOAT),0))
BEGIN
SET #RESULT=25 --Emir miktarı aşılmamalı
GOTO RESULT
END
END
END
IF((#ISEAN=1) AND #PARTIALAMOUNT IS NOT NULL)
BEGIN
DECLARE #PTOAMOUNT FLOAT
DECLARE #PTSAMOUNT FLOAT
SELECT #PTOAMOUNT=ORL.AMOUNT,#PTSAMOUNT=CAST(CAST(SUM(STL.AMOUNT*(STL.CONVFACT2/STL.CONVFACT1))AS NUMERIC(28,6)) AS FLOAT) FROM ORDERLINE ORL
LEFT OUTER JOIN STLINE STL ON ORL.LOGICALREF=STL.ORDERLINEREF
WHERE ORL.STFICHEREF=#STFICHEREF AND ORL.ITEMREF=#ITEMREF AND ORL.VARIANTREF=#VARIANTREF AND ORL.UOMREF=#UOMREF
GROUP BY ORL.LOGICALREF,ORL.AMOUNT
IF EXISTS(SELECT * FROM ORDER_PARAMETER WHERE PARAMETERREF=118 AND VALUE=0)
BEGIN
IF(CAST(CAST((#LSTAMOUNT + ISNULL(#PTSAMOUNT,0))AS NUMERIC(28,6))AS FLOAT) > ISNULL(#PTOAMOUNT,0))
BEGIN
SET #RESULT=25 --Emir miktarı aşılmamalı
GOTO RESULT
END
END
END
END
DECLARE #FIFOCONTROL INT
SELECT #FIFOCONTROL=DBO.FNC_ENTRYDATE(#BARCODEREF,#BRANCH,#SOURCEINDEX,#PARAMETERREF)
IF #FIFOCONTROL>0
BEGIN
SET #RESULT=24
GOTO RESULT
END
IF(#ISEAN=0)
BEGIN
DECLARE #ISCOUNTING SMALLINT
SELECT #ISCOUNTING=DBO.FNC_ISCOUNTING(#BRANCH,#SOURCEINDEX,#ITEMREF,#VARIANTREF,#BARCODEREF)
IF (#ISCOUNTING=2) --SAYIMDA OKUTULMAMIS MALZEME
BEGIN
SET #RESULT=21
GOTO RESULT
END
END
IF (#ISPARTIAL=1 OR (#ISEAN=1 AND ISNULL(#PARTIALAMOUNT,0)=0))
BEGIN
SET #RESULT=11 --miktar girilmeli
GOTO RESULT
END
-- HAREKET ÖZEL KODU
DECLARE #SPECODE VARCHAR(50)
IF EXISTS(SELECT * FROM ORDER_PARAMETER WHERE PARAMETERREF=101 AND VALUE=1)
BEGIN
IF (#ISEAN=0)
BEGIN
SET #SPECODE = #BARCODESPECODE
END
ELSE IF (#ISEAN=1)
BEGIN
SET #SPECODE = #EANSPECODE
END
END
DECLARE #ORDERLINEREF INT
DECLARE #DATE DATETIME
SET #ORDERLINEREF=NULL
IF (ISNULL(#ORLCOUNT,0)>1)
BEGIN
DECLARE #CUOMREF INT
DECLARE #COAMOUNT FLOAT
DECLARE #CSAMOUNT FLOAT
DECLARE #CURRAMOUNT FLOAT
DECLARE #CCONVFACT1 FLOAT
DECLARE #CCONVFACT2 FLOAT
DECLARE CURSOR_SORDER CURSOR FOR SELECT LOGICALREF,AMOUNT,UOMREF,CONVFACT1,CONVFACT2 FROM ORDERLINE WHERE STFICHEREF=#STFICHEREF AND ITEMREF=#ITEMREF AND VARIANTREF=#VARIANTREF ORDER BY (CASE WHEN UOMREF=#UOMREF THEN 0 ELSE 1 END),ISNULL(LGORFICHEREF,2147483647)
OPEN CURSOR_SORDER
FETCH NEXT FROM CURSOR_SORDER INTO #ORDERLINEREF,#COAMOUNT,#CUOMREF,#CCONVFACT1,#CCONVFACT2
WHILE (##FETCH_STATUS = 0)
BEGIN
IF (ISNULL(#LSTAMOUNT,0)<=0)
BEGIN
BREAK
END
SET #CURRAMOUNT=0
IF((#ISEAN=1 OR #ISPARTIAL=0) AND #PARTIALAMOUNT IS NOT NULL)
BEGIN
SET #CURRAMOUNT=#LSTAMOUNT
--SET #CONVFACT1 = #CCONVFACT1
--SET #CONVFACT2 = #CCONVFACT2
END
ELSE
BEGIN
SELECT #CURRAMOUNT=#LSTAMOUNT*(CONVFACT1/CONVFACT2),#CONVFACT1=CONVFACT1,#CONVFACT2=CONVFACT2 FROM LABEL_CARD_UNITA WHERE BARCODEREF =#BARCODEREF AND UOMREF =#CUOMREF
END
IF (ISNULL(#USELABELUNITA,0)=0 AND #CURRAMOUNT =0)
BEGIN
SET #CURRAMOUNT = #LSTAMOUNT*#CCONVFACT1/#CCONVFACT2
SET #CONVFACT1 = #CCONVFACT1
SET #CONVFACT2 = #CCONVFACT2
END
SELECT #CSAMOUNT=ISNULL(SUM(CAST(CAST(AMOUNT AS NUMERIC(28,6)) AS FLOAT)),0) FROM STLINE WHERE STFICHEREF=#STFICHEREF AND ORDERLINEREF=#ORDERLINEREF AND ITEMREF=#ITEMREF AND VARIANTREF=#VARIANTREF AND UOMREF=#CUOMREF
IF (#COAMOUNT>#CSAMOUNT AND ISNULL(#CURRAMOUNT,0)>0)
BEGIN
IF (#COAMOUNT >= #CSAMOUNT + (#CURRAMOUNT))
BEGIN
SET #LSTAMOUNT=0
END
ELSE
BEGIN
SET #CURRAMOUNT = (#COAMOUNT - #CSAMOUNT)
SET #LSTAMOUNT=#LSTAMOUNT-#CURRAMOUNT
END
SET #DATE=GETDATE()
--SELECT 'bir', #STFICHEREF,8,4,#ITEMREF,#VARIANTREF,#BARCODEREF,#CURRAMOUNT,#CUOMREF,#USREF,#CONVFACT1,#CONVFACT2,#CLIENTREF,#BRANCH,#SOURCEINDEX,NULL,NULL,#DATE,#ORDERFICHEREF,#ORDERLINEREF,NULL,NULL,NULL,#TERMINALREF,#SPECODE
EXEC MOB_STLINE_INSERT #STFICHEREF,8,4,#ITEMREF,#VARIANTREF,#BARCODEREF,#CURRAMOUNT,#CUOMREF,#USREF,#CONVFACT1,#CONVFACT2,#CLIENTREF,#BRANCH,#SOURCEINDEX,NULL,NULL,#DATE,#ORDERFICHEREF,#ORDERLINEREF,NULL,NULL,NULL,#TERMINALREF,#SPECODE
END
FETCH NEXT FROM CURSOR_SORDER INTO #ORDERLINEREF,#COAMOUNT,#CUOMREF,#CCONVFACT1,#CCONVFACT2
END
CLOSE CURSOR_SORDER
DEALLOCATE CURSOR_SORDER
END
ELSE
BEGIN
DECLARE #LUSTAMOUNT FLOAT
SET #DATE=GETDATE()
IF (ISNULL(#ORLCOUNT,0)=1)
BEGIN
DECLARE #OCONVFACT1 FLOAT
DECLARE #OCONVFACT2 FLOAT
SELECT #ORDERLINEREF=LOGICALREF,#UOMREF=UOMREF,#OCONVFACT1=CONVFACT1,#OCONVFACT2=CONVFACT2 FROM ORDERLINE WHERE STFICHEREF=#STFICHEREF AND ITEMREF=#ITEMREF AND VARIANTREF=#VARIANTREF
IF((#ISEAN=1 OR #ISPARTIAL=0) AND #PARTIALAMOUNT IS NOT NULL)
BEGIN
SET #LUSTAMOUNT=#LSTAMOUNT
END
ELSE
BEGIN
SELECT #LUSTAMOUNT=#LSTAMOUNT*CONVFACT1/CONVFACT2,#CONVFACT1=CONVFACT1,#CONVFACT2=CONVFACT2 FROM LABEL_CARD_UNITA WHERE BARCODEREF =#BARCODEREF AND UOMREF =#UOMREF
IF (#LUSTAMOUNT IS NULL)
BEGIN
SET #LUSTAMOUNT = #LSTAMOUNT*#OCONVFACT1/#OCONVFACT2
SET #CONVFACT1=#OCONVFACT1
SET #CONVFACT2=#OCONVFACT2
END
END
END
IF #LUSTAMOUNT IS NULL
BEGIN
IF((#ISEAN=1 OR #ISPARTIAL=0) AND #PARTIALAMOUNT IS NOT NULL)
BEGIN
SET #LUSTAMOUNT=#LSTAMOUNT
END
ELSE
BEGIN
SET #LUSTAMOUNT=#LSTAMOUNT*#CONVFACT1/#CONVFACT2
END
END
--SELECT 'iki', #STFICHEREF,8,4,#ITEMREF,#BARCODEREF,ISNULL(#LUSTAMOUNT,#LSTAMOUNT),#UOMREF,#USREF,#CONVFACT1,#CONVFACT2,#CLIENTREF,#BRANCH,#SOURCEINDEX,NULL,NULL,#DATE,#ORDERFICHEREF,#ORDERLINEREF,NULL,NULL,NULL,#TERMINALREF,#SPECODE
EXEC MOB_STLINE_INSERT #STFICHEREF,8,4,#ITEMREF,#VARIANTREF,#BARCODEREF,#LUSTAMOUNT,#UOMREF,#USREF,#CONVFACT1,#CONVFACT2,#CLIENTREF,#BRANCH,#SOURCEINDEX,NULL,NULL,#DATE,#ORDERFICHEREF,#ORDERLINEREF,NULL,NULL,NULL,#TERMINALREF,#SPECODE
END
IF (#STATUS=0 OR #STATUS=6)
BEGIN
UPDATE ORDERFICHE SET [STATUS]=1 WHERE LOGICALREF=#ORDERFICHEREF
INSERT INTO RECORD_LOG (MODULEREF,RECORDID,IDENTITYINFO,USERREF,TERMINALREF,PROCESSDATE,[TYPE],[DESCRIPTION])
VALUES (103,#ORDERFICHEREF,'Emir Numarası:' + ' ' + #FICHENO,NULL,#TERMINALREF,#DATE,16,'Durumu : Yükleniyor')
END
RESULT:
SELECT ISNULL(#RESULT,0) [RESULT]
IF (#ISPARTIAL=1 OR #ISEAN=1)
BEGIN
SELECT ISNULL(#LSTAMOUNT,0) [LSTAMOUNT],#ISEAN [ISEAN],#CHECKTYPE [CHECKTYPE],(SELECT TOP 1 UOMREF FROM ORDERLINE WHERE STFICHEREF=#STFICHEREF AND ITEMREF=#ITEMREF AND VARIANTREF=#VARIANTREF ORDER BY (CASE WHEN UOMREF=#UOMREF THEN 0 ELSE 1 END),ISNULL(LGORFICHEREF,2147483647)) [ORDERUOMREF]
IF(#ISEAN=1)
BEGIN
SELECT UNL.LOGICALREF,UNL.CODE,UNL.MAINUNIT,ISNULL(ORL.CONVFACT1,ITMA.CONVFACT1) [CONVFACT1],ISNULL(ORL.CONVFACT2,ITMA.CONVFACT2) [CONVFACT2],
CASE WHEN ORL.LOGICALREF IS NULL THEN 0 ELSE 1 END [ORDERUNIT],
CASE WHEN ITMA.UNITLINEREF = #UOMREF THEN 1 ELSE 0 END [DEFAULTUNIT],
ORL.AMOUNT - SUM(CAST(CAST(ISNULL(STL.AMOUNT,0) AS NUMERIC(28,6)) AS FLOAT)) [OAMOUNT]
FROM {0}..LG_{1}_ITMUNITA ITMA
INNER JOIN {0}..LG_{1}_UNITSETL UNL ON ITMA.UNITLINEREF = UNL.LOGICALREF
LEFT OUTER JOIN ORDERLINE ORL ON ORL.ORDERFICHEREF = #ORDERFICHEREF AND ORL.STFICHEREF = #STFICHEREF AND ORL.ITEMREF = ITMA.ITEMREF AND ORL.VARIANTREF = ITMA.VARIANTREF AND ORL.UOMREF = ITMA.UNITLINEREF
LEFT OUTER JOIN STLINE STL ON ORL.LOGICALREF = STL.ORDERLINEREF
WHERE ITMA.ITEMREF = #ITEMREF AND ITMA.VARIANTREF = #VARIANTREF
GROUP BY UNL.LINENR,UNL.LOGICALREF,UNL.CODE,UNL.MAINUNIT,ORL.CONVFACT1,ITMA.CONVFACT1,ORL.CONVFACT2,ITMA.CONVFACT2,ORL.LOGICALREF,ITMA.UNITLINEREF,ORL.AMOUNT
ORDER BY UNL.LINENR
END
ELSE
BEGIN
IF((#USELABELUNITA=1 AND ISNULL(#ORLCOUNT,0)>0) OR (ISNULL(#ORLCOUNT,0)=0))
BEGIN
SELECT UNL.LOGICALREF,UNL.CODE,UNL.MAINUNIT,LBLA.CONVFACT1 [CONVFACT1],LBLA.CONVFACT2 [CONVFACT2],
CASE WHEN ORL.LOGICALREF IS NULL THEN 0 ELSE 1 END [ORDERUNIT],
CASE WHEN LBLA.UOMREF = #UOMREF THEN 1 ELSE 0 END [DEFAULTUNIT],
ORL.AMOUNT - SUM(CAST(CAST(ISNULL(STL.AMOUNT,0) AS NUMERIC(28,6)) AS FLOAT)) [OAMOUNT]
FROM LABEL_CARD_UNITA LBLA
INNER JOIN {0}..LG_{1}_UNITSETL UNL ON LBLA.UOMREF = UNL.LOGICALREF
LEFT OUTER JOIN ORDERLINE ORL ON ORL.ORDERFICHEREF = #ORDERFICHEREF AND ORL.STFICHEREF = #STFICHEREF AND ORL.ITEMREF = #ITEMREF AND ORL.VARIANTREF = #VARIANTREF AND ORL.UOMREF = LBLA.UOMREF
LEFT OUTER JOIN STLINE STL ON ORL.LOGICALREF = STL.ORDERLINEREF
WHERE LBLA.BARCODEREF = #BARCODEREF
GROUP BY UNL.LINENR,UNL.LOGICALREF,UNL.CODE,UNL.MAINUNIT,ORL.CONVFACT1,LBLA.CONVFACT1,ORL.CONVFACT2,LBLA.CONVFACT2,ORL.LOGICALREF,LBLA.UOMREF,ORL.AMOUNT
ORDER BY UNL.LINENR
END
ELSE IF(#USELABELUNITA=0 AND ISNULL(#ORLCOUNT,0)>0)
BEGIN
SELECT * FROM (
SELECT UNL.LINENR,UNL.LOGICALREF ,UNL.CODE,UNL.MAINUNIT,LBLA.CONVFACT1 [CONVFACT1],LBLA.CONVFACT2 [CONVFACT2],
CASE WHEN ORL.LOGICALREF IS NULL THEN 0 ELSE 1 END [ORDERUNIT],
CASE WHEN LBLA.UOMREF = #UOMREF THEN 1 ELSE 0 END [DEFAULTUNIT],
ORL.AMOUNT - SUM(CAST(CAST(ISNULL(STL.AMOUNT,0) AS NUMERIC(28,6)) AS FLOAT)) [OAMOUNT],ORL.LOGICALREF [ORDERLINEREF]
FROM LABEL_CARD_UNITA LBLA
INNER JOIN {0}..LG_{1}_UNITSETL UNL ON LBLA.UOMREF = UNL.LOGICALREF
LEFT OUTER JOIN ORDERLINE ORL ON ORL.ORDERFICHEREF = #ORDERFICHEREF AND ORL.STFICHEREF = #STFICHEREF AND ORL.ITEMREF = #ITEMREF AND ORL.VARIANTREF = #VARIANTREF AND ORL.UOMREF = LBLA.UOMREF
LEFT OUTER JOIN STLINE STL ON ORL.LOGICALREF = STL.ORDERLINEREF
WHERE LBLA.BARCODEREF = #BARCODEREF
GROUP BY UNL.LINENR,UNL.LOGICALREF,UNL.CODE,UNL.MAINUNIT,ORL.CONVFACT1,LBLA.CONVFACT1,ORL.CONVFACT2,LBLA.CONVFACT2,ORL.LOGICALREF,LBLA.UOMREF,ORL.AMOUNT
UNION ALL
SELECT UNL.LINENR,UNL.LOGICALREF ,UNL.CODE,UNL.MAINUNIT,LBLA.CONVFACT1 [CONVFACT1],LBLA.CONVFACT2 [CONVFACT2],
CASE WHEN ORL.LOGICALREF IS NULL THEN 0 ELSE 1 END [ORDERUNIT],
CASE WHEN LBLA.UOMREF = #UOMREF THEN 1 ELSE 0 END [DEFAULTUNIT],
ORL.AMOUNT - SUM(CAST(CAST(ISNULL(STL.AMOUNT,0) AS NUMERIC(28,6)) AS FLOAT)) [OAMOUNT],ORL.LOGICALREF [ORDERLINEREF]
FROM ORDERLINE ORL
INNER JOIN {0}..LG_{1}_UNITSETL UNL ON ORL.UOMREF = UNL.LOGICALREF
LEFT OUTER JOIN LABEL_CARD_UNITA LBLA ON ORL.UOMREF=LBLA.UOMREF
--AND ORL.UOMREF = LBLA.UOMREF
LEFT OUTER JOIN STLINE STL ON ORL.LOGICALREF = STL.ORDERLINEREF
WHERE LBLA.BARCODEREF = #BARCODEREF AND ORL.ORDERFICHEREF = #ORDERFICHEREF AND ORL.STFICHEREF = #STFICHEREF AND ORL.ITEMREF = #ITEMREF AND ORL.VARIANTREF = #VARIANTREF AND LBLA.LOGICALREF IS NULL
GROUP BY UNL.LINENR,UNL.LOGICALREF,UNL.CODE,UNL.MAINUNIT,ORL.CONVFACT1,LBLA.CONVFACT1,ORL.CONVFACT2,LBLA.CONVFACT2,ORL.LOGICALREF,LBLA.UOMREF,ORL.AMOUNT
) AS A
ORDER BY A.LINENR
END
END
END
It's so easy I just make every logic as sperate sp.
Before
SELECT #FICHENO =ORF.FICHENO,#STATUS=ORF.[STATUS],#BRANCH=ORF.BRANCH,#SOURCEINDEX=ORF.SOURCEINDEX
FROM ORDERFICHE ORF
INNER JOIN ORDERFICHE_TERMINAL ORFT ON ORF.LOGICALREF=ORFT.ORDERFICHEREF
WHERE ORF.LOGICALREF=#ORDERFICHEREF AND ORFT.TERMINALREF=#TERMINALREF
IF (#STATUS IS NULL OR (#STATUS NOT IN (0,1,6)))
BEGIN
SET #RESULT=14 --Fişe terminal atanmış ve fiş statusu tamamlandıdan küçük olacak
GOTO RESULT
END
After
EXEC PRX_MINT_FICHE_STATUS_CONTROL #ORDERFICHEREF,#TERMINALREF,#RESULT OUTPUT,#FICHENO OUTPUT,#BRANCH OUTPUT,#SOURCEINDEX OUTPUT
IF #RESULT>0
GOTO RESULT;
I write same code in the procedure i create output variables which i needed for next steps.

Paging data and get row count with out considering the page number in stored procedure

I am using SQL Server 2012. I need to do paging in my stored procedure. In client side (Web page), I need to have the result of the stored procedure for requested page and also I need to have the row count without considering the page number for setting number of page with that condition.
For example, I need to run this stored procedure for querying ten row of second page when my SubscribeId is 12345674.
Create Procedure TestSelectBill
(#PageNumber int = 1 ,
#RowCount int = 10 ,
#SubscribeId Int = 0)
As
Begin
Select *
From billing.BillMaster As BM
Where (Bm.SubscribeId = #SubscribeId)
Order by SubscribeId
Offset (#PageNumber - 1) * #RowCount Rows
Fetch Next #RowCount Rows Only;
End
I have to execute this stored procedure like this :
Execute TestSelectBill
#PageNumber = 2, #RowCount int = 10, #SubscribeId = 12345674
Imagine, that I have 105 rows in billing.BillMaster for this SubscribeId = 123456574. Now I need to show 10 row to my end user as result and I have to let him to select one page between 1 to 11.
That means I need to know how many row is exist for this condition SubscribeId = 123456574.
I can change my stored procedure like the below code to return row count:
Create Procedure TestSelectBill
(#PageNumber int = 1,
#RowCount int = 10,
#SubscribeId Int = 0)
As
Begin
DECLARE #ROW_COUNT INT = 0
-- Find Row Count for this condition
Select
#ROW_COUNT = COUNT(*)
From
billing.BillMaster As BM
Where
(Bm.SubscribeId = #SubscribeId)
-- Select Result
SELECT
Row_Count = #ROW_COUNT,
*
FROM
billing.BillMaster As BM
WHERE
(Bm.SubscribeId = #SubscribeId)
ORDER BY
SubscribeId
OFFSET ( #PageNumber - 1 ) * #RowCount ROWS
FETCH NEXT #RowCount ROWS ONLY;
End
But as you see I have to write my select two times and it is not good because modification and maintenance of this stored procedure will be very complicated.
Also, I can save my result into temp table and then use that like the below code:
CREATE Procedure TestSelectBill
(#PageNumber int = 1,
#RowCount int = 10,
#SubscribeId Int = 0)
As
Begin
DECLARE #ROW_COUNT INT = 0
-- Main Select
SELECT
*
FROM
billing.BillMaster As BM
INTO
#T
WHERE
(Bm.SubscribeId = #SubscribeId)
-- Find Row Count for this condituion
SELECT #ROW_COUNT = COUNT(*)
FROM #T
-- Select Result
SELECT
Row_Count = #ROW_COUNT,
*
FROM
#T
ORDER BY
SubscribeId
OFFSET (#PageNumber - 1) * #RowCount ROWS
FETCH NEXT #RowCount ROWS ONLY;
End
But as you can see in this way, I am using physical temp table that can be very slow when I have a lot of data in main select with out paging.
Can anyone tell me the best way to do that?
-- First solution use count with window function
CREATE Procedure TestSelectBill
(#PageNumber int = 1,
#RowCount int = 10,
#SubscribeId Int = 0)
As
Begin
SELECT
COUNT(*) OVER(ORDER BY (SELECT NULL)) AS row_count ,
*
FROM
billing.BillMaster As BM
WHERE
(Bm.SubscribeId = #SubscribeId)
ORDER BY
SubscribeId
OFFSET (#PageNumber - 1) * #RowCount ROWS
FETCH NEXT #RowCount ROWS ONLY;
End
GO
-- Second solution: use dynamic sql with multiple result
Create Procedure TestSelectBill
#PageNumber int = 1,
#RowCount int = 10,
#SubscribeId Int = 0
As
Begin
DECLARE #params NVARCHAR(max) = '#PageNumber int, #RowCount int, #SubscribeId int'
DECLARE #where NVARCHAR(max) = N' WHERE Bm.SubscribeId = #SubscribeId'
DECLARE #stmt NVARCHAR(max) = N'SELECT COUNT(*) as row_cnt FROM billing.BillMaster As BM '
DECLARE #stmt_rowcount NVARCHAR(max) = N'SELECT * FROM billing.BillMaster As BM '
DECLARE #order_by NVARCHAR(max) = ' ORDER BY SubscribeId
OFFSET (#PageNumber - 1) * #RowCount ROWS
FETCH NEXT #RowCount ROWS ONLY;'
SET #stmt += #where + #order_by
SET #stmt_rowcount += #where
-- First result set (rowcount)
EXEC [sys].[sp_executesql]
#stmt = #stmt_rowcount,
#params = #params,
#SubscribeId = #SubscribeId,
#PageNumber = #PageNumber,
#RowCount = #RowCount
-- Second result set (data)
IF ##ERROR = 0
BEGIN
EXEC [sys].[sp_executesql]
#stmt = #stmt,
#params = #params,
#SubscribeId = #SubscribeId,
#PageNumber = #PageNumber,
#RowCount = #RowCount
END
End
GO
You could create a temp table with an identity column that increments by 1 for each row inserted, then read the max value of that column to get the row count.

How does one use loops in TSQL?

In TSQL, I would like to change the following code from have to use hard coded dhomes to using a loop for optimization. My failed attempt at trying to add a loop is also included.
Declare #dhome Tinyint, #bp smallint, #lr smallint, #q smallint
// Set #dhome = 1
While(#dhome <= 3) // My attempt to add a loop
SELECT #lr = MAX(NQdDate), #q = NQd
FROM NQdHistory
WHERE dhomeId = #dhome
GROUP BY NQdDate, NQd
SELECT #bd = COUNT(*)
FROM bdhome
WHERE NQdDate= #lr AND dhomeID= #dhome
DELETE FROM ND1 WITH(XLOCK)
WHERE dhomeID= #dhome AND NQdDate= #lr
UPDATE NQdHistory
SET Nbd = #q - ##RowCount - #bp, NBd = #bp
WHERE NQdDate= #lr AND dhomeID= #dhome
Set #dhome = #dhome +1 //My attempt to end a loop
You're on the right track. You're missing your begin and end. Also, be sure to give #dhome a value. It looks like you started to and have it commented out on your third line:
Declare #dhome Tinyint, #bp smallint, #lr smallint, #q smallint
// Set #dhome = 1
While(#dhome <= 3) // My attempt to add a loop
begin
SELECT #lr = MAX(NQdDate), #q = NQd
FROM NQdHistory
WHERE dhomeId = #dhome
GROUP BY NQdDate, NQd
SELECT #bd = COUNT(*)
FROM bdhome
WHERE NQdDate= #lr AND dhomeID= #dhome
DELETE FROM ND1 WITH(XLOCK)
WHERE dhomeID= #dhome AND NQdDate= #lr
UPDATE NQdHistory
SET Nbd = #q - ##RowCount - #bp, NBd = #bp
WHERE NQdDate= #lr AND dhomeID= #dhome
Set #dhome = #dhome +1 //My attempt to end a loop
end
If you're familiar with C/C#/C++, think of T-SQL's Begin and End like curly braces { and }, if you're more familiar with VB Then and End If. Or more like pascals Begin and End. You get the idea :)
Missing a begin and end on your while.
WHILE (Transact-SQL)
Example 1
DECLARE #I INT,#COUNTVAR INT
SET #I = 1
DECLARE #Parent_Child TABLE(ID INT IDENTITY(1,1),ParentPositionID INT NULL,ChildPositionId Int)
INSERT INTO #Parent_Child(ParentPositionID,ChildPositionId)
SELECT DISTINCT PARENT_POSITION_ID,CHILD_POSITION_ID from tblPOSITION_HIERARCHY
--WHERE CHILD_POSITION_ID IN (--YOUR CONDITION IF ANY)
SELECT #COUNTVAR =COUNT(*) FROM #PTS_Parent_Child
DECLARE #int_SUPE_POSITION_ID INT, #int_CHILD_POSITION_ID INT
--loop through records here
WHILE #I <= #COUNTVAR
BEGIN
SELECT #int_SUPE_POSITION_ID=ParentPositionID,#int_CHILD_POSITION_ID=ChildPositionId FROM #Parent_Child WHERE ID=#I
--Whatever you want to do with records
SET #I=#I+1
END
Example 2
Just another approach if you are fine using temp tables.I have personally tested this and it will not cause any exception (even if temp table does not have any data.)
CREATE TABLE #TempTable
(
ROWID int identity(1,1) primary key,
HIERARCHY_ID_TO_UPDATE int,
)
--INSERT DATA INTO TEMP TABLE USING INSERT INTO CLAUSE OR FOR EAXMPLE BELOW
--INSERT INTO #TempTable VALUES(1)
--INSERT INTO #TempTable VALUES(2)
--INSERT INTO #TempTable VALUES(4)
--INSERT INTO #TempTable VALUES(6)
--INSERT INTO ##TempTable VALUES(8)
DECLARE #MAXID INT
SET #COUNTER =1
SELECT #MAXID=COUNT(*) FROM #TempTable
--PRINT #MAXID
WHILE (#MAXID > 0)
BEGIN
--DO THE PROCESSING HERE
SELECT #HIERARCHY_ID_TO_UPDATE =PT.HIERARCHY_ID_TO_UPDATE FROM #TempTable PT WHERE ROWID=#COUNTER
--PRINT '#MAXID VALUE '
--PRINT #MAXID
SET #MAXID=#MAXID-1
SET #COUNTER =#COUNTER + 1
End
If(OBJECT_ID('tempdb..#TempTable') IS NOT NULL)
BEGIN
DROP TABLE #TempTable
END

T-SQL loop over query results

I run a query select #id=table.id from table and I need to loop over the results so I can exec a store procedure for each row exec stored_proc #varName=#id,#otherVarName='test'
How can I do this in a T-SQL script?
You could use a CURSOR in this case:
DECLARE #id INT
DECLARE #name NVARCHAR(100)
DECLARE #getid CURSOR
SET #getid = CURSOR FOR
SELECT table.id,
table.name
FROM table
OPEN #getid
FETCH NEXT
FROM #getid INTO #id, #name
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC stored_proc #varName=#id, #otherVarName='test', #varForName=#name
FETCH NEXT
FROM #getid INTO #id, #name
END
CLOSE #getid
DEALLOCATE #getid
Modified to show multiple parameters from the table.
You could do something like this:
create procedure test
as
BEGIN
create table #ids
(
rn int,
id int
)
insert into #ids (rn, id)
select distinct row_number() over(order by id) as rn, id
from table
declare #id int
declare #totalrows int = (select count(*) from #ids)
declare #currentrow int = 0
while #currentrow < #totalrows
begin
set #id = (select id from #ids where rn = #currentrow + 1)
exec stored_proc #varName=#id, #otherVarName='test'
set #currentrow = #currentrow +1
end
END
My prefer solution is Microsoft KB 111401 http://support.microsoft.com/kb/111401.
The link refers to 3 examples:
This article describes various methods that you can use to simulate a cursor-like FETCH-NEXT logic in a stored procedure, trigger, or Transact-SQL batch.
/*********** example 1 ***********/
declare #au_id char( 11 )
set rowcount 0
select * into #mytemp from authors
set rowcount 1
select #au_id = au_id from #mytemp
while ##rowcount <> 0
begin
set rowcount 0
select * from #mytemp where au_id = #au_id
delete #mytemp where au_id = #au_id
set rowcount 1
select #au_id = au_id from #mytemp
end
set rowcount 0
/********** example 2 **********/
declare #au_id char( 11 )
select #au_id = min( au_id ) from authors
while #au_id is not null
begin
select * from authors where au_id = #au_id
select #au_id = min( au_id ) from authors where au_id > #au_id
end
/********** example 3 **********/
set rowcount 0
select NULL mykey, * into #mytemp from authors
set rowcount 1
update #mytemp set mykey = 1
while ##rowcount > 0
begin
set rowcount 0
select * from #mytemp where mykey = 1
delete #mytemp where mykey = 1
set rowcount 1
update #mytemp set mykey = 1
end
set rowcount 0
DECLARE #id INT
DECLARE #name NVARCHAR(100)
DECLARE #getid CURSOR
SET #getid = CURSOR FOR
SELECT table.id,
table.name
FROM table
WHILE 1=1
BEGIN
FETCH NEXT
FROM #getid INTO #id, #name
IF ##FETCH_STATUS < 0 BREAK
EXEC stored_proc #varName=#id, #otherVarName='test', #varForName=#name
END
CLOSE #getid
DEALLOCATE #getid
try this:
declare #i tinyint = 0,
#count tinyint,
#id int,
#name varchar(max)
select #count = count(*) from table
while (#i < #count)
begin
select #id = id, #name = name from table
order by nr asc offset #i rows fetch next 1 rows only
exec stored_proc #varName = #id, #otherVarName = 'test', #varForName = #name
set #i = #i + 1
end
DECLARE #id INT
DECLARE #filename NVARCHAR(100)
DECLARE #getid CURSOR
SET #getid = CURSOR FOR
SELECT top 3 id,
filename
FROM table
OPEN #getid
WHILE 1=1
BEGIN
FETCH NEXT
FROM #getid INTO #id, #filename
IF ##FETCH_STATUS < 0 BREAK
print #id
END
CLOSE #getid
DEALLOCATE #getid

first attempt at a sproc transaction

I am trying to write a sproc with a transaction. Can anybody tell me if there would be any issues with code below, or if it will work as intended?
ALTER procedure [dbo].[DeleteMetricMeter]
(
#SectionID int,
#MetricMeterID int,
#Result bit output
)
as
declare #MetricMeterCount int
declare #err int
declare #rowcount int
set xact_abort on
begin tran
select #MetricMeterCount = count(*) from luMetricMeters
where fkSectionID = #SectionID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
delete from luMetricMeterList
where pkMetricMeterID = #MetricMeterID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
delete from luMetricMeters
where pkMetricMeterID = #MetricMeterID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
if (#MetricMeterCount = 1)
begin
delete from luMetricSections
where pkSectionID = #SectionID
select #err = ##error, #rowcount = ##rowcount
if (#err <> 0) or (#rowcount = 0)
begin
goto on_error
end
end
commit tran
set #result = 1
return #result
on_error:
rollback tran
set #result = 0
return #result
If you are using Sql Server 2005+, I would recomend rather using TRY...CATCH (Transact-SQL) and have a look at section [B. Using TRY…CATCH in a transaction]
This will GREATLY simplify your procedure.
There are a few issues with the procedure:
You should not evaluate rowcount unless it really indicates an error. When there is no data deleted there is no need to rollback.
Your code is not thread safe. The MetricMeterCount query should be changed to this to prevent other threads from performing the delete in between your select & the execution of the delete:
select #MetricMeterCount = count(*)
from luMetricMeters with (xlock, serializable)
where fkSectionID = #SectionID
I would write the code like this:
ALTER procedure [dbo].[DeleteMetricMeter]
(
#SectionID int,
#MetricMeterID int,
#Result bit output
)
as
DECLARE #MetricMeterCount int
DECLARE #err int
DECLARE #rowcount int
SET xact_abort ON
BEGIN TRAN
DELETE FROM luMetricMeterList
WHERE pkMetricMeterID = #MetricMeterID
SELECT #err = ##error
IF (#err <> 0)
GOTO on_error
DELETE FROM luMetricMeters
WHERE pkMetricMeterID = #MetricMeterID
SELECT #err = ##error
IF (#err <> 0)
GOTO on_error
IF EXISTS (SELECT *
FROM luMetricMeters WITH (xlock, serializable)
WHERE fkSectionID = #SectionID)
BEGIN
DELETE FROM luMetricSections
WHERE pkSectionID = #SectionID
SELECT #err = ##error
IF (#err <> 0)
GOTO on_error
END
COMMIT TRAN
RETURN (0)
on_error:
ROLLBACK TRAN
RETURN (-1)
GO
Note: The return values should be 0 for success and a negative number for failure.