我有一个SQLQuery:
SELECT * FROM (select ROW_NUMBER() OVER( ORDER BY @sortColumns ) AS 'RowNumber'
FROM MyTable WHERE '@keyword' = '' OR (AppId = '@keyword'))
atd WHERE (RowNumber between @startRecord and @endRecord);
查询中有4个参数:
sortColumns
关键字
startRecord
ENDRECORD
我使用VB.NET语言打开连接,并使用Command.Paremeters通过4个参数将值传递到查询中:
Dim sortColumns = "AppId ASC"
Dim keyword = "abc"
Dim startN As Integer = 1
Dim endN As Integer = 20
Dim ds As New DataSet()
Dim strDatabaseConnectionString As String = ConfigHelper.MainConnectionString
Using connection As New SqlClient.SqlConnection(strDatabaseConnectionString)
Using cmd As New SqlClient.SqlCommand(query, connection)
cmd.Parameters.Add("@sortColumns", SqlDbType.NVarChar).Value = sortColumns
cmd.Parameters.Add("@keyword", SqlDbType.NVarChar).Value = keyword
cmd.Parameters.Add("@startRecord", SqlDbType.Int).Value = startN
cmd.Parameters.Add("@endRecord", SqlDbType.Int).Value = endN
Dim adapter As New SqlClient.SqlDataAdapter(cmd)
adapter.Fill(ds)
End Using
End Using
当代码遇到" adapter.Fill(ds)" 行时,会产生异常。
异常消息:在a中指定的非布尔类型的表达式 预期条件的背景
我的怀疑:
问题:我不知道我用来将值传递给sqlquery的代码有什么问题。你能否就这个问题给我一个建议?
答案 0 :(得分:1)
你有'@keyword',字面意思是字符串“@keyword”。如果要使用@keyword参数,请删除单引号。
您不能在参数中引用列名。这是SQL Server的限制,因为它需要在应用参数之前编译您的查询。
答案 1 :(得分:0)
如果我没错,你的查询将是:
SELECT
*
FROM (
select
ROW_NUMBER() OVER( ORDER BY 'AppId ASC' ) AS 'RowNumber'
FROM
MyTable
WHERE
(''abc'' = '')
OR (AppId = ''abc'') ) atd
WHERE
(RowNumber between 1 and 20);
修改强>
经过短暂的研究后,我相信Sql Server会尝试执行此操作:
exec sp_executesql N'SELECT * FROM (select ROW_NUMBER() OVER( ORDER BY @sortColumns ) AS ''RowNumber'' FROM MyTable WHERE ''@keyword'' = '' OR (AppId = ''@keyword'')) atd WHERE (RowNumber between @startRecord and @endRecord)',
N'@sortColumns nvarchar(9),@keyword nvarchar(3),@startRecord int,@endRecord int',@sortColumns=N'AppId ASC',@keyword=N'abc',@startRecord=1,@endRecord=20
对于像我这样的查询
select @column from Table where @column = 1
执行Sql Server:
exec sp_executesql N'select @column from Table where @column = 1',N'@column nvarchar(10)',@column=N'contractId'
并产生错误:
Msg 245,Level 16,State 1,Line 1 将nvarchar值'contractId'转换为数据类型int时,转换失败。
因此,您无法传递列,因为Sql Server会将其视为字符串。
我认为;唯一的解决方案是从代码中完全构建您的查询并执行它。
类似的东西:
Dim sortColumns = "AppId ASC"
Dim keyword = "abc"
Dim startN As Integer = 1
Dim endN As Integer = 20
Dim sql As String = string.format("SELECT * FROM (select ROW_NUMBER() OVER( ORDER BY {0} ) AS 'RowNumber'
FROM MyTable WHERE @keyword = '' OR (AppId = @keyword))
atd WHERE (RowNumber between @startRecord and @endRecord);", sortColumns)
答案 2 :(得分:0)
问题在于查询,
'@keyword' = ''
不对。 在VB中进行查询,在代码中替换@keyword,而不是在sql中,因此生成的sql是
columnname =''
答案 3 :(得分:0)
您认为无法将列名作为参数传递是正确的。
您可以在VB中创建查询 - 如果您使用的是VS2015,那么您的代码可能看起来像
$
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@keyword", .SqlDbType = SqlDbType.NVarChar, .Size = 50, .Value = keyword})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@startRecord", .SqlDbType = SqlDbType.Int, .Value = startN})
cmd.Parameters.Add(New SqlParameter With {.ParameterName = "@endRecord", .SqlDbType = SqlDbType.Int, .Value = endN})
适用于interpolated string(VS2015的新功能)。对于添加参数,我个人更喜欢这种风格:
.Size
(更改AppId
参数的值以匹配数据库中\n
列的大小。)
我在SQL Server中创建了一个表,并对上述所有内容进行了测试,但它确实有效。