Joshylad
Joshylad

Reputation: 133

SQL Using parameter in WHERE statement

Think I am missing something really obvious but I want to use a parameter in a where statement but when I do I get the following error (This is being run as a stored procedure if that makes any difference)

Invalid column name 'John'

The where statement in question

   USE [Reports]
GO

/****** Object:  StoredProcedure [Reports].[Alarm_TestSignOffFull_Qry]    Script Date: 25/10/2018 08:56:26 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [Reports].[CustomerSearch]
    -- Add the parameters for the stored procedure here  

     @Database VARCHAR(20)
    ,@Schema VARCHAR(20)
    ,@Name VARCHAR(20)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    EXEC ('

            USE ' + @Database + '

            SELECT Customer.Name,
                   [Product Categories].[Product Number]

            RIGHT JOIN ((' + @Schema +'.Customer INNER JOIN ' + @Schema +'.Client ON Customer.Name = Client.Name) 
                LEFT JOIN ' + @Schema +'.Product ON Client.Name = Product.Client) 
            ON [Product Categories].[Product Number] = Client.Product

            WHERE (Customer.Name = ' + @Name + ' AND Customer.Order = ''Y'') OR (Client.Name = ' + @Name + ' AND Customer.Order = ''Y'');

'           )
END
GO

The parameter @Name is declared as VARCHAR(20)

Dont think too much about it had to find and replace table names and column names and stuff to make sure I am allowed to post it.

The select on the real thing also brings through a lot more fields but not too worried about that for this question

To emphasize it is the where statements that are going wrong the rest of the query works and it all works when I do not use any parameters

Upvotes: 0

Views: 103

Answers (4)

Thom A
Thom A

Reputation: 95561

I'm posting this as answer, as the comments aren't enough to explain, however, there is far too little detail here to actually answer the OP's question.

Firstly, the error the OP is getting would be impossible to get with the tiny amount of SQL they have provided. If we expand it into a full Pseudo-SQL query, we get:

SELECT {Columns}
FROM Customer
WHERE Customer.Name = (' + @Name + ');

This would return rows in the Customer table, where Name has the literal string value ' + @Name + '. Very unlikely.

I suspect that the OP simply needs to do:

SELECT {Columns}
FROM Customer
WHERE Customer.Name = @Name;

HOWEVER, the error the OP is getting strong implies they are using Dynamic SQL. This means they have a query like this:

DECLARE @SQL nvarchar(MAX);
DECLARE @Name varchar(20) = 'John';
SET @SQL = N'SELECT {Columns} FROM Customer WHERE Customer.Name = (' + @Name + ');';
EXEC (@SQL);

The problem here is that translates into the SQL:

SELECT {Columns} FROM Customer WHERE Customer.Name = (John);

Notice, no quotes around John, and why the error.

What you are doing here, however, is a very bad idea. Raw string concatenation like that leaves your SQL wide open to injection(SQL injection). Parametrise your SQL:

DECLARE @SQL nvarchar(MAX);
DECLARE @Name varchar(20) = 'John';
SET @SQL = N'SELECT {Columns} FROM Customer WHERE Customer.Name = @dName;'
EXEC sp_executesql @SQL, N'@dName varchar(20)',@dName = @Name;`

Edit: Ok, the OP has provided us with their query. Honestly, it's a mess, far worse that I wanted it to be. Like i said before, raw string concatenation is an awful idea, it leaves you open to injection. You can't get rid of concatenation for dynamic objects, but you can use QUOTENAME, which makes the code safe(r).

You're also missing a FROM; no idea what that needs to be, so i've left that as pseudo-sql. That RIGHT JOIN is very messy too, but I've no idea what you're trying to achieve there.

Anyway, this need to replace your EXEC command. Read the below, understand the below, and don't make the mistake of concatenating raw strings in your dynamic SQL:

DECLARE @SQL nvarchar(MAX)

SET @SQL = N' USE ' + QUOTENAME(@Database) + N';' + NCHAR(10) +
           N'SELECT Customer.Name,'  + NCHAR(10) +
           N'       [Product Categories].[Product Number]' + NCHAR(10) +
           --where is your FROM?
           N'FROM {Something}' + NCHAR(10) + --This needs fixing
           N'     RIGHT JOIN((' + QUOTENAME(@Schema) + N'.Customer' + NCHAR(10) + --This whole thing is messy, but i'm not fixing it, as I have no data
           N'                 INNER JOIN ' + QUOTENAME(@Schema) + N'.Client ON Customer.Name = Client.Name)' + NCHAR(10) +
           N'                 LEFT JOIN ' + QUOTENAME(@Schema) + N'.Product ON Client.Name = Product.Client)ON [Product Categories].[Product Number] = Client.Product' + NCHAR(10) +
           N'WHERE (Customer.Name = @dName' + NCHAR(10) +
           N'   AND Customer.[Order] = ''Y'')' + NCHAR(10) +
           N'   OR (Client.Name = @dName' + NCHAR(10) +
           N'   AND Customer.[Order] = ''Y'');';

EXEC sp_executesql @SQL, N'@dName varchar(20)', @dName = @Name;

Upvotes: 4

Brave Soul
Brave Soul

Reputation: 3620

try giving single quotes in where clause

WHERE (Customer.Name = ''' + @Name + ''' AND Customer.Order = ''Y'') 
   OR (Client.Name = ''' + @Name + ''' AND Customer.Order = ''Y'');

Upvotes: 0

Ilyes
Ilyes

Reputation: 14928

You are using a Dynamic SQL, and if you print your query it will be like

WHERE Customer.Name = (John)

And that's wrong, you can do like

EXECUTE sp_executesql N' ..WHERE Customer.Name = @CName', 
N'@CName VARCHAR(20)', 
@CName = 'John';

Or even

--@Name should be declared and has 'John' value
EXECUTE sp_executesql N' ..WHERE Customer.Name = @CName', 
N'@Name VARCHAR(20)', 
@Name = @Name;

Why does SQL think that the parameter is a column and not just plain text?

Well, as you can see before, the parameter you pass will be John not 'John', thus SQL Server will think it's a column name.

Upvotes: 0

user2042214
user2042214

Reputation: 165

If you are directly write in sql then you can use as below

 WHERE Customer.Name = @Name  

Upvotes: 0

Related Questions