2012-09-04 21 views
5

Mam dwa pytania dotyczące Oświadczenie złożone i transakcje w MySQL.Uruchamianie TRANSACTION w kontekście BEGIN ... END lub poza i składnia LOOP

PIERWSZA:

Istnieją dwie notatki w podręczniku MySQL:

Note

We wszystkich zapisanych programów, traktuje parser BEGIN [WORK] Ponieważ początku BEGIN .. Blok END. Aby rozpocząć transakcję w tym kontekście , użyj zamiast tego opcji START TRANSACTION.

Uwaga

We wszystkich zapisanych programów (procedury przechowywane i funkcje, wyzwalacze, i wydarzenia), traktuje parser BEGIN [WORK] jako początek bloku BEGIN ... END. Rozpocznij transakcję w tym kontekście za pomocą START TRANSACTION.

Nie mogę zrozumieć, co dokładnie ma na myśli. To znaczy, że muszę wstawić START TRANSACTION zamiast BEGIN lub zaraz po BEGIN?

// 1st variant: 

BEGIN 
    START TRANSACTION 
    COMMIT 
END 


// 2nd variant: 

START TRANSACTION 
COMMIT 
END 

Który z nich jest właściwy, wariant 1 lub wariant 2?

DRUGI

Nie chcę stworzyć procedury przechowywanej lub funkcji. Chcę tylko, aby utworzyć blok bezkonsolowe Oświadczenie pętli wewnątrz niego w ogólnym strumieniu, tak:

USE 'someDb'; 
START TRANSACTION 
    ... create table statement 
    ... insert statement 

// now I want to implement some insert/select statements using loop, I do as follows: 

DELIMITER $ 
BEGIN 
    SET @n = 1, @m = 2; 
    lab1: LOOP 

    ... some insert, select statements here 

    END LOOP lab1; 
END $ 
DELIMITER ; 

END 

COMMIT 

Czy jest możliwe takie rodzaj struktury? Bo mam błąd rzucony:

Query: BEGIN SET @n = 1, @m = 2; lab1: LOOP SELECT ... 
Error Code: 1064 
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET @n = 1, @m = 2; 
lab1: LOOP SELECT ... 

Moje pytania są następujące:

  1. Czy wolno używać BEGIN...END tylko w ogólnym strumieniu bez tworzenia i używania procedur składowanych lub funkcji?
  2. Czy można używać BEGIN...END wewnątrz START TRANSACTION...COMMIT lub muszę umieścić START TRANSACTION...COMMIT wewnątrz BEGIN...END?

    BEGIN 
        START TRANSACTION 
        COMMIT 
    END 
    
    // vs. 
    
    START TRANSACTION 
        BEGIN 
        END 
    COMMIT 
    
  3. Do I za wszelką cenę trzeba używać BEGIN...END jeśli chcę użyć tylko LOOP? Czy mogę po prostu użyć składni LOOP bez uruchamiania BEGIN...END? Jedyny przykład w instrukcji dla LOOP to:

    CREATE PROCEDURE doiterate(p1 INT) 
        BEGIN 
         label1: LOOP 
         ... 
    

Odpowiedz

10
  1. Czy wolno używać BEGIN ... END tylko w ogólnym strumieniu bez tworzenia i używania procedur składowanych lub funkcji?

    Nie: złożone instrukcje mogą być używane tylko w obrębie zapisanych programów.

  2. Czy wolno używać BEGIN...END wewnątrz START TRANSACTION...COMMIT czy muszę umieścić START TRANSACTION...COMMIT wewnątrz BEGIN...END?

    START TRANSACTION; i COMMIT; to oddzielne stwierdzenia. Jeśli chcesz, aby treść zapisanego programu zawierała wiele instrukcji, będzie musiała zamknąć te instrukcje w pewnym bloku złożonych zdań, takim jak BEGIN ... END (który jest podobny do bloku instrukcji w nawiasach klamrowych { ... } w języku C-podobnym).

    Mimo to, mógłby mieć zapisany program, który zawiera tylko jeden-oświadczenie START TRANSACTION; lub COMMIT; — taki program nie musiałby dowolny blok oświadczenie związek i to tylko rozpoczęcie nowego/popełnić bieżącej transakcji odpowiednio.

    Poza przechowywanym programem, w którym bloki instrukcji złożonych są niedozwolone, można w razie potrzeby wydawać instrukcje START TRANSACTION; i COMMIT; jako &.

  3. Do I za wszelką cenę trzeba używać BEGIN...END jeśli chcę użyć tylko LOOP? Czy mogę po prostu użyć składni LOOP bez uruchamiania BEGIN...END?

    LOOP to także złożony blok instrukcji, który jest ważny tylko w ramach procedury składowanej. Nie jest konieczne dołączanie bloku w bloku LOOP wewnątrz bloku , chociaż jest to normalne (ponieważ w przeciwnym razie trudno jest przeprowadzić dowolną wymaganą inicjalizację pętli).

w przypadku, w którym najwyraźniej chcesz wstawić dane do tabeli z konstruktem zapętlenie, będzie to albo trzeba:

  • określić zapisany program, w którym używasz LOOP;

  • iterować pętlę w zewnętrznym programie, który wykonuje zapytania do bazy danych w każdej iteracji; lub

  • ponownie zdefiniować swoją logikę w kategoriach zestawów, na których SQL może bezpośrednio działać.

+0

Dlaczego pętle istnieją tylko w zapisanym proc? Wydaje się być opóźnionym, aby utworzyć tymczasowy zapisany proces tylko po to, aby wykonać prostą wstawkę pętli ..... – Pacerier

+0

@Pacerier: ponieważ jest to logika biznesowa, która należy do twojego kodu aplikacji, a nie do warstwy bazy danych. – eggyal

+0

@eggyal, podczas gdy w pełni się z tobą zgadzam Pacerier ma bardzo ważny punkt, dlaczego mysql zachowuje się inaczej w przypadku programów przechowywanych w porównaniu ze standardowymi zapytaniami. –