直接按名称绑定 SQLite 参数
我最近 - 就在最近 - 开始学习如何为 iOS 编程,并且对(对我来说)SQLite3 中的公然疏忽感到困惑。让我限定一下,在上周之前,我对 Mac、Objective C、Xcode、iOS 或 SQLite 的(实践)经验为零,因此我不会妄想进入经过验证的工具领域并发现明显的错误在我第一次尝试时。我想有一个很好的解释。
然而,在过去几个月使用 SQL Server、MySQL 和 PostgreSQL 后,我惊讶地发现 SQLite 没有更好的按名称添加参数的功能。我在网上能找到的所有内容(文档、论坛[包括SO])都说要使用整数索引分配参数,如果您修改查询,维护起来似乎会很痛苦。即使您可以在语句中命名参数并执行类似的操作,但
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, "@my_param"), myInt);
似乎也没有人这样做。事实上,似乎根本没有人尝试将这一过程自动化。我能找到的唯一替代方法使用了参数数组和循环计数器,并检查每个参数以确定要插入的对象类型。我最初考虑过类似的方法,但是a)我老板的立场是数据库参数应该始终进行类型检查(我同意,尽管我意识到SQLite字段不是强类型的并且我在技术上无论如何都可以做到),b)它感觉像是一种不优雅的黑客行为,并且 c) 我认为这种方法没有被广泛使用是有原因的。那么:
1)为什么 SQLite 中没有接受参数名称(例如“const char”)的绑定方法?还是有而我遗漏了一些东西?
2)为什么似乎没有人使用像上面例子这样的方法?
我深入研究了源代码,认为我可以轻松地修改库,或者只编写自己的(类型化)类方法来为我执行上述操作,但我假设没有人将其构建到 SQLite 中是有原因的。我唯一的猜测是,查找参数索引所需的额外内存和周期在 [此处插入 iDevice] 上太宝贵了,并且不值得能够使用参数名称带来的便利。 。 。 ?
任何见解将不胜感激。
I recently - very recently - started learning how to program for iOS, and have been stumped by what appears (to me) to be a blatant oversight in SQLite3. Let me qualify that by saying that prior to last week I had zero (practical) experience with Macs, Objective C, Xcode, iOS or SQLite, so I have no delusions about waltzing into field of tried-and-true tools and finding obvious errors on my first try. I assume there's a good explanation.
However, after spending the last few months using SQL Server, MySQL, and PostgreSQL, I was amazed to discover that SQLite doesn't have better functionality for adding parameters by name. Everything I could find online (documentation, forums [including SO]) says to assign parameters using their integer index, which seems like it would be a pain to maintain if you ever modify your queries. Even though you can name the parameters in your statements and do something like
sqlite3_bind_int(stmt, sqlite3_bind_parameter_index(stmt, "@my_param"), myInt);
no one seems to do that either. In fact, no one seems to try to automate this at all; the only alternate approach I could find used a parameter array and a loop counter, and inspected each parameter to determine which object type to insert. I originally considered a similar approach, but a) my boss's stance is that database parameters should always be type checked (and I agree, although I realize that SQLite fields aren't strongly typed and I technically could do it anyways), b) it felt like an inelegant hack, and c) I assumed there was a reason this approach wasn't widely used. So:
1) Why aren't there binding methods in SQLite that accept a parameter name (as, say, a 'const char')? Or are there and I'm missing something?
2) Why doesn't anyone seem to use an approach like the example above?
I dug in the source code a little and think I could easily modify the library or just write my own (typed) class methods that would do the above for me, but I'm assuming there's a reason no one has built this into SQLite yet. My only guess is that the additional memory and cycles needed to find the parameter index are too precious on an [insert iDevice here], and aren't worth the convenience of being able to use parameter names . . . ?
Any insight would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有;这是您提到的
sqlite3_bind_parameter_index()
函数参数名称放入索引中,然后您可以将其与sqlite3_bind_*()
函数。但是,没有 sqlite3_bind_*_by_name() 函数或类似的东西。这是为了帮助防止 API 膨胀。如果您有兴趣,流行的 Flying Meat Database sqlite 包装器 在其分支之一中支持命名参数看看它是如何使用的。如果您考虑如何实现完整的命名参数绑定方法,请考虑当前的
bind
函数列表:如果我们想添加对命名参数的显式支持,该列表的长度将加倍以包括:
两倍的函数意味着需要花费更多的时间来维护 API、确保向后兼容性等。但是,通过简单地引入
sqlite3_bind_parameter_index()
,他们就能够添加对命名的完整支持仅具有单个函数的参数。这意味着,如果他们决定支持新的绑定类型(也许sqlite3_bind_int128
?),他们只需添加一个函数,而不是两个。至于为什么似乎没有人使用它......我无法通过进行调查给出任何明确的答案。我的猜测是,按顺序引用参数会更自然一些,在这种情况下,命名参数就没那么有用了。命名参数似乎仅在您需要无序引用参数时才有用。
There are; it's the
sqlite3_bind_parameter_index()
function you mentioned that you use to turn a parameter name into an index, which you can then use with thesqlite3_bind_*()
functions. However, there's nosqlite3_bind_*_by_name()
function or anything like that. This is to help prevent API bloat. The popular Flying Meat Database sqlite wrapper has support for named parameters in one of its branches, if you're interested in seeing how it's used.If you think about what it would take to implement full named parameter binding methods, consider the current list of
bind
functions:If we wanted to add explicit support for named parameters, that list would double in length to include:
Twice as many functions means a lot more time spent maintaining API, ensuring backwards-compatibility, etc etc. However, by simply introducing the
sqlite3_bind_parameter_index()
, they were able to add complete support for named parameters with only a single function. This means that if they ever decide to support new bind types (maybesqlite3_bind_int128
?), they only have to add a single function, and not two.As for why no one seems to use it... I can't give any sort of definitive answer with conducting a survey. My guess would be that it's a bit more natural to refer to parameters sequentially, in which case named parameters aren't that useful. Named parameters only seem to be useful if you need to refer to parameters out of order.