为啥我们在 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进行同步时出错

为啥我excel2007版 长度够长(1048576)却导出数据时说内存溢出、急!谢谢!谢谢!!

为啥将整数插入 SQLite 会爆炸?