Convert while Loop to Set based

  • Hi,

    I need some guidance on how to convert a while loop code to a set-based code .  I separate the source data to 2 #temp table based on the @AlertType (email or sms), and inner join the #temptable to the based table (itemheader and itemdetail) to replace the #variable and the while loop  .But I am not sure if this is the correct way .

     **Old code :**
    Where IMD.CustomerAccountNo= @CustAccountNo
    AND IMD.StatusCode=@ItemStatus
    AND (@Reasoncode = '%' OR IMD.Reasoncode = @Reasoncode)
    AND IH.TrackingNo=@TrackingNo
    AND IH.ServiceTypeId = @ServiceType

    **New code:**
    inner join #tempresult_SMS SMS on
    IMD.CustomerAccountNo= SMS.CustAccountNo
    AND IMD.StatusCode= SMS.ItemStatus
    AND (IMD.Reasoncode = SMS.ReasonCode 0R SMS.ReasonCode = '%')
    AND IH.TrackingNo=SMS.TrackingNo
    AND IH.ServiceTypeId = SMS.ServiceType

    Full Stored procedure :

    Alter PROCEDURE [dbo].[ezy_UpdateItemHeader](  
    @SMSNotificationItemDetails ezy_SMSNotificationItemDetailsType READONLY)
    AS
    BEGIN
    SET NOCOUNT ON;

    --Declare temp table
    DECLARE @SMSDetailTable TABLE
    (
    [ROWID] INT NOT NULL PRIMARY KEY IDENTITY(1,1),
    [CustAccountNo] [NVARCHAR](MAX) NULL,
    [ServiceType] [NVARCHAR](MAX) NULL,
    [AlertType] [NVARCHAR](MAX) NULL,
    [ItemStatus] [NVARCHAR](MAX) NULL,
    [TrackingNo] [VARCHAR](MAX) NULL,
    [ReasonCode] [VARCHAR](MAX) NULL
    )

    --Insert into temp table
    INSERT INTO @SMSDetailTable( [CustAccountNo] , [ServiceType] ,[AlertType] ,[ItemStatus],[TrackingNo], [ReasonCode] )
    SELECT [CustAccountNo] ,[ServiceType] ,[AlertType] ,[ItemStatus] ,[TrackingNo], [ReasonCode] FROM @SMSNotificationItemDetails

    DECLARE @TotalRows INT , @CurrentRow INT
    SELECT @TotalRows = COUNT(*) FROM @SMSDetailTable
    SET @CurrentRow = 0

    --Looping start in the first rows
    WHILE(@CurrentRow < @TotalRows)
    BEGIN
    SET @CurrentRow = @CurrentRow + 1

    DECLARE @CustAccountNo VARCHAR(50) ,@ServiceType VARCHAR(50) ,@ItemStatus VARCHAR(50) ,
    @AlertType VARCHAR(50) , @TrackingNo VARCHAR(50) , @ReasonCode VARCHAR(50)

    --Fetch the data into variable
    SELECT @CustAccountNo = CustAccountNo , @ServiceType = ServiceType , @ItemStatus = ItemStatus
    , @AlertType = AlertType , @TrackingNo = TrackingNo , @ReasonCode = ReasonCode
    FROM @SMSDetailTable WHERE ROWID = @CurrentRow


    DECLARE @REQNumber VARCHAR(100) , @EmailREQNumber VARCHAR (100)

    ---Build the transactionID
    SET @REQNumber= 'TESTID'+replace(replace(replace(replace(CONVERT(VARCHAR(40),GETDATE(),121),'-',''),':',''),' ',''),'.','')
    SET @EmailREQNumber= 'TESTEMAILID'+replace(replace(replace(replace(CONVERT(VARCHAR(40),GETDATE(),121),'-',''),':',''),' ',''),'.','')

    --NOtification Item for SMS
    IF (@AlertType = 'SMS' OR @AlertType = 'SMS/Email')
    BEGIN
    declare @NotificationItemDetail table(
    [ID] [int],
    [TransactionID] VARCHAR(max),
    [ItemNumber] VARCHAR(max),
    [AlertType] VARCHAR(max)
    )

    INSERT INTO @NotificationItemDetail (
    [ID],
    [TransactionID],
    [ItemNumber],
    [AlertType]
    )
    Select
    IMD.AutoID
    ,@REQNumber + CAST(RANK() OVER (ORDER BY IMD.AutoID ASC) AS VARCHAR)
    ,@TrackingNo
    ,@AlertType
    from ItemDetail IMD
    INNER JOIN itemheader IH on
    IH.TrackingNo = IMD.TrackingNo
    WHERE
    IMD.CustomerAccountNo= @CustAccountNo
    AND IMD.StatusCode=@ItemStatus
    AND (@Reasoncode = '%' OR IMD.Reasoncode = @Reasoncode)
    AND IH.TrackingNo=@TrackingNo
    AND IH.ServiceTypeId = @ServiceType
    AND IMD.LastUpdatedDate = CAST(GETDATE() as DATE)
    END


    --NOtification Item for Email
    IF (@AlertType = 'Email')
    BEGIN
    declare @NotificationItemSMSEMAILDetail table(
    [ID] [int],
    [ETransactionID] VARCHAR(max),
    [EItemNumber] VARCHAR(max),
    [EAlertType] VARCHAR(max))

    INSERT INTO @NotificationItemSMSEMAILDetail (
    [ID],
    [ETransactionID],
    [EItemNumber],
    [EAlertType]
    )
    Select
    IMD.AutoID
    ,@EmailREQNumber + CAST(RANK() OVER (ORDER BY IMD.AutoID ASC) AS VARCHAR)
    ,IMD.TrackingNo
    ,'Email'
    from ItemDetail IMD
    INNER JOIN Itemheader IH on
    IH.TrackingNo = IMD.TrackingNo
    where
    IMD.CustomerAccountNo= @CustAccountNo
    AND IMD.StatusCode=@ItemStatus
    AND IH.ServiceTypeId = @ServiceType
    AND IMD.LastUpdatedDate = CAST(GETDATE() as DATE)
    END
    END
    END

     

     

    • This topic was modified 2 years, 7 months ago by  stanley_1982.
    • This topic was modified 2 years, 7 months ago by  stanley_1982.
    • This topic was modified 2 years, 7 months ago by  stanley_1982.
  • Couple of initial questions, why do you INSERT the rows from your parameter  @ezy_SMSNotificationItemDetailsType into a user defined table variable @SMSDetailTable? Why not just use the contents of @ezy_SMSNotificationItemDetailsType? Why are all the column within @SMSDetailTable an nvarchar(MAX) too? Are all the columns likely to have values longer than 4,000 characters?

    Also you have some typographical errors. There's a trailing comma after [ReasonCode] [VARCHAR](MAX) NULL, and you attempt to insert data into a column called [TrackingNo, [ReasonCode].

    Thom~

    Excuse my typos and sometimes awful grammar. My fingers work faster than my brain does.
    Larnu.uk

  • Thanks Thom.

    The typo is fixed  .

    All the (Max) data type will  be reviewed with the users once the while loop  logic have been converted and tested .  I can use the contents from @ezy_SMSNotificationItemDetailsType and I will need to amend the user defined table type to ensure the data type length are correct .

    This is the data type length which will be change once user is confirm :

    --Declare temp table

    DECLARE @SMSDetailTable TABLE

    (

    [ROWID] INT NOT NULL PRIMARY KEY IDENTITY(1,1),

    [CustAccountNo] [VARCHAR](50) NULL,

    [ServiceType] [VARCHAR](20) NULL,

    [AlertType] [VARCHAR](20) NULL,

    [ItemStatus] [VARCHAR](10) NULL,

    [TrackingNo] [VARCHAR](50) NULL,

    [ReasonCode] [VARCHAR](10) NULL

    )

     

  • while waiting for user confirmation on the data type length ,  I has some idea how to convert this while loop, but I need help to confirm on the joining part , or is there other better method to convert the while loop :

    First I will  separate the source data based on the Alert Type, then if #tempresult_SMS table is not empty , then insert into the table and inner join with the  #tempresult_SMS  with the @variable used in the while loop :

    drop table if exists #tempresult_SMS
    SELECT CustAccountNo , ServiceType ,ItemStatus ,  AlertType , TrackingNo , ReasonCode into #tempresult_SMS FROM @SMSDetailTable WHERE AlertType = 'SMS'

    IF EXISTS( SELECT TOP (1) 1 FROM #tempresult_SMS)
    Begin 
    INSERT INTO @NotificationItemDetail ([ID],[TransactionID],[ItemNumber],[AlertType])

    Select IMD.AutoID
    ,select 'TESTID'+replace(replace(replace(replace(CONVERT(VARCHAR(40),DATEADD(millisecond, 5 * RANK () over (order by autoid), GETDATE()),121),'-',''),':',''),' ',''),'.','') + CAST(RANK() OVER (ORDER BY IMD.AutoID ASC) AS VARCHAR)
    ,@TrackingNo , ,@AlertType
    from ItemDetail IMD
    INNER JOIN itemheader IH on
    IH.TrackingNo = IMD.TrackingNo

    INNER JOIN #tempresult_SMS T_SMS  on
    IMD.CustomerAccountNo= T_SMS.CustAccountNo
    AND IMD.StatusCode=T_SMS.ItemStatus
    AND (T_SMS.ReasonCode= '%' OR IMD.Reasoncode = T_SMS.ReasonCode)
    AND IH.TrackingNo=T_SMS.TrackingNo
    AND IH.ServiceTypeId = T_SMS.ServiceType

    WHERE
    IMD.LastUpdatedDate = CAST(GETDATE() as DATE)

    End

Viewing 4 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic. Login to reply