If my SQL statement is only evaluated once, then why would I use sqlite3_bind()?

送分小仙女□ 提交于 2020-04-30 06:30:05

问题


For example, the first comment on the question How to properly escape single quotes in SQLite insert statement - iOS says "Don't use stringWithFormat to build your query. Do it properly with sqlite3_bind_xxx statements." I've seen (on Stack Overflow and beyond) many comments/answers like this that unconditionally suggest using parameters instead of literals.

However, I don't see any suggestions like that on the SQLite website. I do see that section "6. Binding Parameters and Reusing Prepared Statements" in "An Introduction To The SQLite C/C++ Interface" says that "SQLite allows the same prepared statement to be evaluated multiple times" by using sqlite3_bind().

So if I'm only evaluating an SQL statement once, then why would I use parameters instead of just using literals (and when necessary escaping user-inputted text or converting data to BLOB literals myself)? Am I missing something here? I understand that "reusing prepared statements" and thereby "avoiding calls to sqlite3_prepare() can give a significant performance improvement", but I'd like to keep my code as simple as possible for now and maybe enhance performance later.


回答1:


"when necessary" is the key here. Being such open-ended, this approach will inevitably lead to SQL injection. What is user-inputted text? Is a part of the interface user-inputted? Is a text you have got from a database user-inputted? Can you guarantee that anyone working with the code base will have correct answers?

The data processing for SQL should be uniform and predictable. And prepared statements offer precisely that.

Besides, "escaping" is not intended for the protection. While giving you a false feeling of security it would betray you at the first opportunity. Try to protect a field name with string escaping and see. Unlike escaping, using prepared statements guarantee the protection, when applicable.

I'd like to keep my code as simple as possible

For one, right now you've got the coding process unnecessarily complex, making yourself to ponder every time a query has be be executed, "is it necessary escaping user-inputted text or not?"

Finally, to simplify a repetitive task, there is a user defined function to the rescue. Just write a function that combines prepare/bind/execute in a single call and then use it to make your application code as simple and meaningful as possible.




回答2:


Reasons to always use sql_bind():

  • It allows you to insert more data since SQLite limits the length of an SQL statement
  • It's faster for a large string since it doesn't "need to be parsed or copied as much"
  • It's faster and uses less memory for a large BLOB since converting data to a BLOB literal takes time and hexadecimal strings take up more memory than the data they represent
  • It's advised in "Limits in SQLite" under "3. Maximum Length Of An SQL Statement"

    If an SQL statement is limited to be a million bytes in length, then obviously you will not be able to insert multi-million byte strings by embedding them as literals inside of INSERT statements. But you should not do that anyway. Use host parameters for your data. Prepare short SQL statements like this:

            INSERT INTO tab1 VALUES(?,?,?);

    Then use the sqlite3_bind_XXXX() functions to bind your large string values to the SQL statement. The use of binding obviates the need to escape quote characters in the string, reducing the risk of SQL injection attacks. It is [sic] also runs faster since the large string does not need to be parsed or copied as much.

Note: I find the reason that "the use of binding obviates the need to escape quote characters in the string" insufficient on its own because doing that is easy enough to simply do explicitly either in my app's programming language or by using one of SQLite's Formatted String Printing Functions with either the %q or %Q substitution types.



来源:https://stackoverflow.com/questions/61140036/if-my-sql-statement-is-only-evaluated-once-then-why-would-i-use-sqlite3-bind

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!