Hướng dẫn mysql select and update in one transaction - mysql chọn và cập nhật trong một giao dịch

Tôi có một bảng các tác vụ MySQL để thực hiện, mỗi hàng có tham số cho một tác vụ duy nhất. Có nhiều ứng dụng công nhân (có thể trên các máy khác nhau), thực hiện các tác vụ trong một vòng lặp. Các ứng dụng truy cập vào cơ sở dữ liệu bằng API C gốc của MySQL.
There are many worker apps (possibly on different machines), performing tasks in a loop.
The apps access the database using MySQL's native C APIs.

Để sở hữu một nhiệm vụ, một ứng dụng làm một cái gì đó như thế:

  • Tạo ID toàn cầu (để đơn giản, giả sử nó là một số)

  • UPDATE tasks SET guid = %d WHERE guid = 0 LIMIT 1
    SET guid = %d
    WHERE guid = 0 LIMIT 1

  • SELECT params FROM tasks WHERE guid = %d
    FROM tasks
    WHERE guid = %d

  • Nếu truy vấn cuối cùng trả về một hàng, chúng tôi sở hữu nó và có các tham số để chạy

Có cách nào để đạt được hiệu ứng tương tự (tức là 'sở hữu' một hàng và nhận các tham số của nó) trong một cuộc gọi đến máy chủ không?

LinuxBuild

15.7k6 huy hiệu vàng58 Huy hiệu bạc87 Huy hiệu đồng6 gold badges58 silver badges87 bronze badges

hỏi ngày 18 tháng 2 năm 2009 lúc 20:29Feb 18, 2009 at 20:29

Paul Oysterpaul OysterPaul Oyster

1.1986 Huy hiệu vàng15 Huy hiệu bạc19 Huy hiệu đồng6 gold badges15 silver badges19 bronze badges

Hãy thử như thế này

UPDATE `lastid` SET `idnum` = (SELECT `id` FROM `history` ORDER BY `id` DESC LIMIT 1);

Mã trên đã làm việc cho tôi

Đã trả lời ngày 8 tháng 10 năm 2012 lúc 9:03Oct 8, 2012 at 9:03

2

Bạn có thể tạo một quy trình thực hiện nó:

CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200)) BEGIN DECLARE task_id INT; SELECT id, out_params INTO task_id, out_params FROM tasks WHERE guid = 0 LIMIT 1 FOR UPDATE; UPDATE task SET guid = in_guid WHERE id = task_id; END; BEGIN TRANSACTION; CALL prc_get_task(@guid, @params); COMMIT;

Đã trả lời ngày 18 tháng 2 năm 2009 lúc 20:43Feb 18, 2009 at 20:43

QuassnoiquassnoiQuassnoi

404K89 Huy hiệu vàng606 Huy hiệu bạc608 Huy hiệu đồng89 gold badges606 silver badges608 bronze badges

4

Nếu bạn đang tìm kiếm một truy vấn duy nhất thì điều đó không thể xảy ra. Chức năng cập nhật chỉ trả về số lượng các mục đã được cập nhật. Tương tự, hàm chọn không thay đổi bảng, chỉ trả về giá trị.

Sử dụng một thủ tục thực sự sẽ biến nó thành một chức năng duy nhất và nó có thể tiện dụng nếu khóa là mối quan tâm của bạn. Nếu mối quan tâm lớn nhất của bạn là lưu lượng mạng (tức là: vượt quá nhiều truy vấn) thì hãy sử dụng quy trình. Nếu bạn lo ngại là quá tải máy chủ (tức là: DB đang làm việc quá chăm chỉ) thì chi phí thêm của quy trình có thể làm cho mọi thứ tồi tệ hơn.

Đã trả lời ngày 18 tháng 2 năm 2009 lúc 21:05Feb 18, 2009 at 21:05

PAULOPAULOPaulo

4.2152 Huy hiệu vàng18 Huy hiệu bạc20 Huy hiệu Đồng2 gold badges18 silver badges20 bronze badges

3

Tôi có vấn đề chính xác như nhau. Chúng tôi đã kết thúc bằng cách sử dụng postresql và CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200)) BEGIN DECLARE task_id INT; SELECT id, out_params INTO task_id, out_params FROM tasks WHERE guid = 0 LIMIT 1 FOR UPDATE; UPDATE task SET guid = in_guid WHERE id = task_id; END; BEGIN TRANSACTION; CALL prc_get_task(@guid, @params); COMMIT; 0:

Mệnh đề trả về tùy chọn khiến cập nhật tính toán và trả về (các) giá trị dựa trên mỗi hàng thực sự được cập nhật. Bất kỳ biểu thức nào sử dụng các cột của bảng và/hoặc các cột của các bảng khác được đề cập từ, có thể được tính toán. Các giá trị mới (Post Update) của các cột của bảng được sử dụng. Cú pháp của danh sách trả về giống hệt với danh sách đầu ra của chọn.

Ví dụ: CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200)) BEGIN DECLARE task_id INT; SELECT id, out_params INTO task_id, out_params FROM tasks WHERE guid = 0 LIMIT 1 FOR UPDATE; UPDATE task SET guid = in_guid WHERE id = task_id; END; BEGIN TRANSACTION; CALL prc_get_task(@guid, @params); COMMIT; 1

Hoặc, trong trường hợp của bạn: CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200)) BEGIN DECLARE task_id INT; SELECT id, out_params INTO task_id, out_params FROM tasks WHERE guid = 0 LIMIT 1 FOR UPDATE; UPDATE task SET guid = in_guid WHERE id = task_id; END; BEGIN TRANSACTION; CALL prc_get_task(@guid, @params); COMMIT; 2

