第八章 SQL修改数据库
文章目錄
- 第八章 SQL修改數(shù)據(jù)庫(kù)
- 插入數(shù)據(jù)
- 使用SQL插入數(shù)據(jù)
- 使用對(duì)象屬性插入數(shù)據(jù)
 
- UPDATE語(yǔ)句
- 在插入或更新時(shí)計(jì)算字段值
- 刪除語(yǔ)句
- 事務(wù)處理
- 事務(wù)和保存點(diǎn)
- 非事務(wù)操作
- 事務(wù)鎖
- 事務(wù)大小限制
- 讀取未提交的數(shù)據(jù)
- ObjectScript事務(wù)命令
 
第八章 SQL修改數(shù)據(jù)庫(kù)
可以對(duì)現(xiàn)有的表使用SQL語(yǔ)句,也可以對(duì)相應(yīng)的持久化類使用ObjectScript操作來(lái)修改InterSystems IRIS?數(shù)據(jù)平臺(tái)數(shù)據(jù)庫(kù)的內(nèi)容。
 不能修改定義為只讀的持久類(表)。
使用SQL命令為維護(hù)數(shù)據(jù)的完整性提供了自動(dòng)支持。
 SQL命令是一個(gè)原子操作(全部或沒(méi)有)。
 如果表上定義了索引,SQL將自動(dòng)更新它們以反映更改。
 如果定義了任何數(shù)據(jù)或引用完整性約束,SQL將自動(dòng)執(zhí)行它們。
 如果有任何已定義的觸發(fā)器,執(zhí)行這些操作將拉動(dòng)相應(yīng)的觸發(fā)器。
插入數(shù)據(jù)
可以使用SQL語(yǔ)句或設(shè)置和保存持久化類屬性將數(shù)據(jù)插入表中。
使用SQL插入數(shù)據(jù)
INSERT語(yǔ)句將一條新記錄插入SQL表中。
 可以插入一條記錄或多條記錄。
下面的示例插入一條記錄。
 它是插入單個(gè)記錄的幾種可用語(yǔ)法形式之一:
以下示例通過(guò)查詢現(xiàn)有表中的數(shù)據(jù)插入多條記錄:
INSERT INTO MyApp.Person(Name,HairColor) SELECT Name,Haircolor FROM Sample.Person WHERE Haircolor IS NOT NULL還可以發(fā)出INSERT或UPDATE語(yǔ)句。
 如果SQL表中不存在新記錄,則該語(yǔ)句將該記錄插入該SQL表中。
 如果記錄存在,則該語(yǔ)句使用提供的字段值更新記錄數(shù)據(jù)。
使用對(duì)象屬性插入數(shù)據(jù)
可以使用ObjectScript插入一條或多條數(shù)據(jù)記錄。
 創(chuàng)建一個(gè)現(xiàn)有持久化類的實(shí)例,設(shè)置一個(gè)或多個(gè)屬性值,然后使用%Save()插入數(shù)據(jù)記錄:
