I wrote this stored procedure which needs to iterate the rows in a table type and for each type it has to make a string and call another SP. Since this has calling another SP I can't think a way of using a CTE. How can I remove the cursor in the below logic? Please assist with a solution.
CREATE PROCEDURE [core].[usp_insertLocationTree]
@locationInfo core.LocationInfo READONLY,
@treeItemCount INT
AS
BEGIN
BEGIN TRY
DECLARE @itemClass VARCHAR(MAX)
DECLARE @location VARCHAR(MAX)
DECLARE @locationId INT
DECLARE @parentLocationId INT
DECLARE @tmpLocation TABLE
(
[rowId] INT,
[location-id] INT,
[name] VARCHAR(MAX),
[class-id] INT,
[parent-location-id] INT
)
DECLARE @itemClassId INT
DECLARE @rule VARCHAR(MAX)
DECLARE @guid VARCHAR(MAX)
DECLARE @id INT
DECLARE @tmp TABLE ([id] INT)
DECLARE @lastProcessedRowId INT
DECLARE @rowCount INT
SELECT @rowCount = COUNT(1)
FROM @locationInfo
SET @lastProcessedRowId = 0
SELECT *
FROM @locationInfo
WHILE (@lastProcessedRowId <= @rowCount)
BEGIN
INSERT INTO @tmpLocation
SELECT TOP(@treeItemCount) rowId,
l.locationId,
l.location,
ic.ItemClassID,
locationId -1
FROM @locationInfo l
INNER JOIN item.ItemClass ic
ON l.itemClass = ic.ItemClass
WHERE l.rowId > @lastProcessedRowId
ORDER BY rowId
SELECT *
FROM @tmpLocation
DECLARE db_cursor CURSOR
FOR
SELECT t.[location-id],
t.name,
t.[class-id],
t.[parent-location-id],
ic.ItemClass
FROM @tmpLocation t
INNER JOIN item.ItemClass ic
ON t.[class-id]=ic.ItemClassID
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @locationId,@location,@itemClassId,@parentLocationId,@itemClass
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT CONVERT(VARCHAR, @locationId) + ' , ' + @location + ' , ' + CONVERT(VARCHAR, @parentLocationId)+ ' , ' + CONVERT(VARCHAR, @itemClassId) + ' , ' + @itemClass
SET @rule = NULL
IF NOT EXISTS (
SELECT 1
FROM item.Item i
WHERE i.ItemName = @location
AND i.FkItemClassID = @itemClassId
)
BEGIN
PRINT @location + ' of ' + @itemClass + ' not exists'
IF (@parentLocationId <> 0)
BEGIN
;WITH abcd
AS (
SELECT tl.[location-id],
tl.name,
ic.ItemClass,
tl.[parent-location-id]
FROM @tmpLocation tl
INNER JOIN item.ItemClass ic
ON tl.[class-id] = ic.ItemClassID
WHERE tl.[location-id] = @locationId
UNION ALL
SELECT tl.[location-id],
tl.name,
ic.ItemClass,
tl.[parent-location-id]
FROM @tmpLocation tl
INNER JOIN item.ItemClass ic
ON tl.[class-id] = ic.ItemClassID
JOIN abcd AS a
ON a.[parent-location-id] = tl.[location-id]
)
SELECT @rule = '{' + (
SELECT CASE ROW_NUMBER() OVER(ORDER BY abcd.[location-id])
WHEN 1 THEN ''
ELSE '} [AND] {'
END +
'{@@EnterpriseDistributionLevel!!<Equals>##'+ abcd.ItemClass +
'??} [AND] {@@EnterpriseDistributionName!!<Equals>##'+ abcd.name + '??}'
FROM abcd
WHERE abcd.[location-id] <> @locationId
FOR XML PATH('')
)+ '}'
SELECT @rule = REPLACE(REPLACE(@rule, '>', '>'), '<', '<')
END
PRINT @rule
SET @guid = 'ffffffff-ffff-ffff-ffff-' + RIGHT(
'00000000000' + CONVERT(VARCHAR, IDENT_CURRENT('item.item') + 1),
12
)
PRINT @location + ' - ' + @rule
EXEC item.usp_InsertUpdateItem
@itemID = @guid,
@pkItemID = 0,
@itemName = @location,
@brokerID = NULL,
@hostID = NULL,
@ipaddress = NULL,
@timezone = NULL,
@timezoneOffest = NULL,
@itemTypeID = 5,
@itemType = 'Logical',
@itemClassID = @itemClassId,
@ItemClass = @itemClass,
@heartBeatDur = 0,
@parentFindingRule = @rule,
@pkItemIDOut = @id OUTPUT,
@itemRegTime = null
END
ELSE
BEGIN
IF (@parentLocationId <> 0)
BEGIN
DELETE
FROM @tmp
;WITH abcd
AS (
SELECT tl.[location-id],
tl.name,
ic.ItemClass,
tl.[parent-location-id]
FROM @tmpLocation tl
INNER JOIN item.ItemClass ic
ON tl.[class-id] = ic.ItemClassID
WHERE tl.[location-id] = @locationId
UNION ALL
SELECT tl.[location-id],
tl.name,
ic.ItemClass,
tl.[parent-location-id]
FROM @tmpLocation tl
INNER JOIN item.ItemClass ic
ON tl.[class-id] = ic.ItemClassID
JOIN abcd AS a
ON a.[parent-location-id] = tl.[location-id]
)
SELECT @rule = '{' + (
SELECT CASE ROW_NUMBER() OVER(ORDER BY abcd.[location-id])
WHEN 1 THEN ''
ELSE '} [AND] {'
END +
'{@@EnterpriseDistributionLevel!!<Equals>##'+ abcd.ItemClass +
'??} [AND] {@@EnterpriseDistributionName!!<Equals>##'+ abcd.name + '??}'
FROM abcd
--WHERE abcd.[location-id] <> @locationId
FOR XML PATH('')
)+ '}'
SELECT @rule = REPLACE(REPLACE(@rule, '>', '>'), '<', '<')
PRINT @rule
INSERT INTO @tmp
EXEC core.usp_GetItemsForDescriptor @descriptor = @rule
IF NOT EXISTS(
SELECT 1
FROM @tmp
)
BEGIN
SET @rule = NULL
;WITH abcd
AS (
SELECT tl.[location-id],
tl.name,
ic.ItemClass,
tl.[parent-location-id]
FROM @tmpLocation tl
INNER JOIN item.ItemClass ic
ON tl.[class-id] = ic.ItemClassID
WHERE tl.[location-id] = @locationId
UNION ALL
SELECT tl.[location-id],
tl.name,
ic.ItemClass,
tl.[parent-location-id]
FROM @tmpLocation tl
INNER JOIN item.ItemClass ic
ON tl.[class-id] = ic.ItemClassID
JOIN abcd AS a
ON a.[parent-location-id] = tl.[location-id]
)
SELECT @rule = '{' + (
SELECT CASE ROW_NUMBER() OVER(ORDER BY abcd.[location-id])
WHEN 1 THEN ''
ELSE '} [AND] {'
END +
'{@@EnterpriseDistributionLevel!!<Equals>##'+ abcd.ItemClass +
'??} [AND] {@@EnterpriseDistributionName!!<Equals>##'+ abcd.name + '??}'
FROM abcd
WHERE abcd.[location-id] <> @locationId
FOR XML PATH('')
)+ '}'
SELECT @rule = REPLACE(REPLACE(@rule, '>', '>'), '<', '<')
PRINT @location + ' of ' + @itemClass +
' exists. But their relationship does not'
SET @guid = 'ffffffff-ffff-ffff-ffff-' + RIGHT(
'00000000000' + CONVERT(VARCHAR, IDENT_CURRENT('item.item') + 1),
12
)
PRINT @location + ' - ' + @rule
EXEC item.usp_InsertUpdateItem
@itemID = @guid,
@pkItemID = 0,
@itemName = @location,
@brokerID = NULL,
@hostID = NULL,
@ipaddress = NULL,
@timezone = NULL,
@timezoneOffest = NULL,
@itemTypeID = 5,
@itemType = 'Logical',
@itemClassID = @itemClassId,
@ItemClass = @itemClass,
@heartBeatDur = 0,
@parentFindingRule = @rule,
@pkItemIDOut = @id OUTPUT,
@itemRegTime = null
END
END
END
FETCH NEXT FROM db_cursor INTO @locationId,@location,@itemClassId,@parentLocationId,@itemClass
END
CLOSE db_cursor
DEALLOCATE db_cursor
SET @lastProcessedRowId = @lastProcessedRowId + @treeItemCount
DELETE FROM @tmpLocation
END
END TRYmayooran99