1
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...

When I run the code, it returns with a result of "SystemNavn" (which is the name of the column in the table), instead of the value of that column in the current row. What am I doing wrong?

4

3 回答 3

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"
于 2013-05-07T12:43:10.370 回答
1

在这种情况下,您的查询不需要任何参数。做就是了

SQL = "SELECT SystemNavn FROM SystemOps"  

这是安全的。如果稍后您需要过滤它,您可以执行以下操作:

SQL = "SELECT SystemNavn FROM SystemOps WHERE COL_A = @ColA"

仅供参考,对于上面的代码,由于它是 VARCHAR 类型,因此它的执行方式如下:

SELECT 'SystemNavn' FROM SystemOps

这就是为什么您要返回“SystemNavn”。

于 2013-05-07T12:35:35.867 回答
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注入。

于 2013-05-07T12:28:47.307 回答