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