应该插入还是更新新数据?当我尝试在表行中插入空值时,为啥会死锁?

Posted

技术标签:

【中文标题】应该插入还是更新新数据?当我尝试在表行中插入空值时,为啥会死锁?【英文标题】:Should the new data be Inserted or updated?when I try to insert a null in the table row,why it deadlocked?应该插入还是更新新数据?当我尝试在表行中插入空值时,为什么会死锁? 【发布时间】:2016-03-09 03:23:09 【问题描述】:

有一个表 user_info。

 CREATE TABLE USER_INFO 
   (USER_ID VARCHAR2(50 BYTE) PRIMARY KEY, 
    USER_NAME VARCHAR2(50 BYTE),
    USER_ROLE_TYPE VARCHAR2(50 BYTE)
   )

为了扩展 api 和 admin(其 user_role_type 为 admin),创建了一个对该表的新表引用。

 CREATE TABLE ADMIN_INFO 
   (USER_ID VARCHAR2(50 BYTE), 
    USER_PHONE VARCHAR2(50 BYTE),
    USER_EMAIL VARCHAR2(100 BYTE)
   )

新表是用外键引用USER_INFO。

ALTER TABLE ADMIN_INFO 
ADD CONSTRAINT FK_ADMIN_INFO
FOREIGN KEY (USER_ID) REFERENCES USER_INFO(USER_ID) ON DELETE CASCADE;

并且 USER_INFO 已经向 USER_INFO 插入了一些数据,并且确实存在 user_id = '123' 的行。

现在我只想更改 USER_PHONE, 所以我写了sql:

update ADMIN_INFO set
        USER_PHONE = '17096022212'
        where USER_ID = '123'

但是当我尝试从 user_id = '123' 的新表中选择行时,仍然没有。

为什么?

我确实想将新信息保存到它,它是一个edit-api,它将显示并可以保存页面中的数据,我是怎么做到的?

如果我想给它一个if-else判断,对于这两种情况和不同的sql。例如

if( the row exists) update it elseinsert

我可以在 mapper.xml 中 sql 这个吗?如果可以,我是如何编写 sql 的?

-------------------2016 年 3 月 10 日/------------------

现在我完成了一个测试好的 sql

        merge into ADMIN_INFO d
        using(select '123' as USER_ID,
              '1234567' as USER_PHONE from dual) dd
        on(d.USER_ID = dd.USER_ID)
        when matched then
            update set d.USER_PHONE = dd.USER_PHONE
        when not matched then
            insert (USER_ID,USER_PHONE)
        values(dd.USER_ID,dd.DRIVER_NUMBER)

但是,当我尝试这样测试时:

        merge into ADMIN_INFO d
        using(select '1234' as USER_ID,
              __null__ as USER_PHONE from dual) dd
        on(d.USER_ID = dd.USER_ID)
        when matched then
            update set d.USER_PHONE = dd.USER_PHONE
        when not matched then
            insert (USER_ID,USER_PHONE)
        values(dd.USER_ID,dd.DRIVER_NUMBER)

数据库显示错误,死锁,sql一直在运行,无法完成。发生了什么?

【问题讨论】:

根据我的经验,从长远来看,最方便和最可靠的数据库总是会添加数据,很少或在少数地方,更新它,并且永远不会删除它(除了归档非常旧的数据)。存储很便宜,开发人员的理智和数据完整性/可追溯性更有价值。 【参考方案1】:

UPDATE 用于更改该特定表中已经存在的行 - 因此,如果 ADMIN_INFO 表(您要更新的表)中没有具有 USER_ID 的行,则需要先插入它

【讨论】:

【参考方案2】:

你更新sql的结果是什么?在我看来,admin_info 表中没有这样的记录。如果要向表中插入新记录,则应使用 insert 而不是 update。

【讨论】:

我首先认为 USER_ID 存在是因为它引用了表 USER_INFO,但现在我知道我错了。 如果我想给它一个 if-else 判断,对于这两种情况和不同的 sql。例如如果(行存在)更新它else插入,我可以 sql 这个在 mapper.xml 中?如果可以的话,我是如何编写 sql 的? @JOLee 这是关于这个主题的一个很好的讨论。 [链接] (***.com/questions/237327/…)

以上是关于应该插入还是更新新数据?当我尝试在表行中插入空值时,为啥会死锁?的主要内容,如果未能解决你的问题,请参考以下文章

存在新值时添加新的 Google 工作表行

唯一约束失败:sqlite 数据库:android

当我尝试通过存储过程插入空值时出现 SqlException

无法添加表行,因为“当 IDENTITY_INSERT 设置为 OFF 时,无法在表 'Users' 中插入标识列的显式值”错误

如何在表行中使用引导程序 x-editable?

如何用新数据正确覆盖 SQLite 表行?