亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

事物&索引&視圖

系統(tǒng) 1979 0

雖然學過SQLServer,但是在腦海里總是覺得很亂,并且有很多疑問和盲點,如今走入工作崗位,那么這些關于自己知識和技術的漏洞是不應該存在了,至少學一種語言或是技術,最起碼要知道是什么、做什么、有什么用、什么時候用、怎么用。如果連這一點都不是很清楚的話那么我不敢相信你做出來的東西有多好,有多強。以前在學習的時候,總覺得這些理論知識,自己知道就行了,不必太在意,會操作,能使用就行了,可是如今我不這么認為了,可能這些很基礎的理論知識學起來很抽象,很枯燥,但是他們真的很有用。作為一名技術人員,沒有清晰透徹的理論作為基礎,那么在技術這條道路上是走不遠,飛不高的。。。最近我在業(yè)余時間抽空復習自己所學的東西,找到一些不錯的資料,在此分享給正在學習中的朋友們,我相信這些資源對你們的學習是很有用的。好了,廢話有點多了,咱們開始吧。聲明:一下內容是我轉載的一些內容,稍作些許加工,以下有地址來源。。。

SQL教程: 事務

我們知道各種子查詢的用法,包括簡單子查詢、IN子查詢和EXISTS子查詢。除此之外,我們在實際開發(fā)中還會用到一些比較特殊的高級查詢,包括事務、索引和視圖。

例如 ,銀行轉賬問題:假定資金從賬戶A轉到賬戶B,至少需要兩步,即賬戶A的資金減少,然后賬戶B的資金相應增加。在進行資金轉賬時,系統(tǒng)必須保證:這些步驟是一個整體,如果其間任一步驟失敗,則將撤銷對這兩個賬戶數據所做的任何修改,這時就需要使用事務處理。事務是指一個工作單元,該單元可以包含多個步驟來完成所需的任務。一個事務作為一個整體,要么成功,要么失敗。

正如漢語字典中的漢字按頁存放一樣,SQL Server中的數據記錄也是按頁存放的,每頁容量一般為4KB。為了加快查找的速度,漢語字(詞)典一般都有按拼音、筆畫、偏旁部首等排序的目錄(索引),我們可以選擇按拼音或筆畫查找,快速查找到需要的字(詞)。同理, SQL Server允許用戶在表中創(chuàng)建索引,指定按某列預先排序,從而大大提高查詢速度。

同一星球,用望遠鏡從不同的角度或方位觀看,將看到星球的不同位置,從而得到不同的結果。同一張員工信息表數據,因為公司保密的原因,可能要求不同權限的人員看到不同的員工信息。例如:財務人員只能查看員工的姓名、工資、獎金等;技術部經理只能查看員工的姓名,職稱、技能等;人事部經理只能查看員工的姓名、工作經歷和發(fā)展方向等;總經理當然可以全部查看。如何更加安全、直觀地顯示數據結果呢?SQL Server中允許用戶創(chuàng)建視圖,在同一原始數據表的基礎上,為不同的用戶選擇不同的列,從而達到不同用戶的需求。

下面我們將詳細討論事務、索引和視圖的具體使用。

事務(Transaction)是單個的工作單元。如果某一事務成功,則在該事務中進行的所有數據更改均會提交,成為數據庫中的永久組成部分。如果事務遇到錯誤且必須取消或回滾,則所有數據更改均被清除。

一、為什么需要事務

一般來說,只要是同一銀行(例如都是農行),一般都支持賬戶間直接轉賬。我們來看看上述提及的轉賬問題,假定張三的賬戶直接轉賬1000元到李四的賬戶,就需要創(chuàng)建賬戶表,存放用戶的賬戶信息,T-SQL語句如 示例1

        
          /*
        
        
          --舉例:為什么需要事務--
        
        
          */
        
        
          --
        
        
          同一銀行,如都是農行的帳號,可以直接轉賬
        
        
          