Xin lỗi, tôi biết điều này không trả lời câu hỏi với MySQL và có thể không dễ dàng chuyển sang PostgreSQL, nhưng đó là cách tốt nhất chúng tôi tìm thấy để làm điều đó. Thậm chí 6 năm sau, MySQL vẫn không hỗ trợ CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200)) BEGIN DECLARE task_id INT; SELECT id, out_params INTO task_id, out_params FROM tasks WHERE guid = 0 LIMIT 1 FOR UPDATE; UPDATE task SET guid = in_guid WHERE id = task_id; END; BEGIN TRANSACTION; CALL prc_get_task(@guid, @params); COMMIT; 0. Nó có thể được thêm vào một số điểm trong tương lai, nhưng bây giờ Mariadb chỉ có nó để xóa các câu lệnh.

Chỉnh sửa: Có một nhiệm vụ (ưu tiên thấp) để thêm hỗ trợ CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200)) BEGIN DECLARE task_id INT; SELECT id, out_params INTO task_id, out_params FROM tasks WHERE guid = 0 LIMIT 1 FOR UPDATE; UPDATE task SET guid = in_guid WHERE id = task_id; END; BEGIN TRANSACTION; CALL prc_get_task(@guid, @params); COMMIT; 0 cho Mariadb.: There is a task (low priority) to add CREATE PROCEDURE prc_get_task (in_guid BINARY(16), OUT out_params VARCHAR(200)) BEGIN DECLARE task_id INT; SELECT id, out_params INTO task_id, out_params FROM tasks WHERE guid = 0 LIMIT 1 FOR UPDATE; UPDATE task SET guid = in_guid WHERE id = task_id; END; BEGIN TRANSACTION; CALL prc_get_task(@guid, @params); COMMIT; 0 support to MariaDB.

Đã trả lời ngày 19 tháng 11 năm 2015 lúc 21:41Nov 19, 2015 at 21:41

Marco Roymarco RoyMarco Roy

3.4116 huy hiệu vàng29 Huy hiệu bạc48 Huy hiệu đồng6 gold badges29 silver badges48 bronze badges

Tôi không biết về phần cuộc gọi duy nhất, nhưng những gì bạn đang mô tả là khóa. Khóa là một yếu tố thiết yếu của cơ sở dữ liệu quan hệ.

Tôi không biết các chi tiết cụ thể về khóa một hàng, đọc nó và sau đó cập nhật nó trong MySQL, nhưng với một chút đọc tài liệu khóa MySQL, bạn có thể thực hiện tất cả các loại thao tác dựa trên khóa.

Tài liệu của Postgres về khóa có một ví dụ tuyệt vời mô tả chính xác những gì bạn muốn làm: Khóa bảng, đọc bảng, sửa đổi bảng.

Đã trả lời ngày 18 tháng 2 năm 2009 lúc 20:35Feb 18, 2009 at 20:35

DanieldanielDaniel

1541 Huy hiệu bạc6 Huy hiệu đồng1 silver badge6 bronze badges

1

UPDATE tasks SET guid = %d, params = @params := params WHERE guid = 0 LIMIT 1;

Nó sẽ trả về 1 hoặc 0, tùy thuộc vào việc các giá trị có được thay đổi hiệu quả hay không.

SELECT @params AS params;

Điều này chỉ chọn biến từ kết nối.

Từ đây

Đã trả lời ngày 7 tháng 8 năm 2014 lúc 11:37Aug 7, 2014 at 11:37

Jogacojogacojogaco

6748 Huy hiệu bạc25 Huy hiệu Đồng8 silver badges25 bronze badges

Chúng ta có thể sử dụng chọn và cập nhật cùng nhau không?

Cấu trúc truy vấn, cập nhật từ Chọn chọn có thể được sử dụng để thực hiện loại kịch bản cập nhật dữ liệu này. Ngoài ra, chúng ta có thể sử dụng các câu lệnh hợp nhất thay thế và phương thức truy vấn con.. Also, we can use alternative MERGE statements and subquery methods.

Bạn có thể sử dụng bản cập nhật và chọn trong một câu lệnh SQL không?

SBURERY xác định một truy vấn nội bộ có thể được sử dụng bên trong câu lệnh CHỌN, CHAIN, CẬP NHẬT và XÓA.Đây là một phương pháp đơn giản để cập nhật dữ liệu bảng hiện có từ các bảng khác.Truy vấn trên sử dụng câu lệnh CHỌN trong mệnh đề đặt của câu lệnh Update.. It is a straightforward method to update the existing table data from other tables. The above query uses a SELECT statement in the SET clause of the UPDATE statement.

Làm cách nào để cập nhật nhiều mục trong MySQL?

Lệnh cập nhật MySQL có thể được sử dụng để cập nhật nhiều cột bằng cách chỉ định danh sách phân tách dấu phẩy của cột_name = new_value.Trong đó cột_name là tên của cột sẽ được cập nhật và new_value là giá trị mới mà cột sẽ được cập nhật.. Where column_name is the name of the column to be updated and new_value is the new value with which the column will be updated.

Chúng ta có thể thực hiện một bản cập nhật từ một câu lệnh chọn?

Thực hiện bản cập nhật bằng cách sử dụng câu lệnh SELLE thứ cấp có thể được thực hiện theo một trong hai cách, chủ yếu tùy thuộc vào phiên bản nào của máy chủ SQL bạn đang sử dụng.

Chủ đề