【问题标题】:error in Search SQL query搜索 SQL 查询中的错误
【发布时间】:2015-07-13 14:39:30
【问题描述】:

我正在尝试创建一个搜索函数,该函数在 GridView 中搜索某个值,然后返回该行。我在 MySQL 工作台中测试了这个查询,它可以工作,但是当查询在 Visual Studio 中运行时,我得到了这个错误:

您的 SQL 语法有错误;检查手册 对应于您的 MySQL 服务器版本,以便使用正确的语法 在第 23 行的“?parameter0”附近

      StringBuilder SQL = new StringBuilder(SearchSQL);
                if (SearchFieldKey != null && SearchFieldKey.Length > 0)
                {
                    if (SearchTerms != null)
                    {
                        SQL.Append(" HAVING ");
                        for (int i = 0; i < SearchFieldKey.Length; i++)
                        {
                            if (SearchFields.ContainsKey(SearchFieldKey[i]))
                            {

                                SQL.Append(SearchFields[SearchFieldKey[i]] + " LIKE ?parameter" + i.ToString());
                                param.Add(new MySqlParameter("parameter" + i.ToString(), "%" + SearchTerms[i] + "%"));

                                if (i != SearchFieldKey.Length - 1)
                                    SQL.Append(" OR ");
                            }
                            else
                                throw new Exception("Error: Attempted to search on invalid field. Check SearchFields Argument.");
                        }
                    }
                }

 SQL.Append(" '); ");
 SQL.Append ("prepare stmt from @sql; execute stmt; deallocate prepare stmt;");

在调试时,我复制了正在运行的确切查询并将其粘贴到 Workbench 中,它可以工作。所以我不知道为什么它不会在视觉工作室中运行。

查询从此代码运行:

 DataTable dtJobs = Job.CustomFill(SQL.ToString(), param);

并且传入的参数是“%TESTING%”

显示数据库行的查询:

private static string SearchSQL
    {
        get
        {
            return @" 
                                                            SET group_concat_max_len=10000000;
                                                            set @sql = null;
                                                                select
                                                                  group_concat(distinct
                                                                    concat(
                                                                       'MAX(CASE WHEN pt.Code = ''', 
                                                                        pt.Code ,
                                                                        ''' THEN jp.AdvisedQty ELSE 0 END) AS `',
                                                                        pt.Code, '`'
                                                                    )
                                                                  ) into @sql
                                                                 FROM customer c
                                                        LEFT JOIN job_address ja ON c.AccountCode = ja.Code AND c.Company_ID = ja.Company_ID
                                                        JOIN  AddressType jat ON ja.AddressType = jat.ID and jat.Description = 'Debtor'
                                                        LEFT JOIN job_new jn ON ja.JobID = jn.ID
                                                        LEFT JOIN job_pieces jp ON ja.JobID = jp.ID
                                                        LEFT JOIN piecestype pt on jp.TypeID = pt.ID
                                                    WHERE c.Company_ID = ?compid;

                                        set @sql = concat('select 
                                                            c.Name,
                                                            COUNT(distinct jn.ID) as Jobs,
                                                            (SELECT Name FROM job_address WHERE AddressType =3 AND JobID = jn.ID) as CollectName,
                                                            (SELECT Name FROM job_address WHERE AddressType =2 AND JobID = jn.ID) as DeliverName,
                                                            ', @sql, ' 
                                                        FROM customer c
                                                        LEFT JOIN job_address ja ON c.AccountCode = ja.Code AND c.Company_ID = ja.Company_ID
                                                        JOIN  AddressType jat ON ja.AddressType = jat.ID and jat.Description = ''Debtor''
                                                        LEFT JOIN job_new jn ON ja.JobID = jn.ID
                                                        LEFT JOIN job_pieces jp ON ja.JobID = jp.ID
                                                        LEFT JOIN piecestype pt on jp.TypeID = pt.ID
                                                   WHERE c.Company_ID = ', ?compid,
                                                    ' GROUP BY c.ID


                                                                            ";
        }
    }

所以我的搜索查询将HAVING c.Name LIKE "%PRL%" '); 放在查询中的 GROUP BY 之后。然后 Append 语句将准备好的 stmts 放在查询的末尾。

【问题讨论】:

  • 我认为您需要使用 '@' 而不是 '?'绑定参数时。
  • 添加代码以打印出完整的 SQL,以便您可以看到它。从中应该很明显问题是什么。如果由于某种原因,这对您来说并不明显,请将完整的 SQL 编辑到问题中,并且在这里的某个地方可能会很明显。但是,乍一看,您缺少参数之间的逻辑 ANDOR 运算符。
  • @EvanMulawski MySql 可以使用?
  • 参数是否已经带有百分号?如果是这样,您不需要在此处再次添加它们:param.Add(new MySqlParameter("parameter" + i.ToString(), "%" + SearchTerms[i] + "%"));
  • @KoBE 不,它还没有出现在百分号中

标签: c# mysql asp.net visual-studio


【解决方案1】:

根据您发布的 SQL,问题在于双引号:

HAVING c.Name LIKE "%PRL%"

SQL 标准规定双引号用于标识符名称,例如别名、列、表、模式、过程、视图或数据库。如果你想要字符串文字,你需要在这里使用单引号:

HAVING c.Name LIKE '%PRL%'

这是 MySql 在遵循标准方面做得很差的众多地方之一(取决于您如何设置 ANSI_QUOTES),但如果您想确定,请尝试使用单引号。

【讨论】:

  • 不加单引号并不能解决问题param.Add(new MySqlParameter("parameter" + i.ToString(), '%' + SearchTerms[i] + '%'));
  • 这不是单引号的所在。我怀疑问题出在您的 CustomFill() 方法中。
  • 那么单引号应该放在哪里?
  • 我发布了 CustomFill() 方法返回的查询。我看不出它有什么问题
  • 它的问题是错误的 ansi_quotes 设置它不是有效的 sql。您需要让它生成带单引号的字符串文字。更糟糕的是,您看到查询中的值被替换的事实是一个HUGE危险信号,它没有正确处理参数,并可能使您的应用程序对sql注入攻击敞开大门。
猜你喜欢
  • 2017-05-16
  • 2015-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 1970-01-01
相关资源
最近更新 更多