当前位置: 首页 > 面试题库 >

SQLlite3更新语句无效

敖毅
2023-03-14
问题内容

我不是SQL专家,但在iPhone应用程序中存在一个错误,其中UPDATE语句对数据库没有影响。我一直在为FireFox使用SQLlite管理器插件,通过反复修改和在db上运行UPDATE来尝试dbug。我还仔细运行了该语句,并使用SQL
Validator进行了验证,该语句符合核心SQL标准。

您能发现以下给出的陈述有什么问题吗?

UPDATE sections
SET
    title = "What is acne ? ABC",
    text = 'Pus on your face',
    created = '2010-03-10 18:46:55',
    modified = '2011-07-04 17:38:44',
    position = 1,
    condition_id = 4
WHERE id = 10;

问题答案:

SQLite以及Mozilla,Google,Adobe和其他公司的各种实现在处理其表在这些实现之外创建的数据库中的数字主键的方式上存在一些混乱和不一致,其中主键被定义为整数类型,但不是为“
INTEGER” [verbatim] -即,它们被定义为INT或INT16或INT32等。

        INTEGER PRIMARY KEY in mothership SQLite is an alias for the rowid.
        INT PRIMARY KEY in mothership SQLite is not an alias for the rowid.

财团成员(或任何实施者)可能会或可能不会遵守此规则。(当然,SQLite在公共领域。)

请参阅此处的第2.0节:http :
//www.sqlite.org/datatypes.html

并在此处查看有关RowId和主键的部分:http
:
//www.sqlite.org/lang_createtable.html#rowid

仅当声明的类型名称恰好是“ INTEGER”时,PRIMARY KEY列才成为整数主键。其他整数类型名称(例如“ INT”或“ BIGINT”或“
SHORT INTEGER”或“ UNSIGNED INTEGER”)使主键列表现为具有整数亲和力和唯一索引的普通表列, 而不是rowid的别名
。[重点添加]

不遵循规则的实现者甚至可能根本不知道自己是在违反规则,因为这是一种“陷阱”奥秘的规则。无论如何,这实际上意味着一个实现可能会将提供的值视为rowid的别名,而另一种实现可能不会。如果给定值10,则可能会检索到rowid
= 10的元组,而可能会检索到指定列的值= 10的元组。合理的结果,但它们完全是错误的。

考虑以下简单测试:使用旗舰SQLite的实用程序(而不是实现者之一提供的实用程序)执行以下DDL和DML语句;然后,在您的实现中,打开数据库并再次执行DML语句以比较DML结果:

        CREATE TABLE TEST
        ("id" INT PRIMARY KEY, "name" text)  -- ** NOTE "INT" not "INTEGER"

        INSERT INTO TEST
        (id, name)
        VALUES
        (7,'seven')


         ** *** N.B. THE ROWID OF THE ROW INSERTED ABOVE =  1  *** **


        select rowid, id, name from test

       result:  1 | 7 | seven


        select * from TEST

        result:  7 | seven


        select * from TEST where id = 7

        result:  ?????  [ymmv]



        select * from TEST where id = 1


        result: ?????  [ymmv]

根据特定实现如何处理INT主键,上面的第三条选择语句(在id = 7的TEST中选择*)可能返回一行 ,也可能什么都不返回!

如果实现将INT PK视为行ID的别名,那么将没有rowid = 7的行,因此它将不返回任何内容。如果实现将INT PK视为正常值,它将找到该行。

现在,如果您要在表TEST中插入更多行,则最终将创建一行rowid = 7的行。在上述任一种实现中,当您使用where-clause- where id
= 7
-–时,您可能会认为您正在寻址id = 7的元组,但实际上正在寻址rowid =
7的元组。您将得到错误的元组,并且您可能没有意识到。考虑将子表联接到父表时的可能性:子表包含外键值7。内部联接从父表返回什么元组?这取决于实现是否尊重INT和INTEGER主键之间的区别。

去年,我为Adobe AIR,BTW进行了详细记录,并在SQLite新闻组中进行了报道。某些实现可能已在此期间更改了行为。

创建SQLite表时,最好将INTEGER [verbatim]用作主键,而不要使用其他任何公认的int类型。



 类似资料:
  • 问题内容: 我有2个表格,Products和ShoppingCart,我想根据ShoppingCart中指定的产品名称和数量来更新和减少Products表中产品的“数量”。我怎样才能做到这一点? 表:产品字段:产品名称,产品数量 表:购物车字段:ProductName,ProductQty 访问数据库 问题答案: 您应该有一个产品ID。然而: 您还应该在字段和表名中删除空格。

  • 问题内容: 我需要使用REPLACE编写一条sql更新语句。字符串看起来像’SE * 88 * 000000001’。我需要替换两个星号“ *”之间的数字。除了要替换的数字始终在两个星号之间之外,这里没有其他模式。在这种情况下可以使用通配符吗? 感谢你的帮助。 谢谢! 问题答案: 或者,如果要替换的是一个特定的数字,那么它将更加简单:

  • 问题内容: 我有两张桌子。表A和表B。 TableA包含一个varbinary(max)列-名为[BinaryA] TableB包含一个包含每个varbinary卷的列(名为“ Volume”,类型为“ Long”)。 为了选择我查询的所有卷 比,我想用它的体积更新tableB。 然后我写 我收到比 虽然我在运行时没有收到任何NULL 问题答案: 尝试使用此查询: 假设TableB和[VAULT]

  • 我需要将priorityId设置为以下。有人能建议一个sql更新语句吗?我想我需要一个由Rid和Gid组成的组或自加入 非常感谢。

  • 问题内容: 抱歉,标题不清楚。基本上,我试图从多个表中选择某些记录,然后为返回的记录更新某个列值。 T-SQL实施 甲骨文 我尝试在Teradata中执行与在Oracle中相同的操作,但是出现以下错误: 我在网上寻找解决方案,但没有运气。 问题答案: 您是否使用Teradata尝试了以下语法:

  • 问题内容: 我有这些表和值: 我想使用表1中的值及其各自的ID更新表2中的所有值。 有没有办法通过简单的SQL查询来做到这一点? 问题答案: 运行选择以确保它是您想要的 更新 另外,请考虑使用,以便在需要时可以将其回滚,但请在满意时再进行确认。