[英]How to use a transaction in a stored procedure?
我有一個SQL腳本,需要將其轉換為參數化的存儲過程。 我過去只寫了簡單的函數,從來沒有寫過帶有參數的復雜事務查詢。
非常感謝您的幫助-下面簡化了查詢。 該腳本實際上可以是包含交易和一些用戶輸入的任何內容。
-- transaction ensures i can clean up a mess, if one happens
begin;
-- parameters for the script; currently set manually before execution
set @parent_id := 123;
set @identifier := 'someid';
-- insert some row with user-specified values
insert into users (field1, field2) values (@parent_id, @identifier);
-- get the new id
set @user_id := last_insert_id();
-- do another insert
insert into usersmeta (user_id, field1, field2) values (@user_id, 1, 2);
-- if no errors happened yet, commit transaction
commit;
-- "return value"; some select query (could be 1 or many rows)
select users.id userid, usersmeta metaid
from users
join usersmeta on usersmeta.user_id = users.id;
我以開始但后來幾乎陷入困境。 我特別關心確保錯誤在發生時以某種方式對調用代碼可見
delimiter ;;
CREATE PROCEDURE mytask(IN parent_id INT(11), IN identifier VARCHAR(200))
BEGIN
SET @query = ???
PREPARE q FROM @query;
EXECUTE q;
DEALLOCATE PREPARE q;
END;;
delimiter ;
經過大量的研究,試驗和錯誤,但是我認為我找到了一個很好的解決方案。
DELIMITER //
CREATE PROCEDURE my_procedure (IN parent_id int, IN identifier varchar(255), OUT out_user_id int)
BEGIN
-- local variable, set later after user is created
DECLARE user_id int;
-- rollback transaction and bubble up errors if something bad happens
DECLARE exit handler FOR SQLEXCEPTION, SQLWARNING
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
-- insert some row with user-specified values
INSERT INTO users (field1, field2) values (parent_id, identifier);
-- get the new id
SET user_id = last_insert_id();
-- do another insert
INSERT INTO usersmeta (user_id, field1, field2) values (user_id, 1, 2);
-- if no errors happened yet, commit transaction
COMMIT;
-- return
SELECT user_id INTO out_user_id;
END //
DELIMITER ;
我可以這樣使用
-- run the procedure
CALL my_procedure(123, 'some_id', @user_id);
-- get the "return" value
SELECT @user_id as user_id;
這絕對是我編寫的最復雜的存儲過程。 如果有人看到需要改進的地方,我將很高興學習如何做得更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.