回答
嘗試從不循環,處理數據集。
您可以一次插入,更新,刪除多行。在這裏一個例子插入多行:
INSERT INTO YourTable
(col1, col2, col3, col4)
SELECT
cola, colb+Colz, colc, @X
FROM ....
LEFT OUTER JOIN ...
WHERE...
你甚至可以插入在單個語句中多個表:
INSERT INTO YourTable
(col1, col2, col3, col4)
OUTPUT INSERTED.PK, Inserted.Col2
INTO OtherTable (ColA, ColB)
SELECT
cola, colb+Colz, colc, @X
FROM ....
LEFT OUTER JOIN ...
WHERE...
當在循環找看看它裏面完成的。如果只是插入/刪除/更新,請重新編寫以使用單個命令。如果有IF,請查看它們是否可以是CASE語句或WHERE條件插入/刪除/更新。如果是這樣,請刪除循環並使用set命令。
我採取了循環,並用基於集合的命令替換它們,並將執行時間從幾分鐘減少到幾秒鐘。我已經採用了許多嵌套循環和過程調用的過程,並保留了循環(不可能只使用插入/刪除/更新),但我刪除了光標,並且看到鎖定/阻塞較少,並且性能大幅提升。這裏有兩個循環的方法是優於光標循環...
,如果你有循環,在一組做這樣的事情:
--this looks up each row for every iteration
DECLARE @msg VARCHAR(250)
DECLARE @hostname sysname
--first select of currsor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
WHILE @hostname is not null
BEGIN
--just some example of some odd task that requires a loop
set @msg='exec master.dbo.xp_cmdshell "net send '
+ RTRIM(@hostname) + ' '
+ 'testing "'
print @msg
--EXEC (@msg) --<<will not actually send the messages
--next select of cursor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
and hostname > @hostname
END
,如果你有一個合理的組項目(不十萬)循環你可以這樣做:
--this will capture each Key to loop over
DECLARE @msg VARCHAR(250)
DECLARE @From int
DECLARE @To int
CREATE TABLE #Rows --use a table @variable depending on the number of rows to handle
(
RowID int not null primary key identity(1,1)
,hostname varchar(100)
)
INSERT INTO #Rows
SELECT DISTINCT hostname
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
SELECT @From=0,@[email protected]@ROWCOUNT
WHILE @From<@To
BEGIN
SET @[email protected]+1
--just some example of some odd task that requires a loop
SELECT @msg='exec master.dbo.xp_cmdshell "net send '
+ RTRIM(hostname) + ' '
+ 'testing "'
FROM #Rows
WHERE [email protected]
print @msg
--EXEC (@msg) --<<will not actually send the messages
END
非常感謝。 – sreekanth 2010-10-04 04:32:46
UPDATE otherTable...
WHERE table2.EmpID IN (SELECT EMP.EmpID FROM EMP WHERE ...)
如果您發佈的是代碼或XML,**請**在文本編輯器中突出顯示這些行,然後單擊編輯器工具欄上的「代碼」按鈕(101 010)以更好地格式化和語法突出顯示它! – 2010-10-01 11:22:22
非常感謝。 – sreekanth 2010-10-04 04:32:37
一般情況下,應避免在SQL程序代碼,但如果你真的需要,使用CURSOR:
DECLARE myCursor CURSOR FAST_FORWARD
FOR
SELECT --your SQL query, a regular SQL query.
field1,
field2
FROM
table
OPEN myCursor;
FETCH NEXT FROM myCursor
INTO
@var1, --must be pre-declared, of the same types as field1
@var2
WHILE (@@FETCH_STATUS = 0)
BEGIN
--your code use @var1, @var2. Perform queries, do whatever you like.
--It will loop through every row fetched by the query in the beginning of the code, and perform this.
FETCH NEXT FROM myCursor --do this exactly as before the WHILE loop
INTO
@var1,
@var2
END
CLOSE myCursor
非常感謝您的回覆。其實我正在寫程序,我沒有實現遊標。 – sreekanth 2010-10-01 11:42:02
通過「procedural」我指的是迭代,代碼提供步驟,將任務分解成最小的部分和定義指令序列。與之相反的是聲明性語法,即SQL(還有更多),您可以在其中聲明所需內容,而無需提供有關如何實現它的具體說明。 – AlexanderMP 2010-10-01 11:49:56
非常感謝。 – sreekanth 2010-10-04 04:32:39
使用一組爲基礎的方法SQL邏輯始終是首選的方法。從這個意義上講,丹丹的答案是可以接受的。 或者你可以使用SQL遊標。雖然資源很重,但它們將允許您遍歷一組並在每行上應用一些邏輯。
DECLARE @EMPID char(11)
DECLARE c1 CURSOR READ_ONLY
FOR
SELECT EmpID
FROM EMP
其中* some_clause *
OPEN c1
FETCH NEXT FROM c1
INTO @EMPID
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @EMPID
FETCH NEXT FROM c1
INTO @EMPID
END
CLOSE c1
DEALLOCATE c1
非常感謝。 – sreekanth 2010-10-04 04:32:44
從DanDan's Answer繼,T-SQL允許你做一個UPDATE
語句的FROM
子句中加入(我不記得,如果這是ANSI或不)。 EG
UPDATE
OtherTable
SET
Auditing = Employees.EmployeeName
FROM
OtherTable
INNER JOIN
Employees ON OtherTable.EmpId = Employees.EmpId
WHERE
Employees.DateStarted > '2010-09-01'
非常感謝。 – sreekanth 2010-10-04 04:32:34
- 1. 功能在SQL Server 2008
- 2. SQL Server 2008中仿效限制功能
- 3. SQL Server 2008的旋轉功能
- 4. SQL Server 2008中的鏡像
- 5. SQL Server 2008 FILESTREAM功能與VLDB
- 6. SQL Server 2008中的數組變量
- 7. SQL Server 2008 R2中過時的T-SQL編程功能
- 8. 不能在SQL Server 2008中
- 9. Sql Server 2008性能
- 10. 在SQL Server 2008中存儲數組
- 11. SQL Server 2008中的參數
- 12. SQL Server 2008 R2的性能
- 13. 的SQL Server 2008 FILESTREAM性能
- 14. SQL Server的功能
- 15. SQL Server計數功能
- 16. 不能從SQL Server 2008中調用RICHTEXT.RichtextCtrl(在Windows 2008 Server x64)的
- 17. 哪些是2005年添加到SQL Server 2008中的新功能?
- 18. SQL Server 2008像查詢
- 19. SQL Server 2008中
- 20. SQL Server 2008數據庫鏡像瘋狂
- 21. SQL Server 2008中的文件組問題
- 22. SQL Server 2008性能問題
- 23. 不能在SQL Server 2008 R2
- 24. IIS6不能與SQL Server 2008
- 25. SQL Server 2008大表性能
- 26. sql server 2008 LIKE性能
- 27. 是否可以鏡像SQL Server 2008和SQL Server 2008R2數據庫?
- 28. SQL Server PIVOT功能
- 29. 在SQL Server功能
- 30. 功能在SQL Server
你能解釋「一些操作」? – Andomar 2010-10-01 11:18:29
每個答案旁邊有2個箭頭。如果你喜歡答案,如果它有點幫助,點擊向上按鈕(upvote)是一個很好的習慣,如果答案是完全錯誤的,你可以倒下,儘管人們不喜歡它,而且你也失去了聲望點。如果您的問題收到的答案是正確的,則必須將其標記爲(答案旁邊箭頭下方的綠色檢查標記)。這是一個有責任提問的權利。如果你不這樣做,人們在未來不會急於幫助你。 – AlexanderMP 2010-10-04 07:37:57