2017-07-29 85 views
0

我正在尝试编写查询在表上搜索,但我得到了通用1064 MySQL语法错误。我没有看到我的查询有什么问题......事实上,我有另一个查询就像它工作正常。MySQL错误1064:搜索查询不按预期方式工作

查询在Go中使用SQL驱动程序,所有?都将在运行查询之前转换为值。

这是我的错误:

Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT tax.* FROM tax JOIN user_tax ON user_tax.tax_id = tax.id WHERE u' at line 3

例如,这是工作的查询:

SELECT tax.* 
FROM tax 
JOIN user_tax 
    ON user_tax.tax_id = tax.id 
WHERE user_tax.user_id = ? 
    AND tax.deleted_at IS NULL 
    AND user_tax.deleted_at IS NULL 

上面的查询会找到一个给定用户的所有纳税记录。

现在我试图做同样的确切查询,除了现在它是一个“搜索”查询。它需要一个搜索字符串并在税表的namerate列中查找。这是它:

SET @searchString = '%?%'; 

SELECT tax.* 
FROM tax 
JOIN user_tax 
    ON user_tax.tax_id = tax.id 
WHERE user_tax.user_id = ? 
    AND tax.deleted_at IS NULL 
    AND user_tax.deleted_at IS NULL 
    AND tax.name LIKE @searchString 
     OR tax.rate LIKE @searchString 

这是代码查询:

var taxes []Tax 
err := r.db.Select(&taxes, ` 
    SET @query = '%?%'; 

    SELECT tax.* 
    FROM tax 
    JOIN user_tax 
     ON user_tax.tax_id = tax.id 
    WHERE user_tax.user_id = ? 
     AND tax.deleted_at IS NULL 
     AND user_tax.deleted_at IS NULL 
     AND tax.name LIKE @query 
      OR tax.rate LIKE @query 
`, q, userId) 
+1

您的接口只允许传入一个查询。我建议您学习如何使用正确的参数。 –

+0

哦,很好,我打算在'%s'的位置放一个'?'。刚刚更新了我的代码以及问题。仍然得到相同的错误。 – Lansana

+0

还将'@ query'改为'@ searchString',因为这可能会让事情混淆,我没有试图将查询放入查询中。 – Lansana

回答

1

我不明白为什么这样做SET @query并把它传递它里面时,您可以使用使用绑定参数做?

所以这里是解决方案(我不熟悉go所以请抱歉,如果有毛病go代码):

var taxes []Tax 
query := "%something%youre%looking%for%" 
err := r.db.Select(&taxes, ` 

    SELECT tax.* 
    FROM tax 
    JOIN user_tax 
     ON user_tax.tax_id = tax.id 
    WHERE user_tax.user_id = ? 
     AND tax.deleted_at IS NULL 
     AND user_tax.deleted_at IS NULL 
     AND (
       tax.name LIKE ? 
       OR 
       tax.rate LIKE ? 
      ) 

`, q, userId, query, query) 

或尝试这个(我不知道是否会工作):

var taxes []Tax 
query := "something" 
err := r.db.Select(&taxes, ` 
    SET @query = CONCAT('%', ?, '%'); 

    SELECT tax.* 
    FROM tax 
    JOIN user_tax 
     ON user_tax.tax_id = tax.id 
    WHERE user_tax.user_id = ? 
     AND tax.deleted_at IS NULL 
     AND user_tax.deleted_at IS NULL 
     AND (
       tax.name LIKE @query 
       OR 
       tax.rate LIKE @query 
      ) 

`, q, query, userId) 
+0

是的,这将工作......但是有没有办法不必传递'查询'N次?如果我有30列......这就是为什么我试图在查询中设置变量的原因,所以我只需绑定一件事,然后重新使用它。 – Lansana

+1

@Lansana你在开玩笑吗?当你有严格的sql查询时,为什么要考虑动态时刻? – num8er

+0

好吧,这是来自一个SQL经验最少的人,但通常在编程中,我可以记住一个值并使用它来保持干净。我想这不是它如何在SQL中工作? – Lansana

1

由MySQL报告的语法错误包含了咒语“检查对应于你的MySQL服务器版本正确的语法使用近“手册”随后查询THA的后部分t不适合已被解析并被发现为正确的主要部分。

当错误消息中报告的查询部分看起来不正确时,通常会在它之前缺少某些内容。

在你的情况下,似乎没有遗漏,这导致了一个单一的结论:你试图运行两个查询(正确分隔;),但你用来发送查询到服务器的库不知道,并认为它只是一个查询。在连接的另一端发生同样的情况,MySQL服务器在第一个查询(及其终止;)后发现的所有内容都是“语法错误”。

不要在一次调用中发送两个查询,也不要在同一个字符串中使用允许多个查询的调用(如果这种调用由库提供​​)。

2

如果你想避免相同的值多次绑定,可以将其绑定在一个交叉连接子查询一次,重用值:

SELECT tax.* 
FROM tax 
JOIN user_tax 
    ON user_tax.tax_id = tax.id 
CROSS JOIN (SELECT ? as q) sub 
WHERE user_tax.user_id = ? 
    AND tax.deleted_at IS NULL 
    AND user_tax.deleted_at IS NULL 
    AND (tax.name LIKE sub.q 
     OR tax.rate LIKE sub.q) 

现在只需绑定%s%作为第一个参数。

+0

这是否有任何重大性能影响? – Lansana

+0

@Lansana我看到你想要的简单解决方案。太好了! – num8er

+0

@Lansana - 我不期望任何性能问题。子查询应该只执行一次。 –