如何将参数传递给SQL Query?

时间:2016-05-30 08:57:06

标签: sql-server vb.net

我有一个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的代码有什么问题。你能否就这个问题给我一个建议?

4 个答案:

答案 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中创建了一个表,并对上述所有内容进行了测试,但它确实有效。