/*
        
        
          ---------------建表-----------------
        
        
          */
        
        
          USE
        
        
           stuDB


        
        
          GO
        
        
          --
        
        
          創(chuàng)建農行帳戶表bank
        
        
          IF
        
        
          EXISTS
        
        (
        
          SELECT
        
        
          *
        
        
          FROM
        
         sysobjects 
        
          WHERE
        
         name
        
          =
        
        
          '
        
        
          bank
        
        
          '
        
        
          )

   
        
        
          DROP
        
        
          TABLE
        
        
           bank


        
        
          GO
        
        
          CREATE
        
        
          TABLE
        
        
           bank

(

    customerName 
        
        
          CHAR
        
        (
        
          10
        
        ), 
        
          --
        
        
          顧客姓名
        
        

    currentMoney 
        
          MONEY
        
        
          --
        
        
          當前余額
        
        
          )


        
        
          GO
        
        
          /*
        
        
          ---添加約束:根據銀行規(guī)定,帳戶余額不能少于1元,除非銷戶----
        
        
          */
        
        
          ALTER
        
        
          TABLE
        
        
           bank

  
        
        
          ADD
        
        
          CONSTRAINT
        
         CK_currentMoney 
        
          CHECK
        
        (currentMoney
        
          >=
        
        
          1
        
        
          )


        
        
          GO
        
        
          /*
        
        
          --插入測試數據:張三開戶,開戶金額為800 ;李四開戶,開戶金額1 ---
        
        
          */
        
        
          INSERT
        
        
          INTO
        
         bank(customerName,currentMoney) 
        
          VALUES
        
        (
        
          '
        
        
          張三
        
        
          '
        
        ,
        
          1000
        
        
          )


        
        
          INSERT
        
        
          INTO
        
         bank(customerName,currentMoney) 
        
          VALUES
        
        (
        
          '
        
        
          李四
        
        
          '
        
        ,
        
          1
        
        
          )


        
        
          GO
        
        
          --
        
        
          查看結果
        
        
          SELECT
        
        
          *
        
        
          FROM
        
        
           bank

 


        
        
          GO
        
        
          /*
        
        
          --轉帳測試:張三希望通過轉賬,直接匯錢給李四1000元--
        
        
          */
        
        
          --
        
        
          我們可能會這樣這樣寫代碼
        
        
          

--
        
        
          張三的帳戶少1000元,李四的帳戶多1000元
        
        
          UPDATE
        
         bank 
        
          SET
        
         currentMoney
        
          =
        
        currentMoney
        
          -
        
        
          1000
        
        
          WHERE
        
         customerName
        
          =
        
        
          '
        
        
          張三
        
        
          '
        
        
          UPDATE
        
         bank 
        
          SET
        
         currentMoney
        
          =
        
        currentMoney
        
          +
        
        
          1000
        
        
          WHERE
        
         customerName
        
          =
        
        
          '
        
        
          李四
        
        
          '
        
        
          GO
        
        
          --
        
        
          再次查看結果,結果發(fā)現了什么嚴重的錯誤?如何解決呢?
        
        
          SELECT
        
        
          *
        
        
          FROM
        
        
           bank


        
        
          GO
        
      
View Code

?上面代碼的輸出結果如圖1:

事物&索引&視圖

圖1 張三、李四的賬戶信息

注意:目前兩個賬戶的余額總和為:1000+1=1001元。

現在開始模擬實現轉賬:從張三的賬戶直接轉賬IOOO元到李四的賬戶??梢允褂肬PDATE語句修改張三的賬戶和李四的賬戶,張三的賬戶減少1OOO元,李四的賬戶增加1000元。 WANGYEXX.COM

顯然,轉賬后的余額總和應保持不變,仍為1001元。

T-SQL實現如示例2所示。

示例2:

        
          /*
        
        
          --轉賬測試:張三轉賬1000元給李四--
        
        
          */
        
        
          --
        
        
          我們可能會這樣這樣編寫語句
        
        
          

