2025年mysql中主键可以为空吗(mysql主键允许为null吗)

mysql中主键可以为空吗(mysql主键允许为null吗)在我没有想到的 SQLite 中 有什么聪明的方法可以做到这一点吗 基本上 如果记录存在 我想更新四列中的三列 如果不存在 我想使用第四列的默认 NUL 值插入记录 ID 是一个主键 因此 UPSERT 只会有一个记录 我试图避免 SELECT 的开销 以便确定是否需要显式更新或插入 有什么建议吗 我无法在 SQLite 网站上确认 TABLE CREATE 的语法 我还没有建立一个演示来测试它

大家好,我是讯享网,很高兴认识大家。



在我没有想到的SQLite中,有什么聪明的方法可以做到这一点吗?

基本上,如果记录存在,我想更新四列中的三列;如果不存在,我想使用第四列的默认(NUL)值插入记录。

ID是一个主键,因此UPSERT只会有一个记录。

(我试图避免SELECT的开销,以便确定是否需要显式更新或插入)

有什么建议吗?

我无法在SQLite网站上确认TABLE CREATE的语法。 我还没有建立一个演示来测试它,但是似乎不被支持。

如果是的话,我有三列,因此实际上看起来像:

CREATE TABLE table1(

id INTEGER PRIMARY KEY ON CONFLICT REPLACE,

Blob1 BLOB ON CONFLICT REPLACE,

Blob2 BLOB ON CONFLICT REPLACE,

Blob3 BLOB

);

但前两个Blob不会引起冲突,只有ID会发生冲突,因此我不会替换Blob1和Blob2(根据需要)

当绑定数据是一个完整的事务时,SQLite中的UPDATE意味着要更新的每个发送行都需要:Prepare / Bind / Step / Finalize语句,与INSERT不同,后者允许使用reset函数

语句对象的寿命如下所示:

使用sqlite3_prepare_v2()创建对象

使用sqlite3_bind_接口将值绑定到主机参数。

通过调用sqlite3_step()运行SQL

使用sqlite3_reset()重置该语句,然后返回到步骤2并重复。

使用sqlite3_finalize()销毁语句对象。

我猜测UPDATE与INSERT相比比较慢,但是与使用主键的SELECT相比又如何呢?


讯享网

也许我应该使用select读取第4列(Blob3),然后使用REPLACE编写一条将原始第4列与前3列的新数据混合在一起的新记录?

#1楼

扩展亚里士多德的答案,您可以从虚拟“单人”表(您自己创建的具有一行的表)中进行选择。 这样可以避免重复。

我还将该示例跨MySQL和SQLite进行了移植,并使用“ date_added”列作为仅第一次设置列的示例。

REPLACE INTO page (

id,

name,

title,

content,

author,

date_added)

SELECT

old.id,

“about”,

“About this site”,

old.content,

42,

IFNULL(old.date_added,“21/05/2013”)

FROM singleton

LEFT JOIN page AS old ON old.name = “about”;

#2楼

这是一个实际上是UPSERT(更新或INSERT)而不是INSERT或REPLACE(在许多情况下工作原理不同)的解决方案。

它是这样的:

1.尝试更新是否存在具有相同ID的记录。

2.如果更新未更改任何行( NOT EXISTS(SELECT changes() AS change FROM Contact WHERE change <> 0) ),则插入记录。

因此,要么更新现有记录,要么执行插入操作。

重要的细节是使用change()SQL函数检查update语句是否命中了任何现有记录,并且仅在未命中任何记录时才执行insert语句。

值得一提的是,changes()函数不会返回由较低级别的触发器执行的更改(请参阅http://sqlite.org/lang_corefunc.html#changes ),因此请务必考虑到这一点。

这是SQL …

测试更新:

#4楼

该答案已经更新,因此下面的评论不再适用。

2018-05-18停止新闻。

SQLite中的UPSERT支持! UPSERT语法已添加到SQLite版本3.24.0(待定)中!

UPSERT是INSERT的特殊语法补充,如果INSERT违反唯一性约束,则它会使INSERT表现为UPDATE或no-op。 UPSERT不是标准的SQL。 SQLite中的UPSERT遵循PostgreSQL建立的语法。

或者:

另一个完全不同的方法是:在我的应用程序中,当我在内存中创建行时,我将内存中的rowID设置为long.MaxValue。 (MaxValue永远不会用作ID,您的寿命将不够长。…然后,如果rowID不是该值,则它必须已经存在于数据库中,因此如果它是MaxValue,则需要进行UPDATE,然后需要插入。仅当您可以跟踪应用程序中的rowID时,此功能才有用。

#5楼

此方法重新混合了该问题答案中的其他几种方法,并结合使用了CTE(公用表表达式)。 我将介绍查询,然后解释为什么我做了我所做的事情。

如果有300名员工,我想将300名员工的姓氏更改为DAVIS。否则,我将添加一个新员工。

表名称:employees列:id,first_name,last_name

查询是:

基本上,我使用CTE来减少必须使用select语句确定默认值的次数。 由于这是CTE,因此我们只需从表中选择所需的列,而INSERT语句将使用此列。

现在,您可以通过将COALESCE函数中的空值替换为应设置的值来决定要使用的默认值。

小讯
上一篇 2025-05-31 12:44
下一篇 2025-05-04 14:55

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/187009.html