为啥我们在 SqLite 中读取内容时说 id,但在创建/更新/删除行时说 'id'?
Posted
技术标签:
【中文标题】为啥我们在 SqLite 中读取内容时说 id,但在创建/更新/删除行时说 \'id\'?【英文标题】:Why do we say id when reading something in SqLite, but 'id' when creating/updating/deleting a row?为什么我们在 SqLite 中读取内容时说 id,但在创建/更新/删除行时说 'id'? 【发布时间】:2021-08-07 05:35:03 【问题描述】:我正在创建一个笔记应用程序。用户可以输入一个注释,它会被保存到数据库/显示在屏幕上。
我有一个包含所有 CRUD 方法(创建、读取、更新、删除)的 DatabaseHelper 类。
当我更新表格中的特定注释时,我必须这样做:
db.update("Note", contentValues, "id='"+id+"'", null)
用 '' 包围用户 ID。
但是,当我查询阅读笔记时,我不必包含'':
String fetchOneNote = "SELECT * FROM Note WHERE id="+id;
这有什么具体原因吗?似乎在两者中,我指的是数据库,那么为什么我需要''?
谢谢!
【问题讨论】:
您根本不应该使用字符串连接来获取 SQL 查询(或其中的一部分)中的值,而是使用参数。 如果 id 是整数,则 ' 是不必要的,但如果它是字符串则需要。但正如已经提到的 - 不要这样做,你正在打开一个巨大的安全整体。查找参数化查询以了解如何正确执行此操作,并查找 SQL 注入以了解其问题的原因。 【参考方案1】:数字文字不需要用单引号括起来,但字符串文字需要单引号。
因此,如果 id 是数字,则无需将其括在单引号中。但是,将数字文字括在引号中并没有什么坏处。
因此假设 id 是数字然后:-
db.update("Note",contentValues,"id=" + id,null)
将有效地工作:-
db.update("Note", contentValues, "id='"+id+"'", null)
然而,SQLiteDatabase update
方法的推荐使用是使用第 4 个参数作为防止 SQLite 注入的 where 子句参数。因此最好使用:-
db.update("Note",contentValues,"id=?",new String[]id);
SQLite 解析器然后适当地处理 id,将 ? 替换为值并防止 SQLite 注入。
见https://sqlite.org/lang_expr.html#literal_values_constants_ 和https://sqlite.org/lang_expr.html#parameters
虽然关于绑定参数的解释包括:-但是因为问号容易数错,所以不鼓励使用这种参数格式。鼓励程序员使用下面的符号格式之一或上面的 ?NNN 格式。
? 是常用的。这是update method
(和其他方法)所期望的。
【讨论】:
感谢您的回复!对于这一行: db.update("Note",contentValues,"id=?",new String[]id);自从 ?不鼓励,我们应该使用参数 ?NNN 来代替,我们是否会使用 ?4 来为第四个参数保留一个位置,我们将其作为更新函数中的 id 传入?谢谢 不使用 SQLiteDataabse 方法,他们仅使用 ?不与?NNN。我很少看到 ?NNN 被使用。例如您可以使用db.Update("mytable", contentvalues,"a=? OR b=? OR c=?", new String[]"Fred","Mary","Tom")
方法替换 ? 对您来说出错的可能性很小(理论上)。
谢谢。会填吗?具有最高参数 +1(如文档中所述 - “不带数字的问号创建一个参数,其数字大于已分配的最大参数编号。”)......或者它会填充在带有我们输入的名称数组的问号中(更直观的方法)?谢谢
它将使用数组中的值,即 Fred 进入第一个?, Mary 进入第二个,Tom 进入第三个......(如果 ? 的数量不匹配参数的数量)。
知道了,谢谢。为什么文档说关于采用最高参数并为“?”增加它?范围 ?那是如果我们有整数而不是字符串吗?谢谢。以上是关于为啥我们在 SqLite 中读取内容时说 id,但在创建/更新/删除行时说 'id'?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Jenkins 在启动代理时说“服务器拒绝了 1 个私钥”?
不理解?为啥我们在“Android Sqlite”中需要 BLOB
为啥我在更新时间时说windows在与time.windows.com进行同步时出错