Your date literal needs to be surrounded in single quotes (I use CHAR(39) usually since it is easier to read and doesn't require escaping). Otherwise you are saying:
WHERE birth_date = (12) - (12) - (2000)
Which resolves to:
WHERE birth_date = -2000
Which resolves to DATEADD(DAY, -2000, '1900-01-01')
or:
WHERE birth_date = '1894-07-11'
This is probably not going to yield the results you want.
With typical SQL injection warnings in place of course, and assuming that @columnName
is always a string or date/time column, here is how I would re-write your stored procedure (though I would probably try to avoid the dynamic SQL altogether if I could).
ALTER PROCEDURE dbo.aaa
@columnName NVARCHAR(10),
@comparisonParam NVARCHAR(10),
@val NVARCHAR(100)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT * FROM dbo.Sheep WHERE '
+ QUOTENAME(@columnName) + @comparisonParam + CHAR(39)
+ REPLACE(@val, CHAR(39), CHAR(39) + CHAR(39))
+ CHAR(39);
EXEC sp_executesql @sql;
END
GO
In order to thwart potential issues you may want to add validation for columns and data types, and ensure that the operation is one you expect. e.g.
CREATE PROCEDURE dbo.bbb
@columnName NVARCHAR(10),
@comparisonParam NVARCHAR(10),
@val NVARCHAR(100)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @delimiter CHAR(1);
SELECT @delimiter = CASE
WHEN [system_type_id] IN
(104,48,52,56,127,59,60,62,106,108,122) THEN '' -- numeric
WHEN [system_type_id] IN
(35,40,41,42,43,58,61,99,167,175,231,239) THEN CHAR(39) -- string
END FROM sys.columns WHERE [object_id] = OBJECT_ID(N'dbo.Sheep')
AND name = @columnName;
IF @delimiter IS NULL
BEGIN
RAISERROR('Column ''%s'' was not found or an unexpected data type.', 11, 1,
@columnName);
RETURN;
END
IF @comparisonParam NOT IN (N'=', N'>=', N'<=', N'<', N'>', N'LIKE')
BEGIN
RAISERROR('Comparison param ''%s'' was not valid.', 11, 1, @comparisonParam);
RETURN;
END
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT * FROM dbo.Sheep WHERE '
+ QUOTENAME(@columnName) + ' ' + @comparisonParam + ' '
+ @delimiter + REPLACE(@val, CHAR(39), CHAR(39) + CHAR(39))
+ @delimiter;
EXEC sp_executesql @sql;
END
GO
Now make sure you use an unambiguous date format for your string literals. 12-12-2000
is not a good choice. 20001212
is much better.
There are possibly some ways to do this without dynamic SQL - I gave a very simplified answer here. This may be feasible depending on the data types, the number of potential columns, and the number of operations you want to support.