2009-06-10 58 views
75

Tôi có một bảng Đơn hàng có cột Số lượng. Khi nhận phòng hoặc trả phòng, chúng tôi cần cập nhật cột Số lượng đó một lần. Có cách nào để làm điều này trong một hành động hoặc chúng ta phải có được giá trị hiện tại và sau đó thêm hoặc trừ một giá trị trên đầu trang của nó?SQL cách tăng hoặc giảm một cột cho một cột int trong một lệnh

Một câu hỏi khác là khi chúng tôi chèn một hàng mới, chúng ta có cần phải kiểm tra nếu dữ liệu giống nhau hiện có sau đó chèn nếu không, đó là hai bước, hoặc là có một cách tốt hơn để làm điều này?

cảm ơn,

Trả lời

182

Để trả lời đầu tiên:

UPDATE Orders SET Quantity = Quantity + 1 WHERE ... 

Để trả lời câu thứ hai:

Có một số cách để làm điều này. Vì bạn không chỉ định một cơ sở dữ liệu, tôi sẽ giả sử MySQL.

  1. INSERT INTO table SET x=1, y=2 ON DUPLICATE KEY UPDATE x=x+1, y=y+2
  2. REPLACE INTO table SET x=1, y=2

Cả hai đều có thể xử lý câu hỏi của bạn. Tuy nhiên, cú pháp đầu tiên cho phép linh hoạt hơn để cập nhật các bản ghi thay vì chỉ thay thế nó (như là thứ hai không).

Hãy ghi nhớ rằng cho cả để tồn tại, có phải được một chìa khóa UNIQUE định nghĩa ...

+24

Vì bạn không chỉ định một cơ sở dữ liệu, bạn nên thực sự giả định SQL tiêu chuẩn. – paxdiablo

3
UPDATE Orders Order 
SET Order.Quantity = Order.Quantity - 1 
WHERE SomeCondition(Order) 

Theo như tôi biết không có build-in hỗ trợ cho INSERT-OR-UPDATE trong SQL. Tôi đề nghị tạo một thủ tục lưu sẵn hoặc sử dụng một truy vấn có điều kiện để đạt được điều này. Here bạn có thể tìm thấy một tập hợp các giải pháp cho các cơ sở dữ liệu khác nhau.

+0

Bạn có thể gặp lỗi cú pháp khi ném từ dành riêng ORDER xung quanh như vậy ... – gahooa

+0

Bạn đúng ... nên được thoát. –

+0

cảm ơn bạn đã liên kết, tài nguyên rất tốt – 5YrsLaterDBA

0

để trả lời câu hỏi thứ hai:

làm cho cột duy nhất và bắt ngoại lệ nếu được đặt thành cùng một giá trị.

2

Nếu hiểu biết của tôi là chính xác, các bản cập nhật sẽ khá đơn giản. Tôi sẽ làm như sau.

UPDATE TABLE SET QUANTITY = QUANTITY + 1 and 
UPDATE TABLE SET QUANTITY = QUANTITY - 1 where QUANTITY > 0 

Bạn có thể cần thêm bộ lọc để chỉ cập nhật một hàng duy nhất thay vì tất cả các hàng.

Để chèn, bạn có thể lưu một số id duy nhất liên quan đến bản ghi của bạn cục bộ và kiểm tra bộ nhớ cache này và quyết định có chèn hay không. Cách tiếp cận thay thế là luôn chèn và kiểm tra lỗi vi phạm PK và bỏ qua vì đây là chèn thừa.

0

@dotjoe Sẽ rẻ hơn khi cập nhật và kiểm tra @@ rowcount, thực hiện chèn sau khi thực tế.

Exceptions đắt & & cập nhật thường xuyên hơn

Góp ý: Nếu bạn muốn trở thành uber performant trong Dal của bạn, hãy kết thúc đường chuyền trước trong một ID duy nhất cho hàng phải được cập nhật, nếu null chèn.

DAL phải là CRUD và không cần phải lo lắng về việc không trạng thái.

Nếu bạn làm cho nó không trạng thái, Với chỉ mục tốt, bạn sẽ không thấy sự khác biệt với câu lệnh SQL vs 1 sau đây. IF (chọn top 1 * Hình thức x nơi PK = @ ID) Chèn khác cập nhật

9

Câu trả lời đơn bước cho câu hỏi đầu tiên là sử dụng cái gì đó như:

update TBL set CLM = CLM + 1 where key = 'KEY' 

Đó là rất nhiều một cách đơn giản để làm điều đó.

Đối với câu hỏi thứ hai, bạn không cần phải sử dụng các thể dục SQL cụ thể DBMS (như UPSERT) để có được kết quả mong muốn. Có một phương pháp tiêu chuẩn để thực hiện cập nhật hoặc chèn mà không yêu cầu một DBMS cụ thể.

try: 
    insert into TBL (key,val) values ('xyz',0) 
catch: 
    do nothing 
update TBL set val = val + 1 where key = 'xyz' 

Tức là, bạn cố gắng thực hiện việc tạo đầu tiên. Nếu nó đã có, bỏ qua lỗi. Nếu không, bạn tạo nó với giá trị 0.

Sau đó làm bản cập nhật này sẽ làm việc một cách chính xác hay không:

  • hàng ban đầu tồn tại.
  • ai đó đã cập nhật nó giữa quá trình chèn và cập nhật của bạn.

Nó không phải là một chỉ dẫn duy nhất và được nêu ra, thật ngạc nhiên, đó là cách chúng tôi đã làm nó thành công trong một thời gian dài.

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