国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > SQL Server > 正文

Sql存儲過程游標循環的用法及sql如何使用cursor寫一個簡單的循環

2020-07-25 12:48:52
字體:
來源:轉載
供稿:網友

用游標,和WHILE可以遍歷您的查詢中的每一條記錄并將要求的字段傳給變量進行相應的處理

==================

DECLARE @A1 VARCHAR(10),@A2 VARCHAR(10),@A3 INTDECLARE CURSOR YOUCURNAME FOR SELECT A1,A2,A3 FROM YOUTABLENAMEOPEN YOUCURNAMEfetch next from youcurname into @a1,@a2,@a3while @@fetch_status<>-1beginupdate … set …-a3 where …

……您要執行的操作寫在這里

fetch next from youcurname into @a1,@a2,@a3endclose youcurnamedeallocate youcurname

―――――――――――――

在應用程序開發的時候,我們經常可能會遇到下面的應用,我們會通過查詢數據表的記錄集,循環每一條記錄,通過每一條的記錄集對另一張表進行數據進行操作,如插入與更新,我們現在假設有一個這樣的業務:老師為所在班級的學生選課,選的課程如有哲學、馬克思主義政治經濟學、毛澤東思想概論、鄧小平理論這些課,現在操作主要如下:

1) 先要查詢這些還沒有畢業的這些學生的名單,畢業過后的無法進行選課;
2) 在批量的選取學生的同時,還需要添加對應的某一門課程;
3) 點添加后選課結束。

數據量少可能看不出用Java程序直接多次進行數據庫操作這種辦法實現的弱點,因為它每次在操作數據庫的時候,都存在著頻繁的和數據庫的I/O直接交互,這點性能的犧牲實屬不應該,那我們就看下面的方法,通過存儲過程的游標方法來實現:建立存儲過程:

Create PROCEDURE P_InsertSubject@SubjectId intASDECLARE rs CURSOR LOCAL SCROLL FORselect studentid from student where StudentGradu = 1OPEN rsFETCH NEXT FROM rs INTO @tempStudentIDWHILE @@FETCH_STATUS = 0BEGINInsert SelSubject values (@SubjectId,@tempStudentID)FETCH NEXT FROM rs INTO @tempStudentIDENDCLOSE rsGO

使用游標對記錄集循環進行處理的時候一般操作如以下幾個步驟:

1、把記錄集傳給游標;
2、打開游標
3、開始循環
4、從游標中取值
5、檢查那一行被返回
6、處理
7、關閉循環
8、關閉游標

上面這種方法在性能上面無疑已經是提高很多了,但我們也想到,在存儲過程編寫的時候,有時候我們盡量少的避免使用游標來進行操作,所以我們還可以對上面的存儲過程進行改造,使用下面的方法來實現:

Create PROCEDURE P_InsertSubject@SubjectId intASdeclare @i int,@studentidDECLARE @tCanStudent TABLE(studentid int,FlagID TINYINT)BEGINinsert @tCanStudent select studentid,0 from student where StudentGradu = 1SET @i=1WHILE( @i>=1)BEGINSELECT @studentid=''SELECT TOP 1 @studentid = studentid FROM @tCanStudent WHERE flagID=0SET @i=@@ROWCOUNTIF @i<=0 GOTO Return_LabInsert SelSubject values (@SubjectId,@studentid)IF @@error=0UPDATE @tCanStudent SET flagID=1 WHERE studentid = @studentidReturn_Lab:ENDEndGO

我們現在再來分析以上這個存儲過程,它實現的方法是先把滿足條件的記錄集數據存放到一個表變量中,并且在這個表變量中增加一個FLAGID進行數據初始值為0的存放,然后去循環這個記錄集,每循環一次,就把對應的FLAGID的值改成1,然后再根據循環來查找滿足條件等于0的情況,可以看到,每循環一次,處理的記錄集就會少一次,然后循環的往選好課程表里面插入,直到記錄集的條數為0時停止循環,此時完成操作。