--
        
        
          張三的賬戶少1000元,李四的賬戶多1000元
        
        
          UPDATE
        
         bank 
        
          SET
        
         currentMoney
        
          =
        
        currentMoney
        
          -
        
        
          1000
        
        
          WHERE
        
         customerName
        
          =
        
        
          '
        
        
          張三
        
        
          '
        
        
          UPDATE
        
         bank 
        
          SET
        
         currentMoney
        
          =
        
        currentMoney
        
          +
        
        
          1000
        
        
          WHERE
        
         customerName
        
          =
        
        
          '
        
        
          李四
        
        
          '
        
        
          GO
        
        
          --
        
        
          再次查看轉賬后的結果。
        
        
          SELECT
        
        
          *
        
        
          FROM
        
        
           bank


        
        
          GO
        
      
View Code

?

上述語句的輸出結果如圖2所示。

輸出的結果是張三的賬戶沒有減少,還是1000元,但李四的賬戶卻多了1000元,轉賬后兩個賬戶的余額總和變?yōu)?000+1001=2001元,銀行的錢憑空多出1000元!

事物&索引&視圖

?

為什么會這樣呢?讓我們一起分析出現如此錯誤的原因。

?

查看SQL Server給出的錯誤提示,顯示UPDATE語句有錯,執(zhí)行時違反了CK_currentMoney約束,即余額不能少于1元。目前有兩條UPDATE語句,哪條語句導致了此錯誤呢?顯然是修改張三賬戶的UPDATE語句。因為張三的賬戶原有余額1000元,減少1000元后即為0元,違反了上述約束,所以終止執(zhí)行,余額保持不變,仍為1000元。遺憾的是,后面的語句并沒有中斷執(zhí)行,修改李四賬戶的UPDATE語句繼續(xù)執(zhí)行,李四的賬戶增加了1000元,變?yōu)?001元。所以兩人賬戶的余額最終出現了圖2所示的結果。

?

如何解決呢?使用事務,轉賬過程就是一個事務,它需要兩條UPDATE語句來完成,這兩條語句是一個整體。如果其中任何一條出現錯誤,則整個轉賬業(yè)務也應取消,兩個賬戶中的余額應恢復到原來的數據,從而確保轉賬前和轉賬后的余額總和不變,即都是1001元。

二、什么是事務

事務是一種機制、一個操作序列,它包含了一組數據庫操作命令,并且所有的命令作為一個整體一起向系統(tǒng)提交或撤銷操作請求,即這一組數據庫命令要么都執(zhí)行,要么都不執(zhí)行,因此事務是一個不可分割的工作邏輯單元,在數據庫系統(tǒng)上執(zhí)行并發(fā)操作時事務是作為最小的控制單元來使用的。它特別適用于多用戶同時操作的數據庫系統(tǒng)。例如,航空公司的訂票系統(tǒng)、銀行、保險公司以及證券交易系統(tǒng)等。

事務是作為單個邏輯工作單元執(zhí)行的一系列操作。一個邏輯工作單元必須有4個屬性,即原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)及持久性(Durability),這些特性通常簡稱為ACID。

(1) 原子性(Atomicity): 事務是一個完整的操作。事務的各元素是不可分的(原子的)。事務中的所有元素必須作為一個整體提交或回滾。如果事務中的任何元素失敗,則整個事務將失敗。

再次以銀行轉賬事務為例,如果該事務提交了,則這兩個賬戶的數據將會更新。如果由于某種原因,事務在成功更新這兩個賬戶之前終止,則不會更新這兩個賬戶余額,并且會撤銷對任何賬戶余額的修改。事務不能部分提交。

(2) 一致性(Consistency):當事務完成時,數據必須處于一致狀態(tài)。也就是說,在事務開始之前,數據庫中存儲的數據處于一致狀態(tài)。在正在進行的事務中,數據可能處于不一致的狀態(tài),例如,數據可能有部分修改。然而,當事務成功完成時,數據必須再次回到己知的一致狀態(tài)。通過事務對數據所做的修改不能損壞數據,或者說事務不能使數據存儲處于不穩(wěn)定的狀態(tài)。

