Reputation:
I had cursor in my stored procedure. I have updated to while loop to execute faster. But my while loops takes same long time. Please help me to debug my script. Please find my below code.
I need the help in updating Cursor to set based operator Query in MS SQL.
DECLARE @orderArray INT
,@LeftTSMKEY NVARCHAR(250)
,@ListElid NVARCHAR(250)
,@ListType NVARCHAR(250)
,@ListType_Prev NVARCHAR(250)
SET @ListType_Prev = ''
SET @inc = 0
DECLARE cursql CURSOR
FOR
SELECT ListElid
,ListType
,orderArray
,LeftTSMKEY
FROM QAT_ListElid
ORDER BY ListType
,orderArray
OPEN cursql
FETCH NEXT
FROM cursql
INTO @ListElid
,@ListType
,@orderArray
,@LeftTSMKEY
WHILE (@@Fetch_status = 0)
BEGIN
IF @ListType <> @ListType_Prev
BEGIN
SET @inc = 0
SET @ListType_Prev = @ListType
END
ELSE IF @ListType = @ListType_Prev
BEGIN
SET @inc = @inc + 1
END
IF @inc <> @orderArray
BEGIN
INSERT [QAT_ListElid2] (
[ListElid]
,[ListType]
,[orderArray]
,[LeftTSMKEY]
)
VALUES (
@ListElid
,@ListType
,@inc
,@LeftTSMKEY + CAST(@inc AS NVARCHAR(10)) + ']'
)
END
FETCH NEXT
FROM cursql
INTO @ListElid
,@ListType
,@orderArray
,@LeftTSMKEY
END
CLOSE cursql
DEALLOCATE cursql
Please find below sample data
ListElid ListType orderArray LeftTSMKEY
1000:odl5:7pt_ToxAcuDo[0] 1000:odl5:7pt_ToxAcuDo 0 ToxAcuDo[
106i:odl5:7pt_ToxAcuDo[0] 106i:odl5:7pt_ToxAcuDo 0 ToxAcuDo[
107:107:7pt_NIL[0] 107:107:7pt_NIL 0 NIL[
107:1827:7pt_NIL[0] 107:1827:7pt_NIL 0 NIL[
107:1827:7pt_NIL[1] 107:1827:7pt_NIL 1 NIL[
107:1827:7pt_NIL[3] 107:1827:7pt_NIL 3 NIL[
107:1hqn:7pt_NIL[0] 107:1hqn:7pt_NIL 0 NIL[
107:1hqn:7pt_NIL[1] 107:1hqn:7pt_NIL 1 NIL[
107:1rj7:7pt_NIL[0] 107:1rj7:7pt_NIL 0 NIL[
107:1rj7:7pt_NIL[1] 107:1rj7:7pt_NIL 1 NIL[
107:1rsg:7pt_NIL[0] 107:1rsg:7pt_NIL 0 NIL[
107:1s2r:7pt_NIL[0] 107:1s2r:7pt_NIL 0 NIL[
107:1s2r:7pt_NIL[1] 107:1s2r:7pt_NIL 1 NIL[
107:1s2r:7pt_NIL[2] 107:1s2r:7pt_NIL 2 NIL[
107:1s2r:7pt_NIL[4] 107:1s2r:7pt_NIL 4 NIL[
107:1vf:7pt_ NIL[0] 107:1vf:7pt_NIL 0 NIL[
Upvotes: 0
Views: 179
Reputation: 29943
If I understand the question correctly, the next statement is a possible solution.
Tables:
CREATE TABLE QAT_ListElid (
ListElid nvarchar(250),
ListType nvarchar(250),
orderArray int,
LeftTSMKEY nvarchar(250)
)
INSERT INTO QAT_ListElid
(ListElid, ListType, orderArray, LeftTSMKEY)
VALUES
('1000:odl5:7pt_ToxAcuDo[0]', '1000:odl5:7pt_ToxAcuDo', 0, 'ToxAcuDo['),
('106i:odl5:7pt_ToxAcuDo[0]', '106i:odl5:7pt_ToxAcuDo', 0, 'ToxAcuDo['),
('107:107:7pt_NIL[0]', '107:107:7pt_NIL', 0, 'NIL['),
('107:1827:7pt_NIL[0]', '107:1827:7pt_NIL', 0, 'NIL['), -- 107:1827:7pt_NIL
('107:1827:7pt_NIL[1]', '107:1827:7pt_NIL', 1, 'NIL['), -- 107:1827:7pt_NIL
('107:1827:7pt_NIL[3]', '107:1827:7pt_NIL', 3, 'NIL['), -- 107:1827:7pt_NIL
('107:1hqn:7pt_NIL[0]', '107:1hqn:7pt_NIL', 0, 'NIL['),
('107:1hqn:7pt_NIL[1]', '107:1hqn:7pt_NIL', 1, 'NIL['),
('107:1rj7:7pt_NIL[0]', '107:1rj7:7pt_NIL', 0, 'NIL['),
('107:1rj7:7pt_NIL[1]', '107:1rj7:7pt_NIL', 1, 'NIL['),
('107:1rsg:7pt_NIL[0]', '107:1rsg:7pt_NIL', 0, 'NIL['),
('107:1s2r:7pt_NIL[0]', '107:1s2r:7pt_NIL', 0, 'NIL['), -- 107:1s2r:7pt_NIL
('107:1s2r:7pt_NIL[1]', '107:1s2r:7pt_NIL', 1, 'NIL['), -- 107:1s2r:7pt_NIL
('107:1s2r:7pt_NIL[2]', '107:1s2r:7pt_NIL', 2, 'NIL['), -- 107:1s2r:7pt_NIL
('107:1s2r:7pt_NIL[4]', '107:1s2r:7pt_NIL', 4, 'NIL['), -- 107:1s2r:7pt_NIL
('107:1vf:7pt_ NIL[0]', '107:1vf:7pt_NIL', 0, 'NIL[')
CREATE TABLE QAT_ListElid2 (
ListElid nvarchar(250),
ListType nvarchar(250),
orderArray int,
LeftTSMKEY nvarchar(250)
)
Statement:
;WITH ChangesCTE AS (
SELECT
ListElid, ListType, orderArray, LeftTSMKEY,
CASE
WHEN ListType = LAG(ListType) OVER (PARTITION BY ListType ORDER BY orderArray) THEN 1
ELSE 0
END AS [Change]
FROM QAT_ListElid
), FinalCTE AS (
SELECT
ListElid, ListType, orderArray, LeftTSMKEY,
SUM([Change]) OVER (PARTITION BY ListType ORDER BY ListType, orderArray) AS [inc]
FROM ChangesCTE
)
INSERT INTO QAT_ListElid2
([ListElid], [ListType], [orderArray], [LeftTSMKEY])
SELECT
ListElid,
ListType,
[inc] AS orderArray,
LeftTSMKEY + CAST([inc] as nvarchar(10)) + ']' AS LeftTSMKEY
FROM FinalCTE
WHERE orderArray <> [inc]
or anotehr statement as second option:
INSERT INTO QAT_ListElid2
([ListElid], [ListType], [orderArray], [LeftTSMKEY])
SELECT
ListElid,
ListType,
[inc] AS orderArray,
LeftTSMKEY + CAST([inc] as nvarchar(10)) + ']' AS LeftTSMKEY
FROM (
SELECT
ListElid, ListType, orderArray, LeftTSMKEY,
ROW_NUMBER() OVER (PARTITION BY ListType ORDER BY orderArray) - 1 AS [Inc]
FROM QAT_ListElid
) t
WHERE orderArray <> [inc]
Result (two inserted rows):
--------------------------------------------------------------
ListElid ListType orderArray LeftTSMKEY
--------------------------------------------------------------
107:1827:7pt_NIL[3] 107:1827:7pt_NIL 2 NIL[2]
107:1s2r:7pt_NIL[4] 107:1s2r:7pt_NIL 3 NIL[3]
Upvotes: 0
Reputation: 9
They are based on the DECLARE CURSOR syntax and are used mainly in Transact-SQL scripts, stored procedures and triggers. Transact-SQL cursors are implemented on the server and are managed by Transact-SQL statements sent from the client to the server. They may also be contained in batches, stored procedures, or triggers.
Like INT
, VARCHAR
and other data types, Cursors are declared in T-SQL batches. SQL Server comes with associated instructions to manage it:
OPEN to tell SQL Server to run the query and populate cursor with results set;
CLOSE to tell SQL Server to release resources used by cursor;
FETCH to tell SQL Server to retrieve a specific row from cursor. When we use this function, we can get the outcome of FETCH instruction in @@FETCH_STATUS variable. If it’s set to 0, this means that the instruction succeeded.
Upvotes: 0