比較以上的幾種循環方法的應用,就會知道,有時候可能對于同一種功能我們實現的方法不同,而最終應用程序性能的影響的差異就會很大,第二種、第三種就大大的減少的數據庫交互I/O操作的頻繁,會節省很多時間,方法三又避免用游標又可以節省不必要的開銷。

使用SQL的Agent可以執行計劃任務,把寫好的SQL語句放在計劃任務里,可以達到奇妙的效果,如定時備份數據,定時執行特定操作等等,當涉及循環操作很多條數據時,這里就要使用游標了,當然SQL中也有循環語句,如使用While。不過while的功能只能實現一般的操作,游標的功能更為強大些,可在一個指定的一個集合內循環操作數據,實現動態操作,那就更牛了,呵呵,以下資料供存檔用。

WHILE

設置重復執行 SQL 語句或語句塊的條件。只要指定的條件為真,就重復執行語句。可以使用 BREAK 和 CONTINUE 關鍵字在循環內部控制 WHILE 循環中語句的執行。

語法

WHILE Boolean_expression  { sql_statement | statement_block }  [ BREAK ]  { sql_statement | statement_block }  [ CONTINUE ]

參數

Boolean_expression

返回 TRUE 或 FALSE 的表達式。如果布爾表達式中含有 SELECT 語句,必須用圓括號將 SELECT 語句括起來。

復制代碼 代碼如下:

{sql_statement | statement_block}

Transact-SQL 語句或用語句塊定義的語句分組。若要定義語句塊,請使用控制流關鍵字 BEGIN 和 END。

BREAK

導致從最內層的 WHILE 循環中退出。將執行出現在 END 關鍵字后面的任何語句,END 關鍵字為循環結束標記。

CONTINUE

使 WHILE 循環重新開始執行,忽略 CONTINUE 關鍵字后的任何語句。

注釋

如果嵌套了兩個或多個 WHILE 循環,內層的 BREAK 將導致退出到下一個外層循環。首先運行內層循環結束之后的所有語句,然后下一個外層循環重新開始執行。

示例

declare @i intset @i=1while @i<30begininsert into test (userid) values(@i)set @i=@i+1end

------------------------------------------------------------

while 條件begin執行操作set @i=@i+1end

A. 在嵌套的 IF...ELSE 和 WHILE 中使用 BREAK 和 CONTINUE

在下例中,如果平均價格少于 $30,WHILE 循環就將價格加倍,然后選擇最高價。如果最高價少于或等于 $50,WHILE 循環重新啟動并再次將價格加倍。該循環不斷地將價格加倍直到最高價格超過 $50,然后退出 WHILE 循環并打印一條消息。

USE pubsGOWHILE (SELECT AVG(price) FROM titles) < $30BEGIN  UPDATE titles  SET price = price * 2  SELECT MAX(price) FROM titles  IF (SELECT MAX(price) FROM titles) > $50  BREAK  ELSE  CONTINUEENDPRINT 'Too much for the market to bear'

B. 在帶有游標的過程中使用 WHILE

以下的 WHILE 結構是名為 count_all_rows 過程中的一部分。下例中,該 WHILE 結構測試用于游標的函數 @@FETCH_STATUS 的返回值。因為 @@FETCH_STATUS 可能返回

主站蜘蛛池模板: 商南县| 时尚| 海口市| 东丽区| 平湖市| 东山县| 抚顺市| 六枝特区| 延吉市| 皋兰县| 乌鲁木齐县| 措美县| 康保县| 鄂伦春自治旗| 额敏县| 麻阳| 大埔县| 津市市| 祁阳县| 灵石县| 深水埗区| 宁陵县| 新蔡县| 阳谷县| 油尖旺区| 连城县| 铜鼓县| 阳春市| 唐海县| 肥西县| 荥阳市| 汪清县| 民丰县| 临漳县| 易门县| 崇州市| 晋中市| 穆棱市| 宁都县| 灵宝市| 柘城县|