我不是SQL专家,但在iPhone应用程序中有一个错误,其中UPDATE语句对数据库没有影响。 我一直在使用FireFox的SQLlite manger插件通过在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;
答案 0 :(得分:2)
在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
如果是PRIMARY KEY列,则只变为整数主键 声明的类型名称正好是“INTEGER”。其他整数类型的名称 “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主键,上面的第三个select语句(从TEST中选择*,其中id = 7)可能返回一行,或者它可能不返回任何内容!
如果实现将INT PK视为行id的别名,那么就没有rowid = 7的行,因此它不会返回任何内容。如果实现将INT PK视为正常值,它将找到该行。
现在,如果要在表TEST中插入更多行,最终会创建一个rowid = 7的行。在其中一个任意实现中,当你使用where where子句时,其中id = 7 ---你可能认为你正在处理id = 7的元组,但你实际上是在寻找rowid = 7的元组。你会得到错误的元组,你可能没有意识到。考虑将子表连接到父表时的可能性:子表包含外键值7.内连接从父表返回什么元组?这取决于实现是否尊重INT和INTEGER主键之间的区别。
去年,我为Adobe AIR,BTW详细记录了这一点,并在SQLite新闻组上进行了报道。某些实现可能已在过渡期间改变了行为。
创建SQLite表时,最好对主键使用INTEGER [verbatim],而不是任何其他已识别的int类型。
答案 1 :(得分:0)
如果您的查询正确,那么您需要确保2件事。
你有没有写过这样的finalize_statement?
sqlite3_finalize(selectStatement);
2.如果您在模拟器中进行测试。您确定要按以下路径检查数据库更新吗?
/user/Libary/Application Support/iPhone Simulator/Your_Version_Number/Applications/YOUR_APPLICATION_GUID/Documents
希望这有帮助。
答案 2 :(得分:0)
查询中唯一让我觉得值得进一步调查的是[title]值中的问号。删除它,看看是否有任何改变。也许它在整个过程中被错误地解析为参数占位符。