sqlite 使用'UPDATE表格SET field =?WHERE key =?更新单个字段;`失败,返回`table.another_field可能不为NULL` [已关闭]

jhdbpxl9  于 2023-03-30  发布在  SQLite
关注(0)|答案(1)|浏览(128)

已关闭。此问题需要details or clarity。当前不接受答案。
**想要改进此问题?**添加详细信息并通过editing this post阐明问题。

2天前关闭。
Improve this question
(我正在使用SQLite编写我的第一个Perl DBI程序)
尝试更新执行预准备语句的记录中的单个字段时
UPDATE table SET field =?WHERE key =?;
我收到一个错误消息

  • table*.another_field 不能为NULL
  • another_field* 确实有NOT NULL限制,但是要更新的记录已经填充了数据。

我可以UPDATE一个只指定要使用设置的字段的记录,这是一种误解吗
设置 * 字段 * = * 值 *
当然,当只想更新一个字段时,使用SELECT读取现有记录来设置所有不需要更改的值似乎有点矫枉过正,因为它们可能不是NULL
我在Linux x86_64上使用SQLite 3.93.3和Perl 5.18.2。

详情

(本来我以为那些细节对问题并不重要,但也许它们是重要的,所以这里有一些,也回答了评论中的问题。

表定义

表的名称是KEYSfield 的名称是KEYDATAother_fieldKEK_DATA

CREATE TABLE KEYS (
ID              INTEGER PRIMARY KEY AUTOINCREMENT       NOT NULL,
NAME            VARCHAR(30)                             NOT NULL,
DK_DATA         VARCHAR(128)                            NOT NULL,
KEK_DATA        VARCHAR(128)                            NOT NULL,
KEYDATA         VARCHAR(4096)                           NOT NULL,
CREATOR         VARCHAR(20),
CREATED         DATETIME,
MODIFIED        DATETIME,
LOCKED          DATETIME);

触发器

我还定义了两个触发器(因为我是初学者,这些触发器可能不是最佳的,但你会猜到它们应该做什么:

CREATE TRIGGER KEY_CREATED AFTER INSERT ON KEYS FOR EACH ROW
BEGIN
  UPDATE KEYS SET CREATED = datetime('now') WHERE ID = new.ID;
END;
CREATE TRIGGER KEY_MODIFIED AFTER UPDATE ON KEYS FOR EACH ROW
BEGIN
  UPDATE KEYS SET MODIFIED = datetime('now') WHERE ID = new.ID;
END;

SQL语句

因此,实际上触发问题的是两个SQL语句:

  1. SELECT DK_DATA, KEK_DATA FROM KEYS WHERE NAME = ?;:我需要读取这些字段才能更新KEYDATA
  2. UPDATE KEYS SET KEYDATA = ? WHERE NAME = ?;:应该更新KEYDATA字段的语句。

样本记录

最后这里是一个导致问题的示例记录(不要浪费时间解码数据;- )):

INSERT INTO KEYS VALUES(62,'2','RVYAAQATAhFkdvSkrEyDbbTUnFHfZWEABAExAAUEMTYABAAxAAcDNTA1Nw==','RVYAAQATDWMY2Y1l1PHWU2qrobycBekABAoyABMM04kRSihvavmUHJi4OzhzugAEADEABQsxNg==','RVYAAQAEADEABAcwABMJ5RVnT9DFN0+naro0L6N7Sg==','proc','2023-03-26 00:06:24','2023-03-26 00:06:24',NULL);

注意:最后的NAME不会像2那样愚蠢,但是在开发数据模型和代码时,到目前为止还可以。

错误消息

以下是原始的DBI::errmsgKEYS.KEK_DATA may not be NULL

检查IS NULL

这是对Tim Roberts问题的回答:

sqlite> SELECT COUNT(*) FROM KEYS WHERE KEK_DATA IS NULL;
0
tnkciper

tnkciper1#

那么,这个问题是无法回答的信息提供,我可以删除它作为无效;但我会解释问题所在:

  • 问题不在SQLite中
  • 问题不在DBI中

相反,问题出在Perl代码中,特别是由于复制类似的代码并忘记正确调整而导致的问题:
而不是准备

use constant SQL_PUT_KEY        =>      # update key record
    qq{UPDATE KEYS SET KEYDATA = ? WHERE NAME = ?;};

我在准备

use constant SQL_ADD_KEY        =>      # insert key record
    qq{INSERT INTO KEYS (NAME, DK_DATA, KEK_DATA, KEYDATA, CREATOR)
VALUES (?, ?, ?, ?, ?);};

但是仍然绑定参数,就好像使用了SQL_PUT_KEY一样。因此,由于只有(前)两个参数被绑定,KEK_DATA(和其余的)实际上是NULL。因此这应该可以解释所看到的错误。
我仍然想知道Perl的DBI在执行语句时什么时候没有警告占位符没有被绑定;如果是的话,我会在这里问之前就注意到我的错误。

相关问题