2009-02-25 20 views
6

OK, tôi biết nó có thể được thực hiện, tôi làm điều đó khá thường xuyên, nhưng tại sao rất khó khăn để làm một vòng lặp trong T-SQL? Tôi có thể nghĩ đến một tấn lý do tôi muốn phân tích thông qua một tập kết quả truy vấn và làm điều gì đó đơn giản là không thể thực hiện mà không có vòng lặp, nhưng mã để thiết lập và thực hiện vòng lặp của tôi là> 20 dòng.Tại sao rất khó khăn để làm một vòng lặp trong T-SQL

Tôi chắc rằng những người khác có ý kiến ​​tương tự, vậy tại sao chúng ta vẫn không có cách đơn giản để thực hiện vòng lặp?

Một bên: cuối cùng chúng tôi có một UPSERT (aka MERGE) trong SQL2008 vì vậy có thể tất cả hy vọng không bị mất.

Trả lời

22

SQL là dựa trên tập hợp, declarative language; không phải là thủ tục hoặc imperative language. T-SQL cố gắng để đứng giữa hai, nhưng nó vẫn được xây dựng trên một mô hình dựa trên cơ sở thiết lập.

+0

Bạn đã có những đường tròn phù hợp chưa? – AnthonyWJones

+0

Rất tiếc! bạn đúng, tôi dán liên kết của tôi theo thứ tự sai :) cảm ơn –

1

Vì SQL là ngôn ngữ được đặt. Sức mạnh của sql là tìm thấy một nhóm nhỏ hơn trong một nhóm dữ liệu lớn hơn dựa trên các đặc điểm cụ thể. Để xử lý nhiệm vụ này, việc lặp lại phần lớn là không cần thiết. Rõ ràng nó đã được thêm vào để thuận tiện trong việc xử lý một số tình huống, nhưng mục đích sử dụng ngôn ngữ này làm cho tính năng này không liên quan.

2

T-SQL không được thiết kế để trở thành ngôn ngữ bắt buộc. Nó được thiết kế để khai báo. Bản chất khai báo của nó cho phép optomizer cắt các nhiệm vụ khác nhau và chạy chúng theo cách song song và theo những cách khác, thực hiện mọi thứ theo thứ tự hiệu quả nhất.

-2

Tôi không phải là chuyên gia về DB nhưng tôi tin rằng bản chất nguyên tử của các giao dịch cơ sở dữ liệu sẽ làm cho các vòng lặp khó thực hiện vì giao dịch hoàn tất hoặc hoàn toàn không xảy ra. Duy trì trạng thái có thể được pesky!

Wikipedia Article on Atomicity

0

SQL là một hệ thống SET dựa, không phải là một thủ tục (loop) một. Nói chung nó được coi là thực hành xấu để sử dụng các vòng trong SQL vì chúng hoạt động kém so với các thiết lập tương đương.

KHI là cấu trúc vòng lặp phổ biến nhất, con trỏ cũng có thể được sử dụng, nhưng có những vấn đề riêng của họ (quên deallocate/đóng)

... một ví dụ về WHILE (bạn có thể không cần nó nhưng những người khác có thể)

DECLARE @iterator INT 
SET @iterator = 0 

WHILE @iterator < 20 
BEGIN 
    SELECT * FROM table WHERE rowKey = @iterator 
/*do stuff*/ 
    @iterator = @iterator + 1 
END 

Câu hỏi thực sự là "Bạn đang cố gắng làm điều gì đơn giản là không thể thực hiện theo cách được thiết lập?"

10

tôi có thể nghĩ đến một tấn lý do tôi muốn phân tích thông qua một kết quả truy vấn thiết lập và làm điều gì đó đơn giản là không thể được thực hiện mà không có một vòng lặp

Và đối với đại đa số tôi có thể chỉ cho bạn cách thực hiện nó trong một hoạt động dựa trên tập hợp hoặc giải thích tại sao nó phải được thực hiện trong mã máy khách của bạn thay vì trên cơ sở dữ liệu. Cần phải làm một vòng lặp trong sql là vượt quá hiếm.

+1

Tôi đồng ý họ nên được thực hiện trong mã khách hàng; tuy nhiên, khi chúng tôi đang xử lý hàng triệu bản ghi thì nhanh hơn 100x (1000x?) để thực hiện tất cả trong cơ sở dữ liệu ngay cả khi đó không phải là "địa điểm" phù hợp để thực hiện. –

+1

Một ví dụ: lặp lại tất cả các "đồ đạc" trong cơ sở dữ liệu và thực hiện một thủ tục được lưu trữ chèn vào một bảng và cập nhật khác dựa trên các giá trị của đồ đạc. Chúng tôi phải chạy điều này thường xuyên, bởi vì các bảng mà các giá trị được tính toán thay đổi thường xuyên. Mã máy khách = 1 ngày, SQL = 1 giờ. –

+1

> "Tôi đồng ý họ nên được thực hiện trong mã khách hàng, tuy nhiên," ... Đó chỉ là một phần của nó. Khác là tái cấu trúc được thiết lập dựa. Đối với ví dụ "đồ đạc" của bạn, bạn sẽ có thể viết lại quy trình được lưu trữ của mình để hoạt động trên toàn bộ bảng. –

1

hầu như mọi thứ có thể được thực hiện dựa trên, hãy thử sử dụng bảng số

tại sao 20 dòng? Đây là tất cả những gì bạn cần

select *,identity(int, 1,1) as Someid into #temp 
from sysobjects 

declare @id int, @MaxId int 
select @id = 1,@MaxId = max(Someid) from #temp 

while @id < @MaxId 
begin 
-- do your stuff here 
print @id 
set @id [email protected] + 1 
end 
1

tùy thuộc vào điều bạn muốn làm trong vòng lặp.sử dụng vòng lặp while không khó chút nào:

declare @i int 
set @i = 20 
while @i>0 begin 
... do some stuff 
set @i = @i-1 
end 

nó chỉ trở nên cồng kềnh khi sử dụng con trỏ, nên tránh mọi thứ.

1

Bạn có thể thử sử dụng các hàm do người dùng xác định để thực hiện hầu hết công việc thay vì thực hiện phương pháp dựa trên vòng lặp. Điều này sẽ bảo toàn ý định của ngôn ngữ SQL được thiết lập dựa trên.

+0

tôi thích điều này. Tôi sẽ điều tra. –

Các vấn đề liên quan