標籤:scene 資料 .com get server name 語句 -o image
遊標cursor,我想大多數人都在sql server裡面用過。當一個表資料量不太大的時候,遊標還是可以用的,畢竟遊標是迴圈一個表中每一行資料的最簡便辦法。但是如果你用一個遊標去迴圈一個沒有主鍵或唯一鍵的表會發生什麼呢?
我們來看看這個例子,我們聲明了一個暫存資料表#Foo並插入了一行資料,這個表沒有主鍵,然後我們使用了一個名叫ID的遊標去更新這個表[Name]列的資料,執行下面的語句看看會發生什嗎?
CREATE TABLE #Foo( [ID] [smallint] IDENTITY(1,1), [Code] [char](3) NULL, [Name] [varchar](50) NULL, [ProvinceID] [tinyint] NULL)goInsert #Foo(Code, Name, ProvinceID)Select ‘A‘, ‘New York‘, 3;Declare ID Cursor For Select top 5 ID From #Foo Order by ID Open ID;Fetch From ID ;Update #Foo Set Name+=‘1‘ Where Current OF IDClose ID ;Deallocate ID Select * From #FoogoDrop Table #Foo
執行結果如下:
你會發現sql server報錯了,提示你聲明的遊標ID是一個READ_ONLY的唯讀遊標。READ_ONLY遊標意味著聲明的遊標只能讀取資料,遊標不能做任何更新操作,而我們上面的語句使用了遊標ID來更新表#Foo的資料,所以報錯了。
現在我們把上面的語句改成下面的,主要就是在聲明表#Foo的時候將列[ID]聲明為了主鍵,再執行下面的語句:
CREATE TABLE #Foo( [ID] [smallint] IDENTITY(1,1), [Code] [char](3) NULL, [Name] [varchar](50) NULL, [ProvinceID] [tinyint] NULL CONSTRAINT [PK_Foo] PRIMARY KEY CLUSTERED ( [ID] ASC))goInsert #Foo(Code, Name, ProvinceID)Select ‘A‘, ‘New York‘, 3;Declare ID Cursor For Select top 5 ID From #Foo Order by ID Open ID;Fetch From ID ;Update #Foo Set Name+=‘1‘ Where Current OF IDClose ID ;Deallocate ID Select * From #FoogoDrop Table #Foo
執行結果如下:
這一次遊標ID沒有報錯了,語句順利執行。
為什麼將遊標用於不帶主鍵或唯一鍵的表後,遊標會變為READ_ONLY的?
If your table does not have a unique index (or a primary key constraint or unique key constraint, both of which create a unique index behind the scenes), then you dynamic cursor is converted to a static cursor. And all static cursors must be read only.
If one of the tables referenced by the CURSOR has no unique index, the CURSOR will be converted to STATIC. And STATIC cursors are READ-ONLY. See Using Implicit Cursor Conversions for more information.
所以使用遊標的時候最好都給表加上主鍵或唯一鍵,這樣使用遊標更新資料的時候就不會報錯了。
Sql Server中的遊標最好只能用於有主鍵或唯一鍵的表