下面的例子插入一條記錄:
SET oref=##class(MyApp.Person).%New()SET oref.Name="Fred Rogers"SET oref.HairColor="Black"DO oref.%Save()下面的例子插入多條記錄:
SET nom=$LISTBUILD("Fred Rogers","Fred Astare","Fred Flintstone")SET hair=$LISTBUILD("Black","Light Brown","Dark Brown")FOR i=1:1:$LISTLENGTH(nom) {SET oref=##class(MyApp.Person).%New()SET oref.Name=$LIST(nom,i)SET oref.HairColor=$LIST(hair,i)SET status = oref.%Save() }UPDATE語(yǔ)句
UPDATE語(yǔ)句修改SQL表中的一條或多條現(xiàn)有記錄中的值:
UPDATE語(yǔ)句修改SQL表中的一條或多條現(xiàn)有記錄中的值:在插入或更新時(shí)計(jì)算字段值
在定義計(jì)算字段時(shí),可以指定ObjectScript代碼來(lái)計(jì)算該字段的數(shù)據(jù)值。
 可以在插入、更新行、插入和更新行或查詢行時(shí)計(jì)算此數(shù)據(jù)值。
 下表顯示了每種計(jì)算操作類型所需的關(guān)鍵字以及字段/屬性定義示例:
- 只在插入時(shí)計(jì)算 - SQL DDL COMPUTECODE關(guān)鍵字Birthday VARCHAR(50) COMPUTECODE {SET {Birthday}=$PIECE($ZDATE({DOB},9),",")_" changed: "_$ZTIMESTAMP}
- 持久化類定義SqlComputeCode和SqlComputeCode關(guān)鍵字屬性生日為%String(MAXLEN = 50) [SqlComputeCode = {SET {Birthday}=$PIECE($ZDATE({DOB},9),",") _" changed: "_$ZTIMESTAMP}, SqlComputed];
 
- 只在更新時(shí)計(jì)算 - SQL DDL DEFAULT, COMPUTECODE,和COMPUTEONCHANGE關(guān)鍵字Birthday VARCHAR(50) DEFAULT ' ' COMPUTECODE {SET {Birthday}=$PIECE($ZDATE({DOB},9),",")_" changed: "_$ZTIMESTAMP} COMPUTEONCHANGE (DOB)
 
- 在插入和更新上都進(jìn)行計(jì)算 - SQL DDL COMPUTECODE和COMPUTEONCHANGE關(guān)鍵字Birthday VARCHAR(50) COMPUTECODE {SET {Birthday}=$PIECE($ZDATE({DOB},9),",")_" changed: "_$ZTIMESTAMP} COMPUTEONCHANGE (DOB)
- 持久化類定義SqlComputeCode, SqlComputed, and SqlComputeOnChange屬性關(guān)鍵字屬性Birthday As %String(MAXLEN = 50) [SqlComputeCode = {SET {Birthday}=$PIECE($ZDATE({DOB},9),",") _" changed: "_$ZTIMESTAMP}, SqlComputed, SqlComputeOnChange = DOB];
 
- 計(jì)算對(duì)查詢 - SQL DDL COMPUTECODE和計(jì)算或瞬態(tài)關(guān)鍵字Birthday VARCHAR(50) COMPUTECODE {SET {Birthday}=$PIECE($ZDATE({DOB},9),",")_" changed: "_$ZTIMESTAMP}計(jì)算
- 持久類定義SqlComputeCode, SqlComputed, and calculate或瞬態(tài)屬性關(guān)鍵字屬性Birthday為%String(MAXLEN = 50) [SqlComputeCode = {SET {Birthday}=$PIECE($ZDATE({DOB},9),",") _" changed: "_$ZTIMESTAMP}, SqlComputed, calculate];
 
DDL DEFAULT關(guān)鍵字在插入時(shí)優(yōu)先于計(jì)算數(shù)據(jù)值。
 DEFAULT必須接受一個(gè)數(shù)據(jù)值,例如空字符串;
 不能為空。
 在持久類定義中,InitialExpression屬性關(guān)鍵字在插入時(shí)不會(huì)覆蓋SqlComputed數(shù)據(jù)值。
DDL COMPUTEONCHANGE關(guān)鍵字可以使用單個(gè)字段名,也可以使用逗號(hào)分隔的字段名列表。
 這些字段名指定了哪些字段更新時(shí)會(huì)觸發(fā)對(duì)該字段的計(jì)算;
 列出的字段名稱必須存在于表中,但它們不必出現(xiàn)在計(jì)算代碼中。
 必須指定實(shí)際的字段名;
 不能指定星號(hào)語(yǔ)法。
在修改記錄時(shí),可以使用ON UPDATE關(guān)鍵字短語(yǔ)將字段設(shè)置為文字或系統(tǒng)變量(如當(dāng)前時(shí)間戳),而不是使用COMPUTECODE和COMPUTEONCHANGE。
 ON UPDATE短語(yǔ)同時(shí)修飾INSERT和UPDATE;
 若要只在更新時(shí)修改,請(qǐng)使用默認(rèn)短語(yǔ)和更新短語(yǔ)。
每次查詢?cè)L問(wèn)該字段時(shí),DDL計(jì)算或TRANSIENT關(guān)鍵字都會(huì)計(jì)算一個(gè)數(shù)據(jù)值。
 該字段不需要在選擇列表中指定。
 例如,SELECT Name FROM MyTable WHERE LENGTH(Birthday)=36在計(jì)算條件表達(dá)式之前計(jì)算生日字段。
 管理門(mén)戶Open Table選項(xiàng)執(zhí)行一個(gè)查詢,因此計(jì)算計(jì)算的和臨時(shí)的數(shù)據(jù)值。
