达梦管理工具报错“结果集不可更新,请确认查询列是否出自同一张表,并且包含值唯一的列。”

在使用达梦数据库管理工具时,我们测试过程中时常需要更新表数据,有时为了便捷,会直接使用管理工具修改表数据的值,但偶尔会遇到“结果集不可更新,请确认查询列是否出自同一张表,并且包含值唯一的列。”的报错,那么这究竟是怎么回事呢。

一、问题复现:

1.创建一张测试表,并插入数据

2.使用SQL查询该表数据

3.修改表数据

在修改表数据的过程中,出现了报错

正常情况下,点击查询结果集这里的“小锁”图标,即可修改数据

但这里点击时,弹出了报错窗口,报错信息为“结果集不可更新,请确认查询列是否出自同一张表,并且包含值唯一的列。

二、问题分析

根据我们的操作可以确认,查询结果集就是出自同一张表。如果查询结果集确实不是出自同一张表(即实际并非本文中的操作方式,而是几张表关联查询),那一定是不可以用这种方式更新表数据的。

所以,根据其报错提示,该问题主要是由于该表查询的列不唯一,也就是说表中不存在主键、唯一约束、唯一索引,无法确定数据唯一性。

进一步排查,在我们操作管理工具执行更新操作前,打开数据库SQL日志,看看操作管理工具,数据库具体执行了什么操作呢?

通过抓取管理工具操作的SQL,查询SQL日志发现,日志中有这样一段SQL:

格式化该SQL,简单分析下可以得知,该条SQL语句,其实就是看查询的结果集对应的表上是不是有唯一索引(达梦创建唯一键时,会自动创建一条由系统内部维护的唯一索引),且唯一索引在哪些列上。

执行一下该条SQL,该语句对应的参数分别是模式名和表名,根据SQL日志中的PARAMS参数提示,确认两个参数实际为模式名'SYSDBA'和表名'TEST'

实际的查询结果为空。 

那么如果在C1列上创建唯一索引,效果会如何呢?

创建唯一索引的方法有很多,可以创建主键,唯一约束,唯一索引(创建主键和唯一约束时,数据库内部都会创建一个由数据库内部自己维护的唯一索引)。

这里创建主键试试:

ALTER TABLE "SYSDBA"."TEST" ADD PRIMARY KEY("C1");

主键创建完毕,再次执行SQL日志中的那条查询语句,此时已经有结果集了,查询结果显示在SYSDBA模式下的TEST表中C1列上,创建了一个升序排列的唯一索引,索引名为INDEX33649530(该索引由数据库系统自动创建,内部自己维护,用户不可主动删除,删除时会报错“试图删除系统索引”)。当然,如果创建唯一约束和唯一索引,效果是一样的,区别在于如果创建的是唯一索引,这里查询结果显示的就是我们自定义的唯一索引名字了。

此时再去用管理工具执行修改数据的操作,则不会再报错,可以提交并修改成功

再次查询,数据确认已修改

三、注意事项

需要注意:

1.如果在执行SQL查询时,查询结果集中的列必须全部包含创建唯一索引时对应的列,否则则会报错。

如下图中,只有SQL1,SQL4,SQL6,SQL7可以更新表数据(即查询结果集必须包含C1列):

而下图中,只有SQL6,SQL7可以更新表数据(即查询结果集必须包含C1,C3列):

四、解决方法

解决该问题,有以下三种方法可供参考:

(1)添加主键约束

ALTER TABLE "SYSDBA"."TEST" ADD CONSTRAINT PK_TEST_C1 PRIMARY KEY("C1");
或
ALTER TABLE "SYSDBA"."TEST" ADD PRIMARY KEY("C1");

(2)添加唯一约束

ALTER TABLE "SYSDBA"."TEST" ADD CONSTRAINT "CONS_UNI_TEST_C1" UNIQUE("C1");

(3)创建唯一索引

CREATE UNIQUE INDEX "UIDX_TEST_C1" ON "SYSDBA"."TABLE1"("C1");

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 可以使用以下 SQL 语句查询一张不同分组不同: SELECT 分组, COUNT(DISTINCT 不同) FROM 名 GROUP BY 分组; 其中,分组是指需要分组的,不同是指需要统计不同。使用 COUNT(DISTINCT 不同) 可以统计不同的数量。 ### 回答2: 可以使用SQL的GROUP BY子句和HAVING子句来查询一张中不同分组的不同。具体的步骤如下: 1. 假设有一个名为table_name的,其中包含了一个名为column_name的。 2. 使用GROUP BY子句将按照column_name分组。 3. 使用HAVING子句筛选出只有一个唯一的分组。 4. 查询结果将会是所有与column_name的唯一对应的分组。 下面是一个具体的SQL查询示例: ```sql SELECT column_name FROM table_name GROUP BY column_name HAVING COUNT(*) = 1; ``` 在这个查询中,我们首先通过GROUP BY子句将按照column_name分组。然后,我们使用HAVING子句筛选出只有一个唯一的分组,即COUNT(*) = 1。最后,我们选择了column_name作为查询结果。 如果有多个不同分组的不同,这个查询将返回所有这些。如果没有满足条件的分组,查询将返回空结果。 需要注意的是,在实际的数据库中,table_name和column_name需要替换为实际的名和名。 ### 回答3: 可以使用SQL语句实现在同一张中不同分组的不同查询。以下是一个示例查询: ``` SELECT 分组, 不同 FROM 名 GROUP BY 分组, 不同; ``` 其中,分组是指将中的数据按照某一进行分组,而不同是指需要查询中的不同。 例如,假设有一个名为"学生"的包含3个:姓名、年龄、性别。我们要查询不同年龄下的不同性别。 假设中的数据如下: ``` 姓名 | 年龄 | 性别 --------------- 小明 | 20 | 男 小红 | 20 | 女 小刚 | 18 | 男 小丽 | 18 | 女 ``` 我们可以使用以下SQL语句进行查询: ``` SELECT 年龄, 性别 FROM 学生 GROUP BY 年龄, 性别; ``` 执行以上查询后,将会返回以下结果: ``` 年龄 | 性别 --------- 20 | 男 20 | 女 18 | 男 18 | 女 ``` 这样就能够查询到同一张中不同分组的不同
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

保定公民

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值