DB知识点记录
DB知識點記錄
分頁
SqlServer:ROW_NUMBER () over (ORDER BY ID) AS RN,
MySql:limit
Oracle:ROWNUM AS RN
數據表的基本結構
一個新表被創建之時,會在磁盤中分配一段以8K為單位的連續空間,當字段的值從內存寫入磁盤時,就在這空間隨機保存,當8K用完會自動分配另一個8K的空間。
這里8K稱為一個數據頁,并分配0-7的頁號,每個文件的第0頁記錄引導信息,叫文件頭;每8個數據頁(64K)的組合形成擴展區,稱為擴展。全數據頁的組成形成堆;
SQL規定行不能跨越數據頁,每行記錄最大數據量只能是8K。所以char和varchar這兩種類型容量要限制在8K以內,存儲超過8K的數據應使用text類型,text類型的字段不能直接錄入和保存,只是存儲一個指針,指向若干的8K的文本數據頁所組成的擴展區。
當一個擴展區的8個數據頁中既包含了空間頁面又包含了數據或索引頁面時,稱為混合擴展,每張表都以混合擴展開始;反之稱為一致擴展,專門保存數據及索引信息。
表被創建時,SQL在混合擴展中分配至少一個數據頁,隨著數量增長,可以在混合擴展中分配7個頁,當數據超過8個頁面時,則從一致擴展中分配數據頁面。
空間頁面專門負責數據空間的分配和管理。PFS頁面:記錄一個頁面是否已分配,還有多少可用空間等信息。GAM頁面和SGAM頁面:用來記錄空閑的擴展或含有空閑頁面的混合擴展位置。
數據頁或索引頁則專門保存數據及索引信息,使用4種類型的數據頁來管理表或索引,分別為:IAM頁、數據頁、文本/圖像頁和索引頁
頁分裂
一半的數據將保存在老頁面、另一半將存放入新頁面,且新頁面可能被分配到任何可用的頁。所以、頻繁頁分裂后果很嚴重,將使物理表產生大量數據碎片、導致直接造成I/O效率的急劇下降。
填充因子
索引的一個特性,定義所以每頁上的可用空間量。FILLFACTOR(填充因子)適應以后表數據的擴展并減少了頁拆分的可能性。填充因子是從0到100的百分比數值,設為100時表示將數據頁填滿。只有當不會對數據進行更改時才用此設置。值越小則數據頁上的空閑空間越大,這樣可以減少在索引增長過程中進行頁分裂的需要,但是需要占用更多的磁盤空間。
索引
查看索引:SHOW INDEX FROM tableName;
查看數據庫索引:select * from information_schema.STATISTICS where INDEX_NAME != 'PRIMARY' and TABLE_SCHEMA = 'bank'
刪除索引:ALTER TABLE tableName DROP INDEX ID;
添加索引:ALTER TABLE tableName ADD INDEX (ID);
索引通常是用來加快數據處理速度的最普遍采用的優化方式。數據庫的索引相當于書的目錄,可以快速找到你想要的信息。
索引的利弊:查詢執行的大部分開銷是I/O,使用索引提高性能的主要目標是避免全表掃描,因為全表掃描需要從磁盤上讀取表的每一個數據頁,如果有索引指向,則查詢只需要讀少數次的磁盤就可以了。帶索引的表需要在數據庫中占用更多的存儲空間,會增加增刪數據的命令運行時長。
SQL SERVER中有多種索引類型
按存儲結構區分:聚集索引、分聚集索引
按數據唯一性區分:唯一索引、非唯一索引
按鍵列個數區分:單列索引、多列索引
MySql所有有以下幾種
普通索引、唯一索引、全文索引、單列索引、多列索引
聚集索引
一種對磁盤上實際數據重新組織以按指定的一列或多列值排序。像我們用到的漢語字典,就是一個聚集索引,比如查張,就需要翻到后面。然后根據字母順序查找,這里用到微軟的平衡二叉樹算法。
聚集索引是給數據排序,一個表只能建立一個聚集索引,它的性能比其他索引更快。
非聚集索引
SqlServer默認情況下建立的索引是非聚集索引,不重新組織表中的數據,而是對每一行存儲索引列值并用一個指針指向數據所在的頁面。即便對數據不排序,他擁有的目錄更像是目錄,對查取數據的效率也是具有提升空間的,而不需要全表掃描。
索引設計原則
對于一張表來說索引的有無和建立什么樣的索引,要取決于where字句和Join表達式
一般來說建立索引的原則包括以下內容
- 系統一般會給逐漸字段自動建立聚集索引
- 有大量重復值且經常有范圍查詢和排序、分組的列,或者經常頻繁訪問的列,考慮建立聚集索引
- 經常做插入操作的表中建立索引,應使用填充因子來減少頁分裂,同時提高并發度降低死鎖的發生。
- 在選擇索引鍵時,應采用小數據類型的列作為鍵以使每個索引能容納盡可能多的索引建和指針
事務隔離
數據庫中的事務是數據庫并發控制的基本單位,一條或一組語句要么全部成功,對數據庫的某些數據成功修改,要么全部不成功,數據的數據還原到這些語句執行。
數據庫中事務的ACID原則
原子性(Atomicity):事務的原子性指一個事務中包含的一條語句或多條語句構成了一個完整的邏輯單元,這個邏輯單元具有不可再分的原子性。要么一起提交全部執行完成、要么一起提交全部執行失敗。
一致性(Consistency):可以理解為數據的完整性,事務的提交要確保在數據庫上的操作沒有破壞數據的完整性,比如不要違背一些約束的數據插入或修改行為。一旦破壞了數據完整性,會回滾這個事務來確保數據庫中的數據是一致的。
隔離性(Isolation):與數據庫的事務隔離級別以及鎖相關,多個用戶可以對同一數據并發訪問而又不破壞數據的正確性和完整性。但是并行事務的修改必須與其他并行事務的修改相互獨立,隔離。但是在不同的隔離級別下,事務的讀取操作可能得到的結果是不同的。
持久性(Durability):數據持久化,事務一旦對數據的操作完成并提交后,數據修改就已經完成,即使服務重啟這些數據也不會改變。如果在事務的執行過程中,系統服務崩潰或者重啟,那么事務所有的操作就會被回滾,回到事務操作之前的狀態。
常見事務
自動提交事務
SqlServer默認的一種事務模式,每條Sql語句都被看成一個事務進行處理。
顯式事務
由Begin Transaction開啟事務開始,由Commit Transaction提交事務、Rollback Transcation回滾事務結束,Save Transaction事務內部設置保存點,事務可以不全部回滾只回滾到這里
---開啟事務 begin tran --錯誤撲捉機制,看好啦,這里也有的。并且可以嵌套。 begin try --語句正確insert into lives (Eat,Play,Numb) values ('豬肉','足球',1)--Numb為int類型,出錯insert into lives (Eat,Play,Numb) values ('豬肉','足球','abc') end try begin catchselect Error_number() as ErrorNumber, --錯誤代碼Error_severity() as ErrorSeverity, --錯誤嚴重級別,級別小于10 try catch 捕獲不到Error_state() as ErrorState , --錯誤狀態碼Error_Procedure() as ErrorProcedure , --出現錯誤的存儲過程或觸發器的名稱。Error_line() as ErrorLine, --發生錯誤的行號Error_message() as ErrorMessage --錯誤的具體信息if(@@trancount>0) --全局變量@@trancount,事務開啟此值+1,他用來判斷是有開啟事務rollback tran ---由于出錯,這里回滾到開始,第一條語句也沒有插入成功。 end catch if(@@trancount>0) commit tran --如果成功Lives表中,將會有3條數據。--表本身為空表,ID ,Numb為int 類型,其它為nvarchar類型 select * from livesset xact_abort
設置xact_abort on/off,指定是否回滾當前事務,為on時如果當前sql出錯,回滾整個事務,為off時如果sql出錯回滾當前sql語句,其他語句照常運行讀寫數據庫
set xact_abort off等待5秒:waitfor delay '0:0:5'?
事務中常見的問題
SqlServer中多用戶并發的情況下,使用事務可能會遇到一些情況
臟讀(Dirty Reads):一個事務正在訪問并修改數據庫中的數據但是沒有提交,另一個事務可能讀取到這些已經做出修改但未提交的數據。可能導致的結果就是所有操作都有可能回滾,比如第一個事務對數據做出的修改可能違背了數據表的某些約束,破壞了完整性,但是恰巧第二個事務卻讀取到了這些不正確的數據造成它自身操作也發生失敗回滾。
不可重復讀取(Non-Repeatable Reads):A事務兩次讀取同一數據,B事務也讀取這同一數據,但是A事務在第二次讀取前B事務已經更新了這一數據。對于A事務來說,第一次和第二次讀取到這一數據可能就不一致了。
幻讀(Phantom Reads):與不可重復讀有點類似,都是兩次讀取,不同的是A事務第一次操作的比如說是全表的數據,此時B事務并不是只修改某一具體數據而是插入了一條新數據,然后A事務第二次讀取這全表的時候就發現比上一次多了一條數據,發生幻覺了。
更新丟失(Lost Update):兩個事務同時更新,但由于某一個事務更新失敗發生回滾操作,這樣有可能的結果就是第二個事務已更新的數據因為第一個事務發生回滾而導致數據最終沒有發生更新,因此兩個事務的更新都失敗了。
事務隔離級別
希望通過何種方式讓并發的事務隔離開來,隔離到什么程度。比如可以容忍臟讀、或者不希望并發的事務出現臟讀的情況,那么這些可以通過隔離界別的設置使得并發事務之間的隔離程度變得寬松或者很嚴峻。
隔離級別越高,讀取臟數據或者造成數據不統一不完整的機會就越少,但是在高并發的系統中性能降低就越嚴重。隔離級別越低,并發系統中性能上提升很大,但是數據本身可能不完整。
SqlServer 2012中可以通過下面的語法來設置事務的隔離級別(從低到高排列)
SET TRANSACTION ISOLATION LEVEL{ READ UNCOMMITTED| READ COMMITTED| REPEATABLE READ| SNAPSHOT| SERIALIZABLE} [ ; ]Read Uncommitted(未提交讀)
隔離級別最低,容易產生的問題就是臟讀,因為可以讀取其他事務修改了但沒有提交的數據。它的作用跟在事務中SELECT語句對象表上設置(NOLOCK)相同
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED DBCC USEROPTIONSRead Committed(已提交讀)
SqlServer的默認設置,已提交讀,可以避免臟讀,可以滿足大多數要求。事務中的語句不能讀取已由其他事務做出修改但是還未提交的數據,但是能讀取由其他事務做出修改并提交了的數據。有可能出現不可重復讀和幻讀的情況,因為當前事務中可能出現兩次讀取同一資源,但是兩次讀取的過程之間,另外一個事務可能對這一資源完成了讀取更新并提交的行為,這樣數據前后可能就不一致了。
Repeatable Read(可重復讀)
不能讀取已由其他事務修改了但是未提交的行,其他任何事務也不能修改在當前事務完成之前由當前事務讀取的數據。但是對于其他事務插入的新行數據,當事務第二次訪問表行時會檢索這一新行。因此這個隔離級別的設置解決了不可重復讀取的問題,但是避免不了幻讀。
SNAPSHOT(快照隔離)
可以解決幻讀的問題,當前事務中讀取的數據在整個事務開始到事務提交結束之間,這個數據版本是一致的。其他的事務可能對這些數據做出修改,但是對于當前事務來說它是看不到這些變化。有點類似于當前事務拿到這個數據的時候是拿到這個數據的快照,因此在這個快照上做出的操作同一事務中前后幾次操作都是基于同一數據版本。因此這個隔離界別可以解決幻讀問題。但是要注意的是,其他事務是可以在當前事務完成之前修改由當前事務讀取的數據。
默認情況下數據庫不允許設置SNAPSHOT隔離界別,直接設置會出現錯誤。
需要使用SET命令開啟這個支持
ALTER DATABASE BIWORK_SSIS SET ALLOW_SNAPSHOT_ISOLATION ONSERIALIZABLE(序列化)
性能最低,隔離界別最高最嚴格,可以幾乎上面提到的所有問題。比如不能讀取其他已由其它事務修改但是沒有提交的數據,不允許其他事務在當前事務完成修改之前修改由當前事務讀取的數據,不允許其他事務在當前事務完成修改之前插入新的行。作用于在事務內所有SELECT語句中的所有表上設置HOLDLOCK相同,并發級別比較低但又對安全性要求比較高的時候可以考慮使用。如果并發級別很高,使用這個隔離級別,性能瓶頸將非常嚴重。
數據庫鎖定
加鎖是SqlServer數據庫引擎用來同步多個用戶同時對同一個數據塊的訪問的一種機制。
當有事務操作時,數據庫引擎會要求不同類型的鎖定,當鎖定運行時,會阻止其他事務對已經鎖定的數據行、數據頁或數據表進行操作。只有在當時事務對于自己鎖定的資源不在需要時,才會釋放其鎖定的資源,供其他事務使用。
鎖的種類與范圍如下
共享鎖(S)
用于不更改或不更新數據的讀取操作,如SELECT語句。
允許并發事務在封閉式并發控制下讀取SELECT資源。
當查詢某條記錄時,SQL SERVER會嘗試取得該條記錄上存在的共享鎖。如無法獲取,就必須等待別人釋放對該記錄中某幾種與共享鎖互斥的鎖,才能在設置共享鎖之后,獲取該條記錄。
當需要查詢某條記錄時,會在該記錄上防止共享鎖,而其他人在查詢此記錄時,因為共享鎖彼此不互斥,所以可以再次放置共享鎖。如果有人要更新此記錄,因為獨占鎖與共享鎖互斥,所以無法放置獨占鎖,要等到所有讀取此記錄的人都讀取完畢,釋放了共享鎖,更新數據的人才能對該記錄設置獨占鎖,并進一步更新數據。默認的事務隔離級別下,當數據讀取完畢,SqlServer會釋放共享鎖
更新鎖(U)
用于可更新的資源中。防止當多個會話在讀取、鎖定以及隨后可能進行的資源更新時發生常見形式的死鎖
更新鎖是一種中繼鎖,當同一項資源從原來的查詢操作轉換為更新操作時,鎖定機制會從共享鎖變為更新鎖,進一步變成獨占鎖。
在可重復讀或可序列化事務中,此事務讀取數據,然后修改數據。如果兩個事務獲得資源上的共享鎖,然后試圖同時更新數據,則一個事務嘗試將鎖轉換為獨占鎖。共享模式到獨占鎖的轉換必須等待一段時間,因為一個事務的獨占鎖與其他事務的共享鎖不兼容,發生鎖等待。第二個事務試圖獲取獨占鎖以進行更新,由于兩個事務都要轉換為獨占鎖,并且每個事務都等待另一個事務釋放共享鎖,因此發生死鎖。
若避免這種死鎖問題,請使用更新鎖。一次只有一個事務可以獲得資源的更新鎖,如果事務修改資源,則更新鎖轉換為獨占鎖。
當查詢一條記錄后,將次內容更新,一定會先查找記錄,在查找的過程中會對相關的記錄放置共享鎖,等找到相應的記錄之后,會對記錄放置更新鎖,以避免發生死鎖。因為共享鎖與更新鎖并不互斥,如果兩個人同時對同一條記錄放置共享鎖,先進行更新的人,可以在別人放置共享鎖時,繼續放置更新鎖,因為更新鎖互斥,當另一個人想再放置更新鎖時,無法設置,進入停止等待狀態。
獨占鎖/排他鎖(X)
用于數據修改操作,例如INSERT、UPDATE、DELETE。確保不會同時對同一資源進行多重更新
可以防止并發事務對資源進行訪問。使用獨占鎖時時,任何其他事務都無法修改數據。僅在使用NOLOCK提示或未提交讀隔離級別時才會進行讀取操作。
對數據進行添加、修改、刪除操作時,語句在執行所需的操作之前首先執行讀取操作以獲取數據。因此需先對所在的資源放置獨占鎖,以確保以上操作未完成時不受到干擾,獨占鎖在開啟事務之后,一直保留到事務結束。
UPDATE語句可能根據與一個表的連接修改另一個表中的行,再次情況下,除了請求更新行上的獨占鎖之外,UPDATE還將請求在連接表中讀取的行上的共享鎖
意向鎖
用于建立鎖的層次結構。意向鎖包含三種類型:意向共享(IS)、意向排他(IX)、意向排他共享(SIX)
在記錄上放置共享鎖之前,需要對存放該記錄的更大范圍上設置意向鎖,以避免其他連接對該頁放置獨占鎖。
數據庫引擎使用意向鎖來保護共享鎖(S)或獨占鎖(X)放置在鎖層次結構的底層資源上。意向鎖在較低級別鎖前可以獲取它們,因此會通知將意向鎖放置在較低級別上。
意向鎖有兩種用途:
- 防止其他事務以會使較低級別的鎖無效的方式修改較高級別的資源。
- 提高數據庫引擎在較高的粒度級別檢測鎖沖突的效率
在該表的數據頁或數據行上請求共享鎖之前,在表級請求共享意向鎖,以防止另一個事務隨后在包含那一頁的表上嘗試放置獨占鎖。意向鎖可以提高性能,因為數據庫引擎僅在表級別檢查意向鎖來確定事務是否可以安全地獲取該表上的鎖。而不需要檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表
意向鎖包括意向共享(IS)、意向排他(IX)、意向排他共享(SIX)等等
意向共享 (IS)
保護針對層次結構中某些低層資源請求或獲取的共享鎖
意向獨占(IX)
保護針對層次結構中某些(而并非所有)低層資源請求或獲取的獨占鎖。 IX 是 IS 的超集,它也保護針對低層級別資源請求的共享鎖。
意向獨占共享(SIX)?
保護針對層次結構中某些(而并非所有)低層資源請求或獲取的共享鎖以及針對某些(而并非所有)低層資源請求或獲取的意向獨占鎖。 頂級資源允許使用并發 IS 鎖。 例如,獲取表上的 SIX 鎖也將獲取正在修改的頁上的意向獨占鎖以及修改的行上的獨占鎖。 雖然每個資源在一段時間內只能有一個 SIX 鎖,以防止其他事務對資源進行更新,但是其他事務可以通過獲取表級的 IS 鎖來讀取層次結構中的低層資源。
意向更新(IU)
保護針對層次結構中所有低層資源請求或獲取的更新鎖。 僅在頁資源上使用 IU 鎖。 如果進行了更新操作,IU 鎖將轉換為 IX 鎖。
共享意向更新(SIU)
S 鎖和 IU 鎖的組合,作為分別獲取這些鎖并且同時持有兩種鎖的結果。 例如,事務執行帶有 PAGLOCK 提示的查詢,然后執行更新操作。 帶有 PAGLOCK 提示的查詢將獲取 S 鎖,更新操作將獲取 IU 鎖。
更新意向排他(UIX)
U?鎖和?IX?鎖的組合,作為分別獲取這些鎖并且同時持有兩種鎖的結果。
架構鎖
在執行依賴于表架構的操作時使用。架構鎖包含兩種類型:架構修改(Sch-M)和架構穩定性(Sch-S)
數據庫引擎在表數據定義語言(DDL)操作的過程中使用架構修改鎖。保持該鎖期間,Sch-M鎖將阻止對表進行并發訪問。
數據庫引擎在編譯和執行查詢時使用架構穩定性鎖,不會阻止某些事務鎖,其中包括排他鎖。因此在編譯查詢的過程中,其他事務將繼續運行。但是無法針對表執行獲取Sch-M鎖的并發DDL操作和并發DML操作
大容量更新鎖(BU)
在向表進行大容量數據復制且制定了TABLOCK提示時使用
數據庫引擎在將數據大容量復制到表中時,指定TABLOCK提示或使用sp_tableoption選項,則是使用大容量更新鎖。大容量更新鎖允許多個線程將數據并發地大容量加載到同一表,以降低數據表的鎖定競爭,同時防止其他不進行大容量加載數據的進程訪問該表。
鍵范圍鎖
當使用可序列化事務隔離級別時保護查詢讀取的行的范圍。確保再次運行查詢時其他事務無法插入符合可序列化事務的查詢的行。
在使用可序列化事務隔離界別時,保護用戶對查詢時所讀取的數據行范圍,以確保其他事務無法插入受"鍵范圍鎖"保護的數據行。鍵范圍鎖放置在索引上,指定開始于結束的索引鍵值。這些操作會先在索引上獲取鎖定,此種鎖定可以封鎖任何嘗試插入、修改、刪除索引鍵值在"鍵范圍鎖"中的數據行。?
SQL優化
查看執行時間和CPU占用時間
set statistics time on SELECT * FROM MSTB_ACCL_ABRS_SHOP_INFO; set statistics time off消息里面就可以查看執行時間了
查看查詢對I/O的操作情況
set statistics io on SELECT * FROM MSTB_ACCL_ABRS_SHOP_INFO; set statistics io off掃描計數:索引或表掃描次數
邏輯讀取:數據緩存中讀取的頁數
物理讀取:從磁盤中讀取的頁數
預讀:查詢過程中,從磁盤放入緩存的頁數
lob邏輯讀取:從數據緩存中讀取,image,text,ntext或大型數據的頁數
lob物理讀取:從磁盤中讀取,image,text,ntext或大型數據的頁數
lob預讀:查詢過程中,從磁盤放入緩存的image,text,ntext或大型數據的頁數
如果物理讀取和預讀次數比較多,可以使用索引優化
查詢->查詢選擇->高級,勾選SET STATISTICS TIME可以不用在SQL中指定
查看執行計劃
執行右側有顯示執行計劃,會顯示此步驟執行的詳細內容。表下面都顯示一個開銷百分比
select查詢優化
保證不查詢多余的列與行。
慎用distinct關鍵字,只在查詢一個字段或者很少字段的情況下使用
慎用union關鍵字,主要功能是把各個查詢語句的結果集合并到一個結果集中返回給你。會依次執行select語句-->合并結果集-->對結果集進行排序。效率很低,應避免使用
判斷表中是否存在:select top(1) id from product
insert查詢優化
盡量使用insert into select批量插入,明顯提升效率
SqlServer表分區
一般情況下,建立數據庫時,表數據都存放在一個文件里。但是如果是分區表的話,表數據就會按照你指定的規則分放到不同的文件里,把一個大的數據文件拆分成多個小文件,還可以把這些小文件放在不同的磁盤下由多個cpu進行處理。這樣文件的大小隨著拆分而減少,還得到硬件系統的加強,自然對我們操作數據是大大有利的。
所以大數據量的數據表,對分區的需要還是必要的,因為可以提高select效率,還可以對歷史數據進行區分存檔。表分區會對數據庫產生不必要的開銷,除了性能會增加實現對象的管理費用和復雜性。
分區是要把一個表數據拆分為若干子集合,把一個數據文件拆分到多個數據文件中,然而這些文件的存放可以依托一個文件組或者多個文件組,多個文件組可以提高數據庫的訪問并發量,還可以把不同的分區配置到不同的磁盤中提高效率,創建時建議分區跟文件組個數相同。
創建文件組
alter database 數據庫名 add filegroup 文件組名
創建數據文件到文件組里面
alter database 數據庫名 add file 數據標識 to filegroup 文件組名
<數據標識> (name:文件名,fliename:物理路徑文件名,size:文件初始大小kb/mb/gb/tb,filegrowth:文件自動增量kb/mb/gb/tb/%,maxsize:文件可以增加到的最大大小kb/mb/gb/tb/unlimited)
alter database AmwayFrameworkWorkflow add file (name=N'ById1',filename=N'D:\數據庫\ById1.ndf',size=5Mb,filegrowth=5mb) to filegroup AGroup1; alter database AmwayFrameworkWorkflow add file (name=N'ById2',filename=N'D:\數據庫\ById2.ndf',size=5Mb,filegrowth=5mb) to filegroup AGroup2; alter database AmwayFrameworkWorkflow add file (name=N'ById3',filename=N'D:\數據庫\ById3.ndf',size=5Mb,filegrowth=5mb) to filegroup AGroup3; alter database AmwayFrameworkWorkflow add file (name=N'ById4',filename=N'D:\數據庫\ById4.ndf',size=5Mb,filegrowth=5mb) to filegroup AGroup4; alter database AmwayFrameworkWorkflow add file (name=N'ById5',filename=N'D:\數據庫\ById5.ndf',size=5Mb,filegrowth=5mb) to filegroup AGroup5;?
可以右鍵數據庫->屬性->文件組中查找
使用向導創建分區表?
右鍵要分區的表->存儲->創建分區->顯示向導視圖?
會讓你選擇可用分區列,如果是int類型,那么你可以指定1-100W是一個分區,100W-200W是另一個分區。
加入你選擇的是datatime,那么可以指定日期作為分區。
?
?
?
?
?
?
?
?
?
?
?
?
http://www.cnblogs.com/knowledgesea/p/3696912.html
SqlServer游標
http://www.cnblogs.com/knowledgesea/p/3699851.html
?
¥
轉載于:https://www.cnblogs.com/chenxygx/p/9294326.html
總結
- 上一篇: WPF获取某控件的位置,也就是偏移量
- 下一篇: 聊聊架构设计做些什么来谈如何成为架构师