2014-09-29 6 views
0

나는 데이터베이스 과정에 대한 과제로 "뱅크"를 구축하고 있습니다. 몇 가지 IN 변수 (예 : 계정 ID, 고객 ID 및 PIN 번호)를 사용하는 저장 함수를 만들었으며 제출 된 데이터가 유효한지 확인하기 위해이 함수를 검사합니다. 데이터가 유효하면 절차는 계좌 잔액을 업데이트하여 화폐 거래를 나타냅니다. 그런 다음 제출 된 데이터가 유효한지 여부를 "반환"합니다. 다음 절차에 대한 코드입니다 :함수 내부에서 프로 시저를 호출하면 MySQL ERROR가 발생합니다. 1422

DELIMITER // 
CREATE PROCEDURE retrieveMoney (
    IN holder INT, 
    IN pin VARCHAR(4), 
    IN account INT, 
    IN amount FLOAT, 
    OUT success INT 
) 
BEGIN 
    START TRANSACTION; 
    SELECT COUNT(id) INTO success FROM account_holder WHERE id=holder AND pin=pin; 
    IF success IS NOT NULL THEN 
     IF (SELECT balance-amount FROM account WHERE id=account) >= 0 THEN 
      UPDATE account SET balance = balance-amount WHERE id=account; 
      CALL logTransaction(account,NULL,amount); 
      COMMIT; 
     ELSE ROLLBACK; 
     END IF; 
    ELSE ROLLBACK; 
    END IF; 
END// 
DELIMITER ; 

내가 쉽게 프로 시저의 출력을 볼 수 있도록 원했고, 나는 내가 래퍼 함수를 ​​작성하기로 결정했습니다 함수 내에서 트랜잭션을 사용하는 것이 허용되지 않아으로는, 다음과 같이

DELIMITER // 
CREATE FUNCTION retrieveMoney (
    holder INT, 
    pin VARCHAR(4), 
    account INT, 
    amount FLOAT 
) 
RETURNS INT 
BEGIN 
    CALL retrieveMoney(holder,pin,account,amount,@success); 
    RETURN @success; 
END// 
DELIMITER ; 

을 불행하게도이 작동하지 않습니다, 나는 여전히 다음과 같은 오류 얻을 :

ERROR 1422 (HY000): Explicit or implicit commit is not allowed in stored function or trigger.

이 내가 때문입니다 함수 안에 트랜잭션이 포함 된 프로 시저를 호출 하시겠습니까?

+2

예. 예. 오류 메시지가 큰 소리로 알려줍니다. –

답변

3

암시 적 커밋을 발생시키는 여러 명령문이 있으며 저장 함수 또는 트리거 또는 저장된 함수 또는 트리거에서 호출 된 저장 프로 시저에서이 중 아무 것도 사용할 수 없으므로 실제로 그물 효과는 다르지 않습니다.

순간적으로 반영된 이유는 쿼리가 인 동안 저장된 함수 (및 트리거)가 입니다. 이들은 항상 예외없이 쿼리가 시작된 후에 실행을 시작하고 쿼리가 끝나기 전에 실행을 마칩니다. 또한 단일 쿼리를 실행하는 동안 여러 번 실행할 수도 있습니다. 특히 쿼리에 여러 행이 포함되는 경우에는 특히 그렇습니다.

단일 쿼리가 실행되는 동안 COMMIT 트랜잭션이 가능한 경우에는 의미가 없습니다. 트랜잭션이 실행 중이면 START TRANSACTION은 암시 적으로 현재 트랜잭션을 커밋하고, 새로운 것을 시작합니다.

다른 쿼리의 중간에 프로 시저를 호출하는 유일한 방법 인 저장 함수 나 트리거를 통해 다른 쿼리의 중간에 호출하지 않는 한 저장 프로 시저에서 문제가 없습니다)하지만 여기에서하는 일은 지원되지 않습니다 ... 실행중인 트랜잭션이 없더라도 실행중인 쿼리의 중간에 트랜잭션을 시작할 수는 없습니다.

http://dev.mysql.com/doc/refman/5.6/en/implicit-commit.html

+1

위대한 답변, 감사합니다! 당신이 그것을 그렇게 넣으면 정말로 의미가 있습니다! – Psyberion