英文:
Golang Gorm Escaping characters in Where clause not working
问题
我有以下工作正常的查询:
if err := rs.db.
Preload("Artist").
Preload("Genre").
Where("MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`) AGAINST (? IN BOOLEAN MODE)", text).
Find(&rs.Records).
Error; err != nil {
utils.Logger.Error("error while preloading artists and genres for record", zap.Error(err))
return errors.New(err.Error())
}
它按预期填充了&rs.Records
。
但是我需要使查询更加灵活,所以我尝试添加一些通配符,因此原始查询应该如下所示:
SELECT * FROM records WHERE MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`)
AGAINST ('* TEXT YOU WANT TO SEARCH *' IN BOOLEAN MODE)
请注意使用了*
。这个转换为我的 Gorm 查询应该是这样的:
if err := rs.db.
Preload("Artist").
Preload("Genre").
Where("MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`) AGAINST (*?* IN BOOLEAN MODE)", text).
Find(&rs.Records).
Error; err != nil {
utils.Logger.Error("error while preloading artists and genres for record", zap.Error(err))
return errors.New(err.Error())
}
它失败并显示以下错误:
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 '? IN BOOLEAN MODE)' at line 1
显然是因为我添加了*
,所以我尝试对其进行转义:
if err := rs.db.
Preload("Artist").
Preload("Genre").
Where("MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`) AGAINST (\\*?\\* IN BOOLEAN MODE)", text).
Find(&rs.Records).
Error; err != nil {
utils.Logger.Error("error while preloading artists and genres for record", zap.Error(err))
return errors.New(err.Error())
}
然而,我得到了相同的错误。我还尝试在其上添加转义的'
:
if err := rs.db.
Preload("Artist").
Preload("Genre").
Where("MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`) AGAINST (\\'\\*?\\*\\' IN BOOLEAN MODE)", text).
Find(&rs.Records).
Error; err != nil {
utils.Logger.Error("error while preloading artists and genres for record", zap.Error(err))
return errors.New(err.Error())
}
但结果是一样的。
你有什么想法,我做错了什么?
谢谢。
英文:
I've got the following query which works just fine:
if err := rs.db.
Preload("Artist").
Preload("Genre").
Where("MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`) AGAINST (? IN BOOLEAN MODE)", text).
Find(&rs.Records).
Error; err != nil {
utils.Logger.Error("error while preloading artists and genres for record", zap.Error(err))
return errors.New(err.Error())
}
It populates &rs.Records
as expected.
But I need my query to be more flexible, so I tried to add some wildcards to it, so the raw query should look like the following:
SELECT * FROM records WHERE MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`)
AGAINST ('* TEXT YOU WANT TO SEARCH *' IN BOOLEAN MODE)
Notice the use of *
. This translated to my Gorm query should be something like:
if err := rs.db.
Preload("Artist").
Preload("Genre").
Where("MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`) AGAINST (*?* IN BOOLEAN MODE)", text).
Find(&rs.Records).
Error; err != nil {
utils.Logger.Error("error while preloading artists and genres for record", zap.Error(err))
return errors.New(err.Error())
}
It fails with the following error:
> 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 '? IN BOOLEAN MODE)' at line 1
so clearly it's because I added *
, so I tried to escape it:
if err := rs.db.
Preload("Artist").
Preload("Genre").
Where("MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`) AGAINST (\\*?\\* IN BOOLEAN MODE)", text).
Find(&rs.Records).
Error; err != nil {
utils.Logger.Error("error while preloading artists and genres for record", zap.Error(err))
return errors.New(err.Error())
}
yet I'm getting the same error. I also tried adding escaped '
to it:
if err := rs.db.
Preload("Artist").
Preload("Genre").
Where("MATCH(`title`, `label`, `description`, `catalog_number`,`barcode`) AGAINST (\\'\\*?\\*\\' IN BOOLEAN MODE)", text).
Find(&rs.Records).
Error; err != nil {
utils.Logger.Error("error while preloading artists and genres for record", zap.Error(err))
return errors.New(err.Error())
}
But the result is the same.
Any ideas what am I doing wrong?
Thanks.
答案1
得分: 1
AGAINST()
函数的参数必须是一个带引号的字符串、一个字符串参数或一个常量字符串表达式。
以下是无效的,因为*
字符需要在一个字符串值内:
AGAINST (*?* IN BOOLEAN MODE)
以下也是无效的,因为参数占位符不能在引号内:
AGAINST ('*?*' IN BOOLEAN MODE)
因此,你有两个选择,要么将表达式创建为字符串字面量和参数的连接:
AGAINST (CONCAT('*', ?, '*') IN BOOLEAN MODE)
要么在你的应用程序中将*
字符连接到模式中,并将其作为参数值传递。
AGAINST (? IN BOOLEAN MODE)
英文:
The argument to AGAINST()
must be a quoted string, or a string parameter, or a constant string expression.
The following is not valid, because the *
characters need to be inside a string value:
AGAINST (*?* IN BOOLEAN MODE)
The following is also not valid, because a parameter placeholder must not be inside the quotes:
AGAINST ('*?*' IN BOOLEAN MODE)
So your options are either create the expression as a concatenation of a string literal and parameter:
AGAINST (CONCAT('*', ?, '*') IN BOOLEAN MODE)
Or else concatenate the *
characters into your pattern in your application, and pass that as the parameter value.
AGAINST (? IN BOOLEAN MODE)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论