mercredi 16 septembre 2020

Check for two conditions in the same IF statement of a dynamic stored procedure - SQL Server

I have created a dummy table:


CREATE TABLE test (
  id_number NVARCHAR(50) NOT NULL,
  number_of_products NVARCHAR(50)
);

INSERT INTO test 
    (id_number, number_of_products, username)
VALUES 
    (1000077004, 3, 'Jhon Smith'),
    (1000077005, 4, 'Nick Smith'),
    (1000077006, 4, 'Dale Smith'),
    (1000077007, 5, 'Diana Smith'),
    (1000077008, 5, 'Alice Smith'),
    (1000077009, 6, 'Antony Smith'),
    (1000077010, NULL, 'Bruce Smith');

SELECT * FROM test

And I use the following stored procedure to filter the table:

CREATE OR ALTER PROCEDURE [dbo].[sp_dynamicquery1] (
    @TableName NVARCHAR(50),
    @Field NVARCHAR(100) = NULL,
    @Criterion NVARCHAR(100) = NULL,
    @Parameter NVARCHAR(100) = NULL,
    @All VARCHAR(2) = '-1'
)
AS          
BEGIN

    SET NOCOUNT ON;  
 
    DECLARE 
        @SQL NVARCHAR(MAX),
        @SQL_WHERE NVARCHAR(MAX),
        @ParameterDef NVARCHAR(500);

    SET @ParameterDef = '@Parameter NVARCHAR(100)'
    SET @SQL = 'SELECT * FROM ' + @TableName;
    SET @SQL_WHERE = '';

    /* BUILD THE WHERE CLAUSE IF @Field IS PRESENT */

    IF NULLIF ( @Field, '' ) IS NOT NULL BEGIN

        -- Field.
        SET @SQL_WHERE = ' WHERE ' + @Field;

        -- Field Comparison.
        IF @Criterion = 'greater than' AND @Field LIKE '%[^0-9]%'
        BEGIN
            SET @Criterion = ' >'
        END;

        IF @Criterion = 'starts with' AND @Field NOT LIKE '%[^0-9]%'
        BEGIN
            SET @Criterion = ' LIKE ''%@Parameter%'' '
        END;

        SET @SQL_WHERE += CASE @Criterion 
            --WHEN 'greater than' AND @Field LIKE '%[^0-9]%' THEN ' >'
            WHEN 'greater than or equal' AND ISNUMERIC(@Field) THEN ' >=' --This is not valid for a reason
            WHEN 'less than' THEN ' <'
            WHEN 'less than or equal' THEN ' <='
            WHEN 'not equal' THEN ' <>'
            WHEN 'equal' THEN ' ='
            ELSE ''
        END;

        -- Field Parameter.
        SET @SQL_WHERE += ' @Parameter';

        -- Set @Parameter value.
        SET @Parameter =
            CASE WHEN NULLIF ( @Parameter, '' ) IS NOT NULL
                THEN @Parameter
                ELSE @All
            END;

    END

    -- Finish SQL statement.
    SET @SQL = @SQL + ISNULL ( @SQL_WHERE, '' ) + ';';

    -- Execute the dynamic statement.
    EXEC sp_executesql @SQL, @ParameterDef, @Parameter = @Parameter;

END
GO

Even though the CASE WHEN statement works successfully for 1 condition, I want to check multiple conditions like the IF statement posted. Basically if the value of variable @Criterion is 'greater than' AND the column @Field is numeric assign the symbol '>'. But if the @Field parameter is not numeric but rather text (string) use the criterion 'LIKE '%@Parameter%''.

[sp_dynamicquery1] @TableName='test', @Field='number_of_products', @Criterion='greater than', @Parameter = 4

-> Return the last three rows

[sp_dynamicquery1] @TableName='test', @Field='username', @Criterion='starts with', @Parameter = 'J'

-> Return only the first row of John Smith

Aucun commentaire:

Enregistrer un commentaire