Quantcast
Channel: Forum Getting started with SQL Server
Viewing all articles
Browse latest Browse all 7129

How can I remove the cursor in the below logic?

$
0
0

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, '&gt;', '>'), '&lt;', '<')
		        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, '&gt;', '>'), '&lt;', '<')

		            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, '&gt;', '>'), '&lt;', '<')

		                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 TRY


mayooran99


Viewing all articles
Browse latest Browse all 7129

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>