Reputation: 1024
This stored procedure works until I add in a variable. The @sWHERE
variable will be populated from a a fixed input.
I'm not sure what I need to amend ...I've tried adding & and +
Error: 4145, Level 15, State 1, Procedure spUniqueUPRN, Line 12 An expression of non-boolean type specified in a context where a condition is expected, near 'Group'.
Stored Procedure:
USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spUniqueUPRN]
@sWHERE varchar(Max)
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT UPRN INTO TBLTEMP FROM TblA
WHERE @sWHERE
Group BY UPRN
UNION ALL
SELECT UPRN FROM TblP
Group BY UPRN
END
VERSION 2 based on help so far (no where near final just a step)
USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spUniqueUPRN]
@sWHERE varchar(Max)
AS
BEGIN
SET NOCOUNT ON;
----------
DROP TABLE TBLTEMP
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = 'UPRN INTO TBLTEMP FROM TblA ' + QUOTENAME(@sWHERE) + '
Group BY UPRN
UNION ALL
SELECT UPRN FROM TblP
Group BY UPRN
';
EXEC sp_executesql @SQL;
----------
END
Verion 3
USE [DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
ALTER PROCEDURE [dbo].[spUniqueUPRN]
@sDateFrom Date,
@sDateTo Date,
@sUPRN varchar(Max),
@sRiskRating varchar(10),
@sSurveyCompany varchar(Max),
@sPostcode varchar(10),
@sStreet varchar(Max),
@sRegion Int
AS
BEGIN
SET NOCOUNT ON;
----------
DROP TABLE TBLTEMP
DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = 'SELECT UPRN INTO TBLTEMP FROM TblA WHERE 1 = 1 '
IF QUOTENAME(@sDateFrom) IS NOT NULL AND QUOTENAME(@sDateTo) IS NOT NULL
SELECT @SQL = @SQL + ' or SurveyDate BETWEEN ' + QUOTENAME(@sDateFrom) + ' AND ' + QUOTENAME(@sDateTo) + ''''
IF QUOTENAME(@sRiskRating) IS NOT NULL
SELECT @SQL = @SQL + ' or OverAllRiskCategory = ' + QUOTENAME(@sRiskRating) +''''
IF QUOTENAME(@sUPRN) IS NOT NULL
SELECT @SQL = @SQL + ' or UPRN LIKE ' + QUOTENAME(@sUPRN) + ''''
IF QUOTENAME(@sSurveyCompany) IS NOT NULL
SELECT @SQL = @SQL + ' or SurveyCompany LIKE ''%' + QUOTENAME(@sSurveyCompany) + '%'''
SELECT @SQL = @SQL + ' GROUP BY UPRN '
SELECT @SQL = @SQL + ' UNION ALL '
SELECT UPRN FROM TblProperty
IF QUOTENAME(@sPostcode) IS NOT NULL
SELECT @SQL = @SQL + ' or Postcode LIKE ''%' + QUOTENAME(@sPostcode) + '%'''
IF QUOTENAME(@sStreet) IS NOT NULL
SELECT @SQL = @SQL + ' or Street LIKE ''%' + QUOTENAME(@sStreet) + '%'''
IF QUOTENAME(@sRegion) IS NOT NULL
SELECT @SQL = @SQL + 'or Region LIKE ''%' + QUOTENAME(@sRegion) + '%'''
SELECT @SQL = @SQL + 'GROUP BY UPRN'
EXEC sp_executesql @SQL;
----------
END
Upvotes: 0
Views: 143
Reputation: 175924
First of all to pass @sWHERE
as string to stored procedure you need to use dynamic SQL.
Before you use dynamic SQL I strongly recommend to read The Curse and Blessings of Dynamic SQL by Erland Sommarskog.
Your case is SELECT * FROM tbl WHERE @condition:
If you are considering to write the procedure
CREATE PROCEDURE search_sp @condition varchar(8000) AS SELECT * FROM tbl WHERE @condition
Just forget it. If you are doing this, you have not completed the transition to use stored procedure and you are still assembling your SQL code in the client. But this example lapses into Dynamic Search Conditions/Dynamic Crosstab.
The point is that you could use (as proposed in comments)
DECLARE @sql NVARCHAR(MAX) =
N'SELECT *
FROM table_name
WHERE ' + @sWHERE;
EXEC dbo.sp_executesql
@sql;
But this is straight way to SQL Injection attacks. User may call:
EXEC dbo.spUniqueUPRN '1=1; DROP TABLE ....; --'
To sum up, it is up to you if you will use WHERE @condition
. It is possible but I would not go this path.
Upvotes: 1