Go-MySQL-Driver:具有可变查询参数的准备语句

时间:2015-05-05 03:46:04

标签: mysql rest http go

我想在Go服务器上使用带有MySQL的预处理语句,但我不确定如何使用未知数量的参数。一个端点允许用户发送一个id数组,Go将从匹配给定id的数据库中选择对象。这个数组可以包含1到20个id的任何位置,那么我将如何构造一个准备好的语句来处理它?我见过的所有示例都要求您准确了解查询参数的数量。

我能想到的唯一(非常不可能)选项是准备20个不同的SELECT语句,并使用与用户提交的id数相匹配的语句 - 但这看起来像是一个糟糕的黑客。我是否会在那时看到准备好的陈述的性能优势?

我很困惑,所以任何帮助都会受到赞赏!

1 个答案:

答案 0 :(得分:3)

没有RDBMS我知道能够绑定未知数量的参数。永远不可能将数组与未知数量的参数占位符匹配。这意味着没有智能的方法将数组绑定到查询,例如:

SELECT xxx FROM xxx WHERE xxx in (?,...,?)

这不是客户端驱动程序的限制,数据库服务器根本不支持。

有各种解决方法。

您可以使用20?创建查询,绑定您拥有的值,并通过NULL值完成绑定。它工作正常,因为涉及NULL值的比较操作的特定语义。像“field =?”这样的条件当参数绑定到NULL值时,总是将false计算为false,即使某些行匹配也是如此。假设您的数组中有5个值,则数据库服务器必须处理5个提供的值,以及15个NULL值。通常很聪明,只需忽略NULL值

另一种解决方案是准备所有查询(每个查询具有不同数量的参数)。只有最大数量的参数是有限的才有意义。它适用于准备好的语句真正重要的数据库(例如Oracle)。

就MySQL而言,使用预准备语句的好处非常有限。请记住,预备语句仅在每个会话中维护,不会在会话中共享。如果你有很多会话,他们会记忆。另一方面,使用MySQL解析语句不需要太多开销(与其他一些数据库系统相反)。通常,生成大量准备好的语句来覆盖单个查询是不值得的。

请注意,某些MySQL驱动程序提供了一个预处理语句接口,而它们并不在内部使用MySQL协议的预准备语句功能(同样,因为它通常不值得)。

还有其他一些解决方案(比如依赖临时表),但只有参数数量很大时才有意思。