Try
Using connection As New SqlConnection(ConnectionString)
connection.Open()
SQL = "SELECT @PARAM FROM SystemOps"
sqlCmd = New SqlClient.SqlCommand(SQL, connection)
sqlCmd.Parameters.Add(New SqlClient.SqlParameter("@PARAM", SqlDbType.VarChar)).Value = "SystemNavn"
' .. and so on...
当我运行代码时,它返回的结果为"SystemNavn"
(这是表中列的名称),而不是当前行中该列的值。我做错了什么?
答案 0 :(得分:2)
您不能将参数名称用于列名或任何其他SQL语法。您只能将参数用作文字值的占位符。参数总是被替换为值的文字形式,因此在您的示例中,正在运行的命令基本上被评估为:
SELECT 'SystemNavn` FROM SystemOps
为了拥有一个变量列名,我建议动态构建SQL字符串,如下所示:
Dim columnName As String = "SystemNavn"
SQL = "SELECT [" & columnName & "] FROM SystemOps"
但是,通过这样做,您可能会遇到潜在的SQL注入攻击,因此您需要小心。我知道,在这种情况下避免攻击的最安全的方法是从数据库中获取列名列表,并将columnName
变量与该列表进行比较,以确保它实际上是有效的列名。
当然,如果列名永远不会改变,那么就没有理由让它成为变量。在这种情况下,只需将其直接硬编码到SQL命令中,从而避免使用参数或变量:
SQL = "SELECT SystemNavn FROM SystemOps"
答案 1 :(得分:1)
在这种情况下,您的查询不需要任何参数。只是做
SQL = "SELECT SystemNavn FROM SystemOps"
这是安全的。如果以后需要对此进行过滤,则可以执行以下操作:
SQL = "SELECT SystemNavn FROM SystemOps WHERE COL_A = @ColA"
仅供参考,对于上面的代码,因为它是VARCHAR类型,所以它的执行方式如下:
SELECT 'SystemNavn' FROM SystemOps
这就是为什么你要'SystemNavn'回来了。
答案 2 :(得分:0)
您不能使用参数指定列或表的名称。
参数集合用于指定要搜索,插入,更新或删除的值。
您的代码应更改为此类
Using connection As New SqlConnection(ConnectionString)
connection.Open()
SQL = "SELECT SystemNavn, <other fiels if needed> " & _
"FROM SystemOps WHERE <keyfield_name> = @PARAM"
sqlCmd = New SqlClient.SqlCommand(SQL, connection)
sqlCmd.Parameters.AddWithValue("@PARAM", paramValue)
......
End Using
当然上面的例子假设您有一个WHERE子句,如果您想要无条件地检索SystemNavn列的每个值,那么您不需要参数化查询,因为您的sql命令的每个部分都是由您提供的并且不用担心sql注入。