做網(wǎng)站借用網(wǎng)絡(luò)圖片不違法吧北京seo的排名優(yōu)化
在使用達(dá)夢(mèng)數(shù)據(jù)庫管理工具時(shí),我們測(cè)試過程中時(shí)常需要更新表數(shù)據(jù),有時(shí)為了便捷,會(huì)直接使用管理工具修改表數(shù)據(jù)的值,但偶爾會(huì)遇到“結(jié)果集不可更新,請(qǐng)確認(rèn)查詢列是否出自同一張表,并且包含值唯一的列。”的報(bào)錯(cuò),那么這究竟是怎么回事呢。
一、問題復(fù)現(xiàn):
1.創(chuàng)建一張測(cè)試表,并插入數(shù)據(jù)
2.使用SQL查詢?cè)摫頂?shù)據(jù)
3.修改表數(shù)據(jù)
在修改表數(shù)據(jù)的過程中,出現(xiàn)了報(bào)錯(cuò)
正常情況下,點(diǎn)擊查詢結(jié)果集這里的“小鎖”圖標(biāo),即可修改數(shù)據(jù)
但這里點(diǎn)擊時(shí),彈出了報(bào)錯(cuò)窗口,報(bào)錯(cuò)信息為“結(jié)果集不可更新,請(qǐng)確認(rèn)查詢列是否出自同一張表,并且包含值唯一的列。”
二、問題分析
根據(jù)我們的操作可以確認(rèn),查詢結(jié)果集就是出自同一張表。如果查詢結(jié)果集確實(shí)不是出自同一張表(即實(shí)際并非本文中的操作方式,而是幾張表關(guān)聯(lián)查詢),那一定是不可以用這種方式更新表數(shù)據(jù)的。
所以,根據(jù)其報(bào)錯(cuò)提示,該問題主要是由于該表查詢的列不唯一,也就是說表中不存在主鍵、唯一約束、唯一索引,無法確定數(shù)據(jù)唯一性。
進(jìn)一步排查,在我們操作管理工具執(zhí)行更新操作前,打開數(shù)據(jù)庫SQL日志,看看操作管理工具,數(shù)據(jù)庫具體執(zhí)行了什么操作呢?
通過抓取管理工具操作的SQL,查詢SQL日志發(fā)現(xiàn),日志中有這樣一段SQL:
格式化該SQL,簡(jiǎn)單分析下可以得知,該條SQL語句,其實(shí)就是看查詢的結(jié)果集對(duì)應(yīng)的表上是不是有唯一索引(達(dá)夢(mèng)創(chuàng)建唯一鍵時(shí),會(huì)自動(dòng)創(chuàng)建一條由系統(tǒng)內(nèi)部維護(hù)的唯一索引),且唯一索引在哪些列上。
執(zhí)行一下該條SQL,該語句對(duì)應(yīng)的參數(shù)分別是模式名和表名,根據(jù)SQL日志中的PARAMS參數(shù)提示,確認(rèn)兩個(gè)參數(shù)實(shí)際為模式名'SYSDBA'和表名'TEST'
實(shí)際的查詢結(jié)果為空。?
那么如果在C1列上創(chuàng)建唯一索引,效果會(huì)如何呢?
創(chuàng)建唯一索引的方法有很多,可以創(chuàng)建主鍵,唯一約束,唯一索引(創(chuàng)建主鍵和唯一約束時(shí),數(shù)據(jù)庫內(nèi)部都會(huì)創(chuàng)建一個(gè)由數(shù)據(jù)庫內(nèi)部自己維護(hù)的唯一索引)。
這里創(chuàng)建主鍵試試:
ALTER TABLE "SYSDBA"."TEST" ADD PRIMARY KEY("C1");
主鍵創(chuàng)建完畢,再次執(zhí)行SQL日志中的那條查詢語句,此時(shí)已經(jīng)有結(jié)果集了,查詢結(jié)果顯示在SYSDBA模式下的TEST表中C1列上,創(chuàng)建了一個(gè)升序排列的唯一索引,索引名為INDEX33649530(該索引由數(shù)據(jù)庫系統(tǒng)自動(dòng)創(chuàng)建,內(nèi)部自己維護(hù),用戶不可主動(dòng)刪除,刪除時(shí)會(huì)報(bào)錯(cuò)“試圖刪除系統(tǒng)索引”)。當(dāng)然,如果創(chuàng)建唯一約束和唯一索引,效果是一樣的,區(qū)別在于如果創(chuàng)建的是唯一索引,這里查詢結(jié)果顯示的就是我們自定義的唯一索引名字了。
此時(shí)再去用管理工具執(zhí)行修改數(shù)據(jù)的操作,則不會(huì)再報(bào)錯(cuò),可以提交并修改成功
再次查詢,數(shù)據(jù)確認(rèn)已修改
三、注意事項(xiàng)
需要注意:
1.如果在執(zhí)行SQL查詢時(shí),查詢結(jié)果集中的列必須全部包含創(chuàng)建唯一索引時(shí)對(duì)應(yīng)的列,否則則會(huì)報(bào)錯(cuò)。
如下圖中,只有SQL1,SQL4,SQL6,SQL7可以更新表數(shù)據(jù)(即查詢結(jié)果集必須包含C1列):
而下圖中,只有SQL6,SQL7可以更新表數(shù)據(jù)(即查詢結(jié)果集必須包含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)創(chuàng)建唯一索引
CREATE UNIQUE INDEX "UIDX_TEST_C1" ON "SYSDBA"."TABLE1"("C1");