SQLServer學習筆記系列10

來源:互聯網
上載者:User

標籤:

一.寫在前面的話

生活的路很長,還是要堅持走下去,自己選擇的生活,就該讓這樣的生活放射精彩!我不奢求現在的積累,在將來能夠收穫多少,至少在以後的日子裡回憶起來,我不曾放棄過,我堅持過,我不後悔!最近跟朋友談到成長的話題,我們似乎擺脫不了被敦促的年紀,結婚、下一代是父母對我們的期盼,不同的年齡看問題的方式或許不同,真的到了他們那個年齡,我們才能真正體會那種心情,那種期盼!我只想告訴父母們,我們會努力的!走進未來的幸福,也是我們追求的,只是在這條路上,我們需要更大的勇氣努力!你們好好保重,幸福會來的!

          

二.死結

在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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.