【问题标题】:Using a Loop to add varying parameters to an SQL Query使用循环向 SQL 查询添加不同的参数
【发布时间】:2018-08-12 12:29:33
【问题描述】:

因此,我尝试在 c# 中的表单上使用条件语句和复选框来有条件地构建 MySQL SQL 查询。我没有看到很多关于它的主题,所以要么我做错了什么(很可能),要么我错过了一些简单的东西。无论哪种方式,我都碰壁了,需要一些帮助。

以下是场景:我正在尝试在 C# 中为我的 MySQL 数据库创建一个搜索表单,并且取决于用户选择的选项取决于搜索的粒度。

所以基本上它看起来像这样:

/*Obviously sanitized
  the variable areas*/
string exportQuery = "SELECT * FROM `/*Schema*/`.`/*Table*/` WHERE `/*PK*/`=";
List<string> parameters = new List<string>();
List<string> fields = new List<string>();
List<string> placeholders = new List<string>();
DataTable exportTemp;
int v = 0;

并且在下面的每一点,它都会进行这样的检查:

 if (/*ACheckBox*/.Checked == true)
 {
     v++;
     /*String variable I initialized earlier*/ = DateTimePickerOnForm.Value.ToString("yyyy-MM-dd");
     parameters.Add(/*String variable I initialized earlier*/);
     fields.Add("AND `/*FieldX*/`=@/*FieldVar*/ ");
     placeholders.Add("@/*FieldVar*/");
 }

最后将它们全部计数并开始添加:

 if (v > 0)
 {
     //Build the custom Query
     foreach (string s in fields)
     {
         exportQuery += s;
     }
     //tack on the closing semicolon
     exportQuery += ";";
     Program.conn.Open();
     using (MySqlCommand data = new MySqlCommand(exportQuery, Program.conn))
     {
         data.Prepare();
         for (int f = 0; f < v; f++)
         {
             data.Parameters.AddWithValue("\"" + placeholders[f] + "\"", parameters[f]);
         }
         //Datatable prep
         exportTemp = Program.FillTable(data);/*this runs the query through the database*/
      }

但是,我收到未定义的变量错误(例如“必须定义字段 1”)。现在提供一些快速说明以进行澄清。

• 引发错误的地方是在循环中添加的第一个变量中。

• 我刚刚发表评论的所有区域都已清理,但当再次使用时,我会重复评论名称。

• 如果我不应该使用这种方法,我愿意接受其他方法。

编辑: • 我试图传递的第一个参数是一个字符串,选择日期时间区域的 sn-p 是为了简单地展示我的方法。

感谢任何帮助,显然是在尝试清理我的输入,但我不确定我做错了什么。

【问题讨论】:

  • 使用AddWithValue 意味着数据库引擎必须猜测真实的数据类型。鉴于这件事的性质,这意味着您可能会将它们传递为 Object 或字符串,从而更难正确猜测。我会回到绘图板并避免使用通用方法
  • @Plutonix 我可能是错的,但虽然你是对的,但我认为更准确地说参数是作为盒装字符串传入的。也许有一个 List 而不是 List 作为参数将意味着参数作为它们需要的数据类型的盒装对象传入,这将实现 OP 的目标
  • @AlexC.Unfortunately that didn't do it。 Plutonix 可能是对的,但我仍然希望其他人能来提供帮助,我不确定编写条件查询的更好方法。

标签: c# mysql loops input-sanitization


【解决方案1】:

如果 MySQL 表中有 DATE 或 DATETIME 列,则必须传递 System.DateTime 类型的参数值,而不是带有格式化日期的字符串。

List<object> parameters = new List<object>();
...
parameters.Add(fieldVar, DateTimePickerOnForm.Value);
...

【讨论】:

  • 我应该澄清一下,第一个字段是一个 varchar,我正在传递一个字符串,我抓住了一个日期,因为它是我能抓住的最简单的 sn-p 形式条件。我之前没有时间将值传递到表单中。此外,问题在于它说变量是未定义的,不是无效的。
  • 您是否检查了生成的查询字符串exportQuery?它是否包含您所期望的内容?
  • 是的,谢天谢地,它确实正确地构建了查询。我考虑了空格以供读取,然后根据我的操作方式修剪最后并添加分号。所以添加刚刚生成的日期: SELECT * FROM /*Schema*/./*Table*/ WHERE *PK*/=@/*PKVar*/ AND *Field1*/=@*Field1Var*/ AND *Field2*/=@/*Field2Var*/;
  • 您的某些字段名称在 MySQL 中是否为 reserved word?您应该用反引号字符 (`) 将字段名称括起来以避免此问题。 (顺便说一句。经过清理的查询是否也符合预期?)
  • 是的,每个字段都被(`)包围,不,没有保留字,抱歉保密,必要的邪恶。我现在有一个故障排除输出,它会吐出使用的全部导出查询,然后是每个占位符和变量,因为它们应该通过“data.Parameters.AddWithValue”部分。一切似乎都是正确的。
【解决方案2】:

变化:

data.Parameters.AddWithValue("\"" + placeholders[f] + "\"", parameters[f]);

到:

data.Parameters.AddWithValue(placeholders[f], parameters[f]);

placeholders[f] 包含@/*FieldVar*/,这是AddWithValue 期望的参数名称。如果你用额外的双引号括起来,你最终会尝试使用一个名为 "@/*FieldVar*/" 的参数,它与你的 SQL 查询不匹配并导致“field1 must be defined”错误。

【讨论】:

    猜你喜欢
    • 2016-01-19
    • 1970-01-01
    • 2011-05-30
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 2019-09-30
    • 1970-01-01
    相关资源
    最近更新 更多