我希望能够向查询中添加参数,以使我的语句不易受到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个参数,但是没有将它们添加到我的查询中,这是我要解决的问题
这不是参数的工作方式。它们不是文本模板的替换值。参数是一种将值传递给查询中的变量的机制,就像将参数传递给存储过程将传递该值以用作查询中的变量一样。
沿着这些行,仅在可以在查询中使用变量的地方才可以使用参数。并且,变量不能用于对象名称,这就是为什么人们在表和/或列名称需要更改时诉诸使用SQL Injection的原因。在您的示例代码中:
@tableName
永远不可能是查询中的变量,因此它不能是参数@fieldName
永远不可能是查询中的变量,因此它不能是参数@fieldEntityName
如果应该是值而不是列名,则可以是参数,在这种情况下,它将在查询中保留为@fieldEntityName
,并且其值为fieldEntity
。] >请参阅my answer on your related question的第二个选项以了解如何防止SQL注入(简短答案:清理输入)。
而且,使用AddWithValue()
也是一种不好的做法。创建具有预期最大大小的参数,然后为其指定一个值,最后将其添加到参数集合中。您要做not