Go postgresql LIKE 查询

25

我正在使用 Go 和 PostgreSQL(pq 驱动程序),我有以下查询

SELECT p.id, p.name, p.description, p.price, p.image, p.rate
FROM products AS p
WHERE LOWER(p.name) LIKE %$1% ORDER BY p.rate DESC

如果我直接在PostgreSQL中执行此查询,它可以工作,但在Golang中会提示错误:

pq: syntax error at or near "%"

我该如何修复它?我试过用"\%"但没用。

谢谢。

这是完整的源代码。

func FindByName(name *string) ([]*Product, error) {
    db, err := db.StablishConnection()
    if err != nil {
            log.Fatal(err)
            panic(err)
    }
    defer db.Close()

    query := `SELECT p.id, p.name, p.description, p.price, p.image, p.rate
        FROM products AS p
        WHERE LOWER(p.name) LIKE %$1% ORDER BY p.rate DESC`

    product_rows, err := db.Query(query, name)

    if err != nil {
            return nil, err
    }

    if product_rows == nil {
            return nil, errors.New("No Products Named " + *name)
    }

    products := []*Product{}
    for product_rows.Next() {
            product := new(Product)
            err = product_rows.Scan(&product.Id,
                    &product.Name,
                    &product.Description,
                    &product.Price,
                    &product.Image,
                    &product.Rate)
            if err != nil {
                    panic(err)
            }
            products = append(products, product)
    }
    return products, nil
}
6个回答

48

你需要把like模式放在单引号中:

SELECT p.id, p.name, p.description, p.price, p.image, p.rate
FROM products AS p
WHERE LOWER(p.name) LIKE '%' || $1 || '%'
ORDER BY p.rate DESC;

1
现在显示为:pq:传入1个参数,但语句需要0个参数,就好像它不能识别$1。 - sescob27
3
需要使用LIKE '%' || $1 || '%'才能让占位符被识别为一个占位符吗?或者在Go中进行字符串连接并使用LIKE $1 - mu is too short
4
LIKE '%' || $1 || '%' 可以正常工作,但 '%?%' 报错:pq: 提供了 1 个参数,但语句不需要参数。 - sescob27
可以确认:WHERE name LIKE %?% 不起作用。会导致 near "%": syntax error 的错误。正确的写法是:WHERE name LIKE '%'||?||'%' - 425nesp
2
@Gordon Linoff,我曾经苦苦思索如何在golang与sqlite3中使用LIKE和%,后来看到了这篇帖子。真的给了我很大的帮助。 - Andy Song
显示剩余2条评论

0

我猜这是做这件事最正确的方法:

query := `SELECT p.id, p.name, p.description, p.price, p.image, p.rate
    FROM products AS p
    WHERE LOWER(p.name) LIKE CONCAT('%%',$1::text,'%%') ORDER BY p.rate DESC`

product_rows, err := db.Query(query, name)

if err != nil {
        return nil, err
}

-1
不要在准备查询时添加引号。只需使用引号和%符号提供值即可解决问题。已经尝试过。
解决方案: query:= SELECT p.id,p.name,p.description,p.price,p.image,p.rate         FROM products AS p         WHERE LOWER(p.name) LIKE $1 ORDER BY p.rate DESC

product_rows, err := db.Query(query, "'%" + name + "%'")

我从这个帖子中得到了我的解决方案。


刚刚发现解决方案取决于Golang的版本,因为升级到1.10后,我的解决方案停止工作了,我不得不采用“% || $1 || %”的解决方案。因此,请尝试不同的解决方案以使事情正常运行。 - Mohit
6
可能存在SQL注入攻击的漏洞。 - ranu
这段代码肯定存在 SQL 注入漏洞,请考虑修改答案。 - Yandry Pozo

-2

这对我有效

query := "SELECT ProductId,Name,Description,Price,SKU FROM Products WHERE Name LIKE ?"
rows, err := r.db.QueryContext(ctx, query, "%"+name+"%")

此代码存在 SQL 注入漏洞,请考虑编辑答案。 - Yandry Pozo

-2
query := `SELECT p.id, p.name, p.description, p.price, p.image, p.rate
    FROM products AS p
    WHERE LOWER(p.name) LIKE $1 ORDER BY p.rate DESC`

product_rows, err := db.Query(query, '%' + name+ '%'))

-3

根据此问题,您的查询语句不能包含“%”符号,但是“name”参数必须用“%”引用。

query := `SELECT p.id, p.name, p.description, p.price, p.image, p.rate
    FROM products AS p
    WHERE LOWER(p.name) LIKE $1 ORDER BY p.rate DESC`

product_rows, err := db.Query(query, fmt.Sprintf("%%%s%%", name))

1
它是不安全的,可能会发生SQL注入。 - Dariush Abbasi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接