標籤:
一.寫在前面的話
生活的路很長,還是要堅持走下去,自己選擇的生活,就該讓這樣的生活放射精彩!我不奢求現在的積累,在將來能夠收穫多少,至少在以後的日子裡回憶起來,我不曾放棄過,我堅持過,我不後悔!最近跟朋友談到成長的話題,我們似乎擺脫不了被敦促的年紀,結婚、下一代是父母對我們的期盼,不同的年齡看問題的方式或許不同,真的到了他們那個年齡,我們才能真正體會那種心情,那種期盼!我只想告訴父母們,我們會努力的!走進未來的幸福,也是我們追求的,只是在這條路上,我們需要更大的勇氣努力!你們好好保重,幸福會來的!
二.死結
在Sql中,當我們想訪問某個資源時,而此時正好對方的資源也想訪問你所持有的資源時,那麼就會出現死結。就好比兩個人互相握住對方的雙手,那麼此時兩個人都無法解脫出來,都被束縛了(死結)。我們看例子吧:
開啟兩個會話(54號、57號):
54號會話:
1 USE TSQLFundamentals2008; 2 BEGIN TRANSACTION; 3 UPDATE Production.Products 4 SET unitprice=unitprice+1 5 WHERE productid=2 6 7 --在51號會話中準備修改57會話中的資料 8 UPDATE Sales.OrderDetails 9 SET unitprice=unitprice+110 WHERE productid =2;
57號會話:
1 USE TSQLFundamentals2008; 2 BEGIN TRANSACTION; 3 4 --更新操作擷取到獨佔鎖 5 UPDATE Sales.OrderDetails 6 SET unitprice=unitprice+1 7 WHERE productid =2; 8 9 10 --在57號會話中更新54號會話資料11 UPDATE Production.Products 12 SET unitprice=unitprice+113 WHERE productid=2
此時,54號、57號會話都做了事務更新操作,那麼兩者都獨自佔有了資源。如果54號同時想更新57號的裡面的記錄了?57號也想更新54號會話的記錄?此時就會處出現死結。
我們可以看看啟動並執行結果:
通過結果我們可以看到,sql內部會對死結有一個機制,即選擇死結犧牲品,由於54號會話所做操作犧牲的代價小一些,所以被犧牲了!此時可以看到57號已做了更新操作!
三.T-SQL編程
1.定義變數
(1)常量:
1 DECLARE @s INT;2 SET @s=10;3 PRINT @s;
(2)字元類型:
1 DECLARE @str NVARCHAR;2 SET @str =‘Hello World‘;3 PRINT @str;
此時列印出來的結果為:
因為給str 聲明為nvarchar時,沒有給定長度,所以一定要注意給字元定義長度;同時還可以用select對變數賦值:
1 DECLARE @m NVARCHAR(100);2 SELECT @m=99;3 PRINT @m;
查詢顧客的數量,儲存到變數中:
2.流程式控制制
(1)if......else
例子:根據目前時間來決定幹什麼(睡覺or學習)
(2)while
例子:高斯問題
3.遊標
遊標在我們的使用中不常使用,因為遊標所帶來的開銷比較大,所以對於集合處理,能用sql解決的,就盡量不適用遊標,根據具體業務來定。
現在有這樣一個需求,我們要查詢出所有的客戶公司名稱,進而進行其他的業務處理:
有人可能會想到用變數處理,接受查詢出來的結果:
所以變數時無法獲得的,考慮用遊標怎麼獲得。
遊標的使用:
1 --1.聲明遊標,基於查詢 2 DECLARE c CURSOR 3 FOR 4 SELECT companyname 5 FROM Sales.Customers; 6 7 DECLARE @name NVARCHAR(100); 8 9 --2.在使用時候,必須開啟遊標10 OPEN c;11 12 --3.從遊標中讀取資料,每次可以讀取出來一條資料13 FETCH NEXT FROM c INTO @name;14 15 --4.注意fetch,並不一定能獲得實際的資料16 WHILE @@fetch_status=017 BEGIN18 PRINT @name;19 FETCH NEXT FROM c INTO @name;20 21 END;22 23 --5.遊標使用完成以後,一定要關閉24 CLOSE c;25 26 --6.釋放遊標27 DEALLOCATE c;
執行結果:
4.暫存資料表
(1)局部暫存資料表
建立暫存資料表,注意暫存資料表表名前需要加(#):
1 CREATE TABLE #tempdb2 (3 num INT4 )5 6 INSERT INTO #tempdb 7 ( num )8 VALUES (1),(2),(3),(4),(5)
(2)全域暫存資料表
名字前面帶##:以兩個井號 (##) 開頭的那些表名。在所有串連上都能看到全域暫存資料表。如果在建立全域暫存資料表的串連斷開前沒有顯式地除去這些表,那麼只要所有其它任務停止引用它們,這些表即被除去。當建立全域暫存資料表的串連斷開後,新的任務不能再引用它們。當前的語句一執行完,任務與表之間的關聯即被除去;因此通常情況下,只要建立全域暫存資料表的串連斷開,全域暫存資料表即被除去。
CREATE TABLE ##tempdb( name NVARCHAR(100))INSERT INTO ##tempdb ( name )VALUES (‘mm‘)
5.動態Sql
動態sql語句,用於將sql語句封裝成一條字串記錄。
首先看看靜態sql,也就是查詢的欄位確定的查詢語句即為靜態sql語句,比如查詢客戶的公司名稱
1 --靜態sql2 SELECT companyname3 FROM Sales.Customers;
動態sql:
1 DECLARE @sql NVARCHAR(100);2 SET @sql=‘SELECT custid,companyname3 FROM Sales.Customers‘;4 5 EXEC(@sql);
執行結果:
在這要提醒一點的就是Sql的注入攻擊,因為當sql語句作為執行時候,那麼使用者的輸入就是邪惡的,存在漏洞。比如:
1 DECLARE @sql NVARCHAR(100);2 SET @sql=‘SELECT custid,companyname3 FROM Sales.Customers where custid=‘;4 5 DECLARE @input NVARCHAR(100);6 SET @input =‘0; select * from Sales.Customers‘;7 SET @[email protected]+@input;8 EXEC(@sql);
執行結果:
防止此類現象發生,可以用嚴格意義的動態sql語句執行命令:sp_executesql
關於sql注入,需要仔細研究,這裡說的很淺顯,希望可以進一步學習!
希望各位大牛給出指導,不當之處虛心接受學習!謝謝!
SQLServer學習筆記系列10