再次以銀行轉賬事務為例。在事務開始之前,所有賬戶余額的總額處于一致狀態(tài)。在事務進行的過程中,一個賬戶余額減少,而另一個賬戶余額尚未修改。因此,所有賬戶余額的總額處于不一致狀態(tài)。事務完成以后,賬戶余額的總額再次恢復一致狀態(tài)。

(3) 隔離性(Isolation):對數據進行修改的所有并發(fā)事務是彼此隔離的,這表明事務必須是獨立的,它不應以任何方式依賴于或影響其他事務。修改數據的事務可以在另一個使用相同數據的事務開始之前訪問這些數據,或者在另一個使用相同數據的事務結束之后訪問這些數據。另外,當事務修改數據時,如果任何其他進程正在同時使用相同的數據,則直到該事務成功提交之后,對數據的修改才能生效。張三和李四之間的轉賬以及王五和趙二之間,永遠是相互獨立的。

(4) 持久性(Durability):事務完成之后,它對于系統(tǒng)的影響是永久性的。該修改即使出現系統(tǒng)故障,也將一直保持。

三、如何創(chuàng)建事務

Transact-SQL使用下列語句來管理事務。

● 開始事務:BEGIN TRANSACTION。

● 提交事務:COIVIIVIIT TRANSACTION。

● 回滾(撤銷)事務:ROLLBACK TRANSACTION。

事務的分類有以下3種。

● 顯式事務:用BEGIN TRANSACTION明確指定事務的開始。

● 隱式事務:通過設置SET IMPLICIT TRANSACTIONS ON語句,將隱式事務模式設置為打開。當以隱式事務操作時,SQL Server將在提交或回滾事務后自動啟動新事務。無法描述事務的開始,只需提交或回滾每個事務。

● 自動提交事務:這是SQL Server的默認模式,它將每條單獨的T-SQL語句視為一個事務。如果成功執(zhí)行,則自動提交。如果錯誤,則自動回滾。

實際開發(fā)中最常用的就是顯式事務,它明確地指定事務的開始邊界。

判斷T-SQL語句是否有錯,將使用到曾講過的全局變量@@ERROR,它用來判斷當前T-SQL語句執(zhí)行是否有錯誤,若有錯誤則返回非零值。下面我們應用顯式事務來解決上述轉賬問題,T-SQL語句如示例3所示。

示例3:

?

        
          USE
        
        
           stuDB


        
        
          GO
        
        
          --
        
        
          恢復原來的數據
        
        
          

--
        
        
          UPDATE bank SET currentMoney=currentMoney-1000 WHERE customerName='李四'
        
        
          SET
        
         NOCOUNT 
        
          ON
        
        
          --
        
        
          不顯示受影響的行數信息
        
        
          print
        
        
          '
        
        
          查看轉帳事務前的余額
        
        
          '
        
        
          SELECT
        
        
          *
        
        
          FROM
        
        
           bank


        
        
          GO
        
        
          /*
        
        
          --開始事務(指定事務從此處開始,后續(xù)的T-SQL語句都是一個整體--
        
        
          */
        
        
          BEGIN
        
        
          TRANSACTION
        
        
          /*
        
        
          --定義變量,用于累計事務執(zhí)行過程中的錯誤--
        
        
          */
        
        
          DECLARE
        
        
          @errorSum
        
        
          INT
        
        
          SET
        
        
          @errorSum
        
        
          =
        
        
          0
        
        
          --
        
        
          初始化為0,即無錯誤
        
        
          /*
        
        
          --轉帳:張三的帳戶少1000元,李四的帳戶多1000元
        
        
          */
        
        
          UPDATE
        
         bank 
        
          SET
        
         currentMoney
        
          =
        
        currentMoney
        
          -
        
        
          800
        
        
          WHERE
        
         customerName
        
          =
        
        
          '
        
        
          張三
        
        
          '
        
        
          SET
        
        
          @errorSum
        
        
          =
        
        
          @errorSum
        
        
          +
        
        
          @@error
        
        
          --
        
        
          累計是否有錯誤
        
        
          UPDATE
        
         bank 
        
          SET
        
         currentMoney
        
          =
        
        currentMoney
        
          +
        
        
          800
        
        
          WHERE
        
         customerName
        
          =
        
        
          '
        
        
          李四
        
        
          '
        
        
          SET
        
        
          @errorSum
        
        
          =
        
        
          @errorSum
        
        
          +
        
        
          @@error
        
        
          --
        
        
          累計是否有錯誤
        
        
          print
        
        
          '
        
        
          查看轉帳事務過程中的余額
        
        
          '
        
        
          SELECT
        
        
          *
        
        
          FROM
        
        
           bank

 


        
        
          /*
        
        
          --根據是否有錯誤,確定事務是提交還是撤銷---
        
        
          */
        
        
          IF
        
        
          @errorSum
        
        
          <>
        
        
          0
        
        
          --
        
        
          如果有錯誤
        
        
          BEGIN
        
        
          print
        
        
          '
        
        
          交易失敗,回滾事務
        
        
          '
        
        
          ROLLBACK
        
        
          TRANSACTION
        
        
          END
        
        
          ELSE
        
        
          BEGIN
        
        
          print
        
        
          '
        
        
          交易成功,提交事務,寫入硬盤,永久的保存
        
        
          '
        
        
          COMMIT
        
        
          TRANSACTION
        
        
          END
        
        
          GO
        
        
          print
        
        
          '
        
        
          查看轉帳事務后的余額
        
        
          '
        
        
          SELECT
        
        
          *
        
        
          FROM
        
        
           bank


        
        
          GO
        
      
View Code

?

事物&索引&視圖

圖3 事務處理:交易失敗的情況

示例3中,我們將轉賬金額設置為1000元,因張三的賬戶余額為0,違反了約束而有錯。如果我們修改轉賬金額為800元,則結果如圖4所示。

事物&索引&視圖

圖3 事務處理:交易成功的情況

?

說明:現實中銀行的開戶、轉賬問題比上述處理要更加復雜,如后續(xù)的項目案例所示。

轉載請注明原文地址: http://www.wangyexx.com/db/sqlbasic/1460.html

?

?

?

?

事物&索引&視圖


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 成人a视频在线观看 | 久久免费大片 | 免费一级毛片在线播放放视频 | 999久久久免费精品国产牛牛 | 国产一区二区三区四区 | 国产成人亚洲毛片 | 性网站免费 | 在线日韩国产 | 国产精品亚洲高清一区二区 | 2022国产91精品久久久久久 | 免费一级毛片不卡在线播放 | 成人三级做爰在线观看男女 | 欧美综合天天夜夜久久 | 国产精品全国探花泡良大师 | 五月久久亚洲七七综合中文网 | 男人手机天堂 | 成年黄网站免费大全毛片 | 这里只有精品视频在线 | 四虎影视在线观看 | 四虎 影院ww9584h | 一道本一区二区三区 | 日本激情啪啪 | 人色在线视频 | 一区视频在线播放 | 欧美白人猛性xxxxx交69 | 国产在线公开视频 | 中文国产欧美在线观看 | 台湾一级毛片永久免费 | 成人欧美一区二区三区黑人 | 色狠狠成人综合色 | 福利色姬网站视频入口 | 亚洲国产精品自产拍在线播放 | 国产欧美二区三区 | 久久久久久免费观看 | 日日夜夜操美女 | 中国国产高清一级毛片 | 一级免费大片 | 毛片一区 | 九九久久99 | 免费观看日本污污ww网站精选 | 久久不色|