計(jì)算字段限制:
- 不更新的更新:為記錄中的字段提供與它們之前的值相同的值的更新實(shí)際上并不更新記錄。
 如果沒(méi)有對(duì)記錄執(zhí)行真正的更新,則不會(huì)調(diào)用COMPUTEONCHANGE。
 即使沒(méi)有對(duì)一條記錄執(zhí)行真正的更新,也會(huì)在更新操作上調(diào)用ON UPDATE。
 如果希望在更新時(shí)總是重新計(jì)算已計(jì)算字段,而不管記錄是否實(shí)際更新,請(qǐng)使用更新觸發(fā)器。
- 用戶為計(jì)算字段指定的顯式值: - INSERT:在INSERT時(shí),您總是可以向COMPUTECODE、DEFAULT或On UPDATE字段提供顯式的值。
 InterSystems SQL總是采用顯式的值,而不是生成的值。
- 更新COMPUTEONCHANGE:更新操作可以為COMPUTEONCHANGE字段提供顯式的值。
 InterSystems SQL總是采用顯式的值,而不是計(jì)算的值。
- 更新時(shí)更新:更新操作不能為ON UPDATE字段提供顯式值。
 InterSystems SQL忽略用戶提供的值,并接受ON UPDATE生成的值。
 但是,InterSystems SQL確實(shí)會(huì)對(duì)顯式值執(zhí)行字段驗(yàn)證,例如,如果提供的值大于最大數(shù)據(jù)大小,就會(huì)生成SQLCODE -104錯(cuò)誤。
- 計(jì)算或暫態(tài):插入或更新操作不能為計(jì)算或暫態(tài)字段提供顯式值,因?yàn)橛?jì)算或暫態(tài)字段不存儲(chǔ)數(shù)據(jù)。
 但是,InterSystems SQL確實(shí)會(huì)對(duì)顯式值執(zhí)行字段驗(yàn)證,例如,如果提供的值大于最大數(shù)據(jù)大小,就會(huì)生成SQLCODE -104錯(cuò)誤。
 
- INSERT:在INSERT時(shí),您總是可以向COMPUTECODE、DEFAULT或On UPDATE字段提供顯式的值。
刪除語(yǔ)句
DELETE語(yǔ)句從SQL表中刪除一條或多條現(xiàn)有記錄:
DELETE FROM MyApp.PersonWHERE HairColor = 'Aqua'可以執(zhí)行TRUNCATE TABLE命令刪除表中的所有記錄。
 還可以使用delete刪除表中的所有記錄。
 DELETE(默認(rèn)情況下)提取刪除觸發(fā)器;
 TRUNCATE TABLE不拉出刪除觸發(fā)器。
 使用DELETE刪除所有記錄不會(huì)重置表計(jì)數(shù)器;
 TRUNCATE TABLE重置這些計(jì)數(shù)器。
事務(wù)處理
事務(wù)是一系列插入、更新、刪除、插入或更新以及截?cái)啾頂?shù)據(jù)修改語(yǔ)句,它們組成單個(gè)工作單元。
SET TRANSACTION命令用于設(shè)置當(dāng)前進(jìn)程的事務(wù)參數(shù)。
 還可以使用START TRANSACTION命令設(shè)置相同的參數(shù)。
 這些事務(wù)參數(shù)在多個(gè)事務(wù)中繼續(xù)有效,直到顯式更改為止。
START TRANSACTION命令顯式地啟動(dòng)事務(wù)。
 這個(gè)命令通常是可選的;
 如果事務(wù)%COMMITMODE是隱式或顯式的,事務(wù)從第一個(gè)數(shù)據(jù)庫(kù)修改操作自動(dòng)開(kāi)始。
 如果事務(wù)%COMMITMODE為NONE,則必須顯式指定START transaction來(lái)啟動(dòng)事務(wù)處理。
如果事務(wù)成功,提交其更改可以是隱式(自動(dòng))或顯式的;
 %COMMITMODE值決定是否需要顯式地使用COMMIT語(yǔ)句來(lái)永久地將數(shù)據(jù)修改添加到數(shù)據(jù)庫(kù)并釋放資源。
如果事務(wù)失敗,可以使用ROLLBACK語(yǔ)句撤消其數(shù)據(jù)修改,這樣這些數(shù)據(jù)就不會(huì)進(jìn)入數(shù)據(jù)庫(kù)。
注意:通過(guò)管理門(mén)戶執(zhí)行SQL查詢接口運(yùn)行SQL時(shí),不支持SQL事務(wù)語(yǔ)句。
 這個(gè)接口旨在作為開(kāi)發(fā)SQL代碼的測(cè)試環(huán)境,而不是用于修改實(shí)際數(shù)據(jù)。
事務(wù)和保存點(diǎn)
在InterSystems SQL中,可以執(zhí)行兩種事務(wù)處理:完整事務(wù)處理和使用保存點(diǎn)的事務(wù)處理。通過(guò)完整的事務(wù)處理,事務(wù)將從START TRANSACTION語(yǔ)句(顯式或隱式)開(kāi)始,一直持續(xù)到COMMIT語(yǔ)句(顯式或隱式)結(jié)束事務(wù)并提交所有工作,或者ROLLBACK語(yǔ)句反轉(zhuǎn)事務(wù)期間完成的所有工作。
通過(guò)保存點(diǎn),InterSystems SQL支持事務(wù)中的級(jí)別。可以使用START TRANSACTION語(yǔ)句(顯式或隱式)開(kāi)始事務(wù)。然后,在事務(wù)期間,可以使用SAVEPOINT在程序中指定一個(gè)或多個(gè)命名保存點(diǎn)。可以在一個(gè)事務(wù)中最多指定255個(gè)命名保存點(diǎn)。添加一個(gè)保存點(diǎn)會(huì)增加$TLEVEL事務(wù)級(jí)別計(jì)數(shù)器。
- COMMIT提交事務(wù)期間執(zhí)行的所有工作。保存點(diǎn)將被忽略。
- ROLLBACK將回滾事務(wù)期間執(zhí)行的所有工作。保存點(diǎn)將被忽略。
- ROLLBACK TO SAVEPOINT點(diǎn)名將回滾自點(diǎn)名指定的SAVEPOINT以來(lái)執(zhí)行的所有工作,并以適當(dāng)數(shù)量的保存點(diǎn)級(jí)別將內(nèi)部事務(wù)級(jí)別計(jì)數(shù)器遞減。例如,如果建立了兩個(gè)保存點(diǎn)svpt1和svpt2,然后回滾到svpt1,則ROLLBACK TO SAVEPOINT svpt1會(huì)反轉(zhuǎn)自svpt1以來(lái)所做的工作,在這種情況下,將事務(wù)級(jí)別計(jì)數(shù)器減2。
非事務(wù)操作
當(dāng)事務(wù)生效時(shí),以下操作不包括在事務(wù)中,因此無(wú)法回滾:
- IDKey計(jì)數(shù)器增量不是事務(wù)操作。IDKey由$INCREMENT(或$SEQUENCE)自動(dòng)生成,它維護(hù)獨(dú)立于SQL事務(wù)的計(jì)數(shù)。例如,如果插入IDKey為17、18和19的記錄,然后回滾此插入,則下一條要插入的記錄的IDKey將為20。
- 緩存查詢的創(chuàng)建、修改和清除不是事務(wù)操作。因此,如果在事務(wù)期間清除高速緩存的查詢,然后回滾該事務(wù),則在回滾操作之后,高速緩存的查詢將保持清除狀態(tài)(不會(huì)恢復(fù))。
- 事務(wù)內(nèi)發(fā)生的DDL操作或調(diào)諧表操作可以創(chuàng)建和運(yùn)行臨時(shí)例程。此臨時(shí)例程被視為與緩存查詢相同。也就是說(shuō),臨時(shí)例程的創(chuàng)建、編譯和刪除不被視為事務(wù)的一部分。臨時(shí)例程的執(zhí)行被認(rèn)為是事務(wù)的一部分。
事務(wù)鎖
事務(wù)使用鎖來(lái)保護(hù)唯一的數(shù)據(jù)值。例如,如果進(jìn)程刪除了唯一的數(shù)據(jù)值,則該值在事務(wù)持續(xù)時(shí)間內(nèi)被鎖定。因此,在第一個(gè)事務(wù)完成之前,另一個(gè)進(jìn)程無(wú)法使用相同的唯一數(shù)據(jù)值插入記錄。這可以防止回滾導(dǎo)致具有唯一性約束的字段出現(xiàn)重復(fù)值。這些鎖由INSERT、UPDATE、INSERT或UPDATE和DELETE語(yǔ)句自動(dòng)應(yīng)用,除非該語(yǔ)句包含%NOLOCK限制參數(shù)。
事務(wù)大小限制
除了日記文件的空間可用性外,可以在事務(wù)中指定的操作數(shù)量沒(méi)有限制。鎖表的大小通常不會(huì)施加限制,因?yàn)镮nterSystems IRIS提供自動(dòng)鎖升級(jí)。
每個(gè)表有1000個(gè)鎖的默認(rèn)鎖閾值。對(duì)于當(dāng)前事務(wù),一個(gè)表可以有1000個(gè)唯一的數(shù)據(jù)值鎖。第100個(gè)鎖定操作在事務(wù)持續(xù)時(shí)間內(nèi)將該表的鎖定升級(jí)為表鎖。
此鎖定閾值可使用以下任一選項(xiàng)進(jìn)行配置:
- 調(diào)用$SYSTEM.SQL.SetLockThreshold()方法。此方法更改當(dāng)前系統(tǒng)范圍的值和配置文件設(shè)置。要確定當(dāng)前的鎖升級(jí)閾值,請(qǐng)使用$SYSTEM.SQL.GetLockThreshold()方法。
- 轉(zhuǎn)到管理門(mén)戶。從系統(tǒng)管理中,依次選擇配置、SQL和對(duì)象設(shè)置、SQL。在此屏幕上,可以查看和編輯鎖定閾值的當(dāng)前設(shè)置。
可以終止的子節(jié)點(diǎn)(子表)的數(shù)量沒(méi)有限制。所有子節(jié)點(diǎn)終止都被記錄下來(lái),因此可以回滾。
讀取未提交的數(shù)據(jù)
可以通過(guò)為發(fā)出查詢的進(jìn)程設(shè)置SET TRANSACTION或START TRANSACTION來(lái)指定讀取隔離級(jí)別。
- 提交未提交的隔離級(jí)別:對(duì)于其他用戶進(jìn)行查詢(只讀)訪問(wèn),可以看到未提交的對(duì)數(shù)據(jù)的插入,更新和刪除。如果未指定任何事務(wù),則為默認(rèn)設(shè)置。
- 已驗(yàn)證隔離級(jí)別:可供其他用戶以查詢(只讀)訪問(wèn)的方式看到未提交的對(duì)數(shù)據(jù)的插入,更新和刪除。提供對(duì)查詢條件所使用并由查詢顯示的數(shù)據(jù)的重新檢查。
- 讀取已提交的隔離級(jí)別:未提交的插入和更新對(duì)數(shù)據(jù)所做的更改未顯示在查詢結(jié)果集中。查詢結(jié)果集僅包含已提交的插入和更新。但是,未提交的刪除對(duì)數(shù)據(jù)所做的更改將顯示在查詢結(jié)果集中。
不管當(dāng)前的隔離級(jí)別如何,以下SELECT命令子句始終返回未提交的數(shù)據(jù):聚合函數(shù),DISTINCT子句,GROUP BY子句或帶有%NOLOCK關(guān)鍵字的SELECT。
ObjectScript事務(wù)命令
ObjectScript和SQL事務(wù)命令是完全兼容和可互換的,但以下情況除外:
如果沒(méi)有當(dāng)前事務(wù),則ObjectScript TSTART和SQL START TRANSACTION都將啟動(dòng)一個(gè)事務(wù)。但是,START TRANSACTION不支持嵌套事務(wù)。因此,如果需要(或可能需要)嵌套事務(wù),則最好使用TSTART啟動(dòng)事務(wù)。如果需要與SQL標(biāo)準(zhǔn)兼容,請(qǐng)使用START TRANSACTION。
ObjectScript事務(wù)處理為嵌套事務(wù)提供了有限的支持。 SQL事務(wù)處理為事務(wù)中的保存點(diǎn)提供支持。
總結(jié)
以上是生活随笔為你收集整理的第八章 SQL修改数据库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 送给女朋友的java程序_逗女朋友开心的
- 下一篇: 事务处理:概念与技术
