Skip to content
Advertisement

CASE Statement in SQL

just a curious question. I have written following code using CASE statement but I don’t have data so I am not sure if my logic is correct. All I am doing is I am applying length check on each field and if it doesn’t match then put it in error table. So, can anybody just tell me if my logic is correct?

Query:

 INSERT INTO
                [Elig].[dbo].[ErrorTable]
                (
                 [SeqId],
                 [CodeId],
                 [SubjectArea],
                 [FieldName],
                 [TableName],
                 [ErrorValue],
                 [ActiveFlag]
                )
                SELECT
                    [sd].[SuscriberDataId] AS [SeqId],
                    @InvalidLength AS [CodeId],
                    @SubjectArea AS [SubjectArea],
            CASE WHEN len(ltrim(Rtrim([sd].[SubscriberNumber]))) > 9 THEN 'SubscriberNumber'
                 WHEN len(ltrim(Rtrim([sd].[SubscriberLastName]))) > 35 THEN 'SubscriberLastName'
                 WHEN len(ltrim(Rtrim([sd].[SubscriberFirstName]))) > 15 THEN 'SubscriberFirstName'
                 WHEN len(ltrim(Rtrim([sd].[SubscriberMiddleInitial]))) > 1 THEN 'SubscriberMiddleInitial'  
                 WHEN len(ltrim(Rtrim([sd].[Sex]))) > 1 THEN 'Sex'
                 WHEN len(ltrim(Rtrim([sd].[Dob]))) > 8 THEN 'Dob'   
                 WHEN len(ltrim(Rtrim([sd].[Ssn]))) > 9 THEN 'Ssn'
                 WHEN len(ltrim(Rtrim([sd].[FacetsGroup]))) > 8 THEN 'FacetsGroup'  
           END AS FieldName,
           'Eligibility.SubscriberData',
           CASE  WHEN len(ltrim(Rtrim([sd].[SubscriberNumber]))) > 9 THEN [SubscriberNumber]
                 WHEN len(ltrim(Rtrim([sd].[SubscriberLastName]))) > 35 THEN [SubscriberLastName]
                 WHEN len(ltrim(Rtrim([sd].[SubscriberFirstName]))) > 15 THEN [SubscriberFirstName]
                 WHEN len(ltrim(Rtrim([sd].[SubscriberMiddleInitial]))) > 1 THEN [SubscriberMiddleInitial]  
                 WHEN len(ltrim(Rtrim([sd].[Sex]))) > 1 THEN [Sex]
                 WHEN len(ltrim(Rtrim([sd].[Dob]))) > 8 THEN [Dob]   
                 WHEN len(ltrim(Rtrim([sd].[Ssn]))) > 9 THEN [Ssn]
                 WHEN len(ltrim(Rtrim([sd].[FacetsGroup]))) > 8 THEN [FacetsGroup]  
           END AS ErrorValue,           
           @ActiveFlag AS [ActiveFlag]
           FROM [Eligibility].[SubscriberData]
           WHERE len(ltrim(Rtrim([sd].[SubscriberNumber]))) > 9 OR
                 len(ltrim(Rtrim([sd].[SubscriberLastName]))) > 35 OR
                 len(ltrim(Rtrim([sd].[SubscriberFirstName]))) > 15 OR
                 len(ltrim(Rtrim([sd].[SubscriberMiddleInitial]))) > 1 OR  
                 len(ltrim(Rtrim([sd].[Sex]))) > 1 OR
                 len(ltrim(Rtrim([sd].[Dob]))) > 8 OR   
                 len(ltrim(Rtrim([sd].[Ssn]))) > 9 OR
                 len(ltrim(Rtrim([sd].[FacetsGroup]))) > 8 

Advertisement

Answer

Ideally, your source table should be defined so that each field cannot be larger than the defined maximum. I am therefore guessing (hoping) that this is a bit of a one-off exercise to identify bad data and fix it, before fixing the underlying table definition.

As @Matt commented, lots of len(ltrim(rtrim( in here, which is going to make this slow.

And as @Arvo points out, you will only log the first error in each row – e.g. if SubscriberNumber and SubscriberLastName are both too long, only SubscriberNumber will get logged.

You should ensure your data is trimmed when writing it. This will remove the need to ltrim(rtrim( all over the shop. If necessary, run a one-off query across your table to fix the existing data values.

Your where clause is probably as efficient as it’s going to be (once you lose all those trims), and could be used either to drive a cursor or to populate a temp table that you can then query several times – once for each field check.

The latter solution might look like this. First get the rows that have errors:

SELECT
     [sd].[SuscriberDataId]
    ,[sd].[SubscriberNumber]
    ,[sd].[SubscriberLastName]
    ,[sd].[SubscriberFirstName]
    ,[sd].[SubscriberMiddleInitial]
    ,[sd].[Sex]
    ,[sd].[Dob]
    ,[sd].[Ssn]
    ,[sd].[FacetsGroup]
INTO #temp
FROM [Eligibility].[SubscriberData] [sd]
WHERE
    len([sd].[SubscriberNumber]) > 9 OR
    len([sd].[SubscriberLastName]) > 35 OR
    len([sd].[SubscriberFirstName]) > 15 OR
    len([sd].[SubscriberMiddleInitial]) > 1 OR  
    len([sd].[Sex]) > 1 OR
    len([sd].[Dob]) > 8 OR   
    len([sd].[Ssn]) > 9 OR
    len([sd].[FacetsGroup]) > 8 

Then, for one field at a time, get the rows which break the rules:

-- SubscriberNumber check
INSERT INTO [Elig].[dbo].[ErrorTable]
    (
        [SeqId],
        [CodeId],
        [SubjectArea],
        [FieldName],
        [TableName],
        [ErrorValue],
        [ActiveFlag]
    )

SELECT
    [t].[SuscriberDataId],
    @InvalidLength,
    @SubjectArea,
    'SubscriberNumber',
    'Eligibility.SubscriberData',
    [t].[SubscriberNumber],
    @ActiveFlag
FROM #temp
WHERE len([t].[SubscriberNumber]))) > 9

Repeat for the next field, etc.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement