2009-05-17 35 views
10

Nó có vẻ như không có trí tuệ với tôi. Tôi đã nghe vô số câu chuyện về những người quên mệnh đề WHERE trong một UPDATE hoặc DELETE và trashing toàn bộ một bảng. Tôi biết rằng những người bất cẩn không nên đưa ra các truy vấn trực tiếp và tất cả điều đó ... và có trường hợp hợp pháp mà bạn muốn ảnh hưởng đến tất cả các hàng, nhưng sẽ không có tùy chọn theo mặc định yêu cầu các truy vấn đó được viết như sau:Tại sao SQL Server không thực hiện mệnh đề WHERE theo mặc định?

UPDATE MyTable SET MyColumn = 0 WHERE * 

Hoặc mà không thay đổi ngôn ngữ,

UPDATE MyTable SET MyColumn = 0 WHERE 1 = 1 -- tacky, I know 
+4

Bạn giả định rằng người chết não sẽ không chỉ thêm một WHERE 1 = 1 bởi rote và sẽ bắt đầu suy nghĩ thay thế. Tôi không nghĩ điều đó sẽ xảy ra: họ đã chết não. Trong khi đó, mọi công ty sẽ yêu cầu tùy chọn "Josh" được đặt vào mọi lúc để "bảo mật" và thế giới tư duy sẽ săn lùng bạn và giết bạn. IMHO, tất nhiên, YMMV. –

+1

Vì vậy, bạn có nghĩa là để cho tôi biết rằng nó là phổ biến để cố ý phát hành bản cập nhật và xóa mà không có một mệnh đề where và "thế giới suy nghĩ" sẽ rất phiền bởi tùy chọn này mà họ muốn tôi chết? – Josh

+5

Tôi không mua lập luận rằng mọi người sẽ học cách gõ 'WHERE 1 = 1' nơi họ không thực sự muốn nó. Để phát triển thói quen đó, họ sẽ phải có một tình huống thường xuyên, nơi họ thực sự muốn cập nhật để đạt được mọi hàng, và điều đó dường như ít phổ biến hơn trong trường hợp bạn * không * muốn điều đó. Điểm yêu cầu một cái gì đó như 'WHERE 1 = 1' không phải là để bảo vệ chống lại những người * nghĩ * họ muốn đánh mỗi hàng, nó là để bảo vệ chống lại những người vô tình nhấn F5 quá sớm hoặc chọn tất cả mọi thứ nhưng mệnh đề WHERE . –

Trả lời

5

Không phải là có thể đặt tự động cam kết sai trong phiên khách hàng của bạn như là một mặc định?Bạn phải đưa ra một "cam kết" để xem những thay đổi của bạn theo cách đó, trong hầu hết "bạn có chắc chắn muốn làm điều này không?" thời trang.

Tôi tin rằng đó là mặc định cho tất cả khách hàng của Oracle TOAD tại một nhà tuyển dụng cũ.

+0

Rất tuyệt! Tôi đã không biết về nó nhưng nó được gọi là SET IMPLICIT_TRANSACTIONS {ON | OFF} và như bạn đã lưu ý, nó gây ra các lệnh yêu cầu commit rõ ràng. Trong khi tôi chắc chắn sẽ chạy với tùy chọn đó từ bây giờ, nó vẫn cảm thấy sai với tôi rằng SQL mặc định ảnh hưởng đến tất cả các hàng. – Josh

+0

Nếu nó "đẹp", tại sao không bỏ phiếu và chấp nhận câu trả lời? Bạn sẽ phải cảnh báo cơ quan tiêu chuẩn SQL để cho họ biết rằng bạn không chấp nhận quyết định của họ. – duffymo

+0

Tôi đã bỏ phiếu, nhưng ai đó đã đến và bỏ phiếu cho tất cả các câu trả lời đồng ý. Tôi không đánh dấu nó là câu trả lời vì tôi đang chờ xem có người nào đi cùng với lời giải thích nào đó về việc tại sao nó không thể hoặc không nên làm. Nhưng có vẻ như "chúng tôi là lập trình viên nên chúng tôi không nên phạm sai lầm" là câu trả lời phổ biến nhất. Tôi sẽ đánh dấu của bạn. – Josh

10

spec không đòi hỏi nó, và bạn không nên chạy sql quảng cáo hoc trực tiếp chống lại dữ liệu sản xuất anyway.

+5

"không nên chạy ad hoc sql trực tiếp với dữ liệu sản xuất anyway". lol. Mọi người cũng không nên vượt quá giới hạn tốc độ trên đường cao tốc - nhưng họ làm, và mọi người bây giờ buộc phải đeo dây an toàn để ngăn chặn chấn thương. OP đang tự hỏi tại sao dây an toàn không được yêu cầu trong vùng đất SQL. – TheSoftwareJedi

+6

Dây an toàn ít nhất phải là một lựa chọn – rpetrich

+2

Trong khi dây an toàn phải là một lựa chọn, IMHO, không cần phải có bất kỳ tùy chọn nào. Chúng tôi là những lập trình viên, và đã được trao quyền lực, sức mạnh to lớn để gây ra sự trỗi dậy và sụp đổ của các cơ sở dữ liệu; chúng ta phải sử dụng trách nhiệm và sự chăm sóc lớn trong công việc hàng ngày của chúng ta. Người quản trị có thể kích hoạt dây an toàn nếu có, nhưng tôi không nghĩ chúng ta nên trông đợi một cái ở đó. –

4

Làm cho sai lầm này là một nghi thức thông điệp được khắc dài đối với người lập trình. Tất cả chúng ta đã làm cho nó - và royally screwed lên dữ liệu sản xuất - học được rất nhiều trong quá trình sửa chữa nó. Bạn chỉ mắc lỗi này một lần, vì vậy thật vui khi xem một nhà phát triển tham gia vào các cấp bậc khi nó xảy ra.

Ngăn chặn nó xảy ra sẽ làm hỏng tất cả những niềm vui!

:)

+0

Trong tất cả sự nghiêm túc, công việc đầu tiên của tôi ở trường trung học làm việc trong lĩnh vực hỗ trợ kỹ thuật cho một .com họ có nghĩa là chúng tôi sẽ sử dụng các lệnh như "người dùng cập nhật thiết lập bị khóa = 0 nơi ..." trong khi ứng dụng vĩnh viễn "phát triển" . sau đó họ sẽ hét lên khi ai đó quên mệnh đề where. :) Nhưng tôi đã luôn luôn tự hỏi tại sao họ thậm chí sẽ cho phép cú pháp đó và tôi vẫn không thực sự thấy một lý do hợp lệ. – Josh

4

Joel, tôi nghĩ điểm của câu hỏi Josh là lý do tại sao không spec cần đến nó, hoặc ít thuê có một thiết lập tùy chọn mà sẽ làm cho cơ sở dữ liệu cụ thể đòi hỏi nó?

Vì thông số không yêu cầu như bạn nói, có một cơ hội cho truy vấn không rõ ràng (hoặc quảng cáo đặc biệt hoặc đơn giản là lỗi chương trình) để thay đổi các hàng trong cơ sở dữ liệu bạn không có ý định thay đổi.

Một ẩn "TẤT CẢ ROWS" có vẻ nguy hiểm hơn nhiều so với "KHÔNG ROWS" ngầm định.

+2

Tôi sẽ phải đồng ý rằng nó có lẽ sẽ là lợi ích tốt nhất của tất cả nếu nó là một NO ROWS ẩn. –

0

Tôi biết từ kinh nghiệm mà bạn chỉ làm điều này một lần ... sau khi nó xảy ra một khi bạn luôn luôn đảm bảo không bao giờ để cho nó xảy ra một lần nữa !!!

5

Chỉ cần để chơi nó an toàn, chúng tôi luôn có thể chạy trong một giao dịch:

BEGIN TRAN 

UPDATE MyTable SET MyColumn = 0 

Sau đó, nếu số lượng hàng có vẻ tốt:

COMMIT TRAN 
+0

Đó là một gợi ý tuyệt vời. Tôi luôn luôn làm điều đó nếu không có lý do khác hơn để đảm bảo tiêu chí của tôi là tốt. – Josh

4

từ quan điểm của tôi đây là một câu hỏi rethoric, Tôi có nghĩa là đó là một gợi ý ...

Bằng chứng, tôi thấy nó thực sự tốt, có thể có một số cài đặt như "SAFE_UPDATE" hoặc một cái gì đó tương tự ...

những gì tôi thường làm, bên cạnh mũi robin của (allways mở một giao dịch), là để chạy các truy vấn với lựa chọn, chỉ để có một cái nhìn tại các hồ sơ mà sẽ được cập nhật, một cái gì đó như thế này

update mytable set column = xx 
-- select * from mytable 
where mycondition = mycondition 

trước cập nhật tôi chỉ cần chọn từ các lựa chọn và xem những gì nó sẽ trả về ...

dù sao, bạn allways nên có một bản sao lưu (tôi nghe sql 2005 bức ảnh chụp được khá mát mẻ quá) và làm việc bên trong một giao dịch ...

0

Josh thực sự không phải là tất cả những điều bất thường khi muốn xóa hoặc cập nhật tất cả các hàng trong bảng.

1

MySQL KHÔNG cung cấp tùy chọn đó cho truy vấn đặc biệt. Nó được gọi là - cập nhật an toàn (hoặc --i-am-a-giả). Như những người khác đã chỉ ra, chúng tôi đã tất cả đã phạm sai lầm đó một lần. Những người trong chúng ta, những người chạy các truy vấn đặc biệt mọi lúc, đôi khi vào lúc 1 giờ sáng, đã phạm sai lầm nhiều lần.

Mặc dù tôi thường ghét các hệ thống "bằng chứng không xác thực" và các hộp thoại "bạn chắc chắn", Tôi thích tùy chọn này. Bạn nên luôn cẩn thận, nhưng thậm chí là cẩn thận bạn sẽ làm cho có lẽ một lỗi mỗi nghìn giờ. Nếu bạn dành 50 giờ một năm tuần đăng nhập với tư cách là người chủ trên hệ thống sản xuất, một lỗi mỗi nghìn giờ là 2 1/2 số lần trục vít lớn mỗi năm. Vì lý do đó và một lý do khác, chúng tôi tìm thấy - cập nhật an toàn rất hữu ích.

Có hai lý do hữu ích hơn hầu hết các xác nhận MS thư. Đầu tiên nó bắt được một thứ có nhiều khả năng là một lỗi, không giống như "bạn có chắc chắn muốn xóa tệp đó không?". Hầu hết các tập tin xóa thực sự là mong muốn, do đó, xác nhận là một khó chịu. Hầu hết "xóa từ người dùng", nếu thiếu mệnh đề where, thực sự là lỗi. Thứ hai, nó chỉ ra chính xác những gì các vấn đề có khả năng là - thiếu khoản where. Đó là như thể xác nhận xóa tệp là đủ thông minh để nói "đó là thương hiệu bản sao cập nhật mới, không phải bản sao cũ mà bạn cho rằng mình đang xóa. Bạn có thực sự muốn xóa bản sao mới hay bạn định xóa cái cũ thay thế? "

Dù sao, nói chung tôi ghét "bằng chứng ngốc nghếch", nhưng tôi thích - cập nhật an toàn và nếu đó là tùy chọn những người không muốn nó không cần sử dụng nó. Mối quan tâm của tôi là nếu bạn liên tục làm việc trên một hệ thống có tính năng, ai đó có thể bị cẩu thả và gặp rắc rối khi họ chuyển sang hệ thống mà không có nó, chẳng hạn như chuyển từ MySQL sang MSSQL.

Làm xước cảnh báo trước - không ai trong tâm trí của họ sẽ chuyển sang MS sau khi trở nên quen thuộc với nguồn mở. :)

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