当对多个变量使用clr / c ++时如何在查询中添加参数

问题描述 投票:0回答:1

我希望能够向查询中添加参数,以使我的语句不易受到sql注入的伤害

我的代码(关键部分用**包围,因为我无法将代码设为粗体)

        OleDbConnection^ existingSqlConnection = nullptr;
        existingSqlConnection = gcnew OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0;" +
            "Data Source =" + "myDatabaseV3.accdb");
        **String^ sqlText = "SELECT * FROM @tableName WHERE @fieldName = @fieldEntityName";
        OleDbCommand^ dbCommand = gcnew OleDbCommand(sqlText, existingSqlConnection);
        OleDbParameterCollection^ paramCollection = dbCommand->Parameters;
        dbCommand->Parameters->Add(gcnew OleDbParameter("@tableName", tableName->ToString()));
        dbCommand->Parameters->AddWithValue("@fieldName", field);**
        dbCommand->Parameters->AddWithValue("@fieldEntityName", fieldEntity);
        **Console::WriteLine(dbCommand->CommandText);
        Console::WriteLine(paramCollection->Count);** 
        existingSqlConnection->Open();
        OleDbDataReader^ reader = dbCommand->ExecuteReader(System::Data::CommandBehavior::CloseConnection);

        return reader;

此输出为

选择*来自@tableName,在@fieldName = @fieldEntityName

3

这清楚地表明有3个参数,但是没有将它们添加到我的查询中,这是我要解决的问题

c++-cli sqlclr
1个回答
0
投票

这不是参数的工作方式。它们不是文本模板的替换值。参数是一种将值传递给查询中的变量的机制,就像将参数传递给存储过程将传递该值以用作查询中的变量一样。

沿着这些行,仅在可以在查询中使用变量的地方才可以使用参数。并且,变量不能用于对象名称,这就是为什么人们在表和/或列名称需要更改时诉诸使用SQL Injection的原因。在您的示例代码中:

  • @tableName永远不可能是查询中的变量,因此它不能是参数
  • @fieldName永远不可能是查询中的变量,因此它不能是参数
  • @fieldEntityName如果应该是值而不是列名,则可以是参数,在这种情况下,它将在查询中保留为@fieldEntityName,并且其值为fieldEntity。] >
  • 请参阅my answer on your related question的第二个选项以了解如何防止SQL注入(简短答案:清理输入)。

而且,使用AddWithValue()也是一种不好的做法。创建具有预期最大大小的参数,然后为其指定一个值,最后将其添加到参数集合中。您要做not

希望它自动检测参数的最大大小,因为它将使用它获得的第一个值,而任何后续的更长的值将被静默截断。
© www.soinside.com 2019 - 2024. All rights reserved.