我想我确实遗漏了一些明显的东西,但是我想在where语句中使用一个参数,但是当我这样做时,出现以下错误(如果有任何区别,它将作为存储过程运行)
无效的列名“ John”
有问题的where语句
keyof T
参数@Name声明为VARCHAR(20)
不要太想它,必须查找并替换表名,列名和东西以确保允许我发布它。
对真实事物的选择也带来了更多领域,但对此问题并不太担心
为了强调这是哪里语句出了问题,其余的查询仍然有效,而当我不使用任何参数时,所有这些都可以正常工作
答案 0 :(得分:4)
我将其发布为答案,因为评论不足以解释,但是,这里的细节太少,无法真正回答OP的问题。
首先,使用他们提供的少量SQL不可能获得OP出现的错误。如果将其扩展为完整的伪SQL查询,则会得到:
SELECT {Columns}
FROM Customer
WHERE Customer.Name = (' + @Name + ');
这将返回Customer
表中的行,其中Name
具有文字字符串值' + @Name + '
。不太可能。
我怀疑OP只需要做:
SELECT {Columns}
FROM Customer
WHERE Customer.Name = @Name;
但是,OP变得越来越强大的错误意味着他们正在使用动态SQL。这意味着他们有这样的查询:
DECLARE @SQL nvarchar(MAX);
DECLARE @Name varchar(20) = 'John';
SET @SQL = N'SELECT {Columns} FROM Customer WHERE Customer.Name = (' + @Name + ');';
EXEC (@SQL);
这里的问题是转换为SQL:
SELECT {Columns} FROM Customer WHERE Customer.Name = (John);
注意,John
周围没有引号,以及为什么出错。
但是,您在这里所做的是一个非常不好的主意。像这样的原始字符串连接使您的SQL易于进行注入(SQL injection)。参数化您的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;`
编辑:好的,OP向我们提供了他们的查询。老实说,这真是一团糟,更糟的是我想要做到这一点。就像我之前说的那样,原始字符串连接是一个糟糕的主意,它使您可以进行注入。您无法摆脱动态对象的并置,但可以使用QUOTENAME
,这使代码更安全(r)。
您还缺少FROM
;不知道那是什么,所以我把它留为伪SQL。 RIGHT JOIN
也很混乱,但是我不知道您要在那实现什么。
无论如何,这需要替换您的EXEC
命令。阅读下面的内容,理解下面的内容,并且不要犯错误,即在动态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;
答案 1 :(得分:0)
如果您直接用sql编写,则可以按以下方式使用
WHERE Customer.Name = @Name
答案 2 :(得分:0)
您正在使用动态SQL,并且如果您打印查询,它将像
WHERE Customer.Name = (John)
那是错误的,你可以做
EXECUTE sp_executesql N' ..WHERE Customer.Name = @CName',
N'@CName VARCHAR(20)',
@CName = 'John';
甚至
--@Name should be declared and has 'John' value
EXECUTE sp_executesql N' ..WHERE Customer.Name = @CName',
N'@Name VARCHAR(20)',
@Name = @Name;
为什么SQL认为参数是一列而不是纯文本?
好吧,正如您之前看到的那样,您传递的参数将是John
而不是'John'
,因此SQL Server会认为它是列名。
答案 3 :(得分:0)
尝试在where子句中使用单引号
WHERE (Customer.Name = ''' + @Name + ''' AND Customer.Order = ''Y'')
OR (Client.Name = ''' + @Name + ''' AND Customer.Order = ''Y'');