2012-09-04 20 views
5

Tôi có hai câu hỏi về Tuyên bố Hợp chất và Giao dịch trong MySQL.BẮT ĐẦU GIAO DỊCH bên trong BEGIN ... Ngữ cảnh END hoặc bên ngoài và cú pháp LOOP

FIRST:

Có hai ghi chú trong MySQL Manual:

Note

Trong tất cả các chương trình lưu trữ, xử lý phân tích cú pháp BEGIN [WORK] như khởi đầu của một BEGIN .. Khối END. Để bắt đầu giao dịch trong ngữ cảnh này, hãy sử dụng START TRANSACTION thay thế.

Note

Trong tất cả các chương trình lưu trữ (lưu trữ thủ tục và hàm, gây nên, và các sự kiện), các xử lý phân tích cú pháp BEGIN [WORK] là sự khởi đầu của một BEGIN ... khối END. Bắt đầu giao dịch trong ngữ cảnh này với START GIAO DỊCH thay thế.

Tôi không thể hiểu chính xác ý nghĩa của nó. Có nghĩa là tôi phải đặt START TRANSACTION thay vì BEGIN hoặc ngay sau BEGIN?

// 1st variant: 

BEGIN 
    START TRANSACTION 
    COMMIT 
END 


// 2nd variant: 

START TRANSACTION 
COMMIT 
END 

Cách nào đúng, biến thể thứ nhất hoặc biến thể thứ 2?

SECOND:

Tôi không muốn tạo Thủ tục hoặc chức năng được lưu trữ. Tôi chỉ muốn tạo Khối đối chiếu-Tuyên bố với một vòng lặp bên trong nó trong luồng chung, như sau:

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 

Có thể loại cấu trúc như vậy không? Bởi vì tôi đã một lỗi ném:

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 ... 

Câu hỏi của tôi là:

  1. Có được phép sử dụng BEGIN...END chỉ trong dòng chảy chung mà không cần tạo và sử dụng thủ tục lưu trữ hoặc chức năng?
  2. Được phép sử dụng BEGIN...END bên trong START TRANSACTION...COMMIT hoặc tôi phải đặt START TRANSACTION...COMMIT bên trong BEGIN...END?

    BEGIN 
        START TRANSACTION 
        COMMIT 
    END 
    
    // vs. 
    
    START TRANSACTION 
        BEGIN 
        END 
    COMMIT 
    
  3. Đỗ tôi bằng mọi cách phải sử dụng BEGIN...END nếu tôi muốn sử dụng chỉ LOOP? Tôi có thể sử dụng cú pháp LOOP mà không cần bắt đầu BEGIN...END không? Ví dụ duy nhất trong cuốn hướng dẫn cho LOOP là thế này:

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

Trả lời

10
  1. Có được phép sử dụng BEGIN ... END chỉ trong dòng chảy chung mà không cần tạo và sử dụng thủ tục lưu trữ hoặc chức năng?

    Không: chỉ có thể sử dụng câu lệnh ghép trong phần thân của chương trình được lưu trữ.

  2. Có được phép sử dụng BEGIN...END bên trong START TRANSACTION...COMMIT hoặc tôi có phải đặt START TRANSACTION...COMMIT bên trong BEGIN...END?

    START TRANSACTION;COMMIT; là các tuyên bố riêng biệt. Nếu bạn muốn cơ thể của một chương trình được lưu trữ chứa nhiều câu lệnh, nó sẽ cần phải kèm theo các câu lệnh đó trong một số loại khối câu lệnh phức hợp như BEGIN ... END (tương tự như bao gồm một khối câu lệnh trong dấu ngoặc đơn { ... } trong ngôn ngữ giống chữ C).

    Điều đó nói rằng, bạn có thể có một chương trình được lưu trữ mà chỉ chứa các đơn tuyên bố START TRANSACTION; hoặc COMMIT; — một chương trình như vậy sẽ không yêu cầu bất kỳ khối câu lệnh ghép và chỉ đơn thuần là sẽ bắt đầu một mới/cam kết giao dịch hiện hành tương ứng.

    Bên ngoài chương trình được lưu trữ, trong đó không cho phép khối dấu hợp chất, bạn có thể phát hành các câu hỏi START TRANSACTION;COMMIT; như & khi được yêu cầu.

  3. Tôi có phải sử dụng BEGIN...END nếu tôi chỉ muốn sử dụng LOOP? Tôi có thể sử dụng cú pháp LOOP mà không cần bắt đầu BEGIN...END không?

    LOOP cũng là khối câu lệnh ghép, chỉ hợp lệ trong một quy trình được lưu trữ. Nó không phải là cần thiết để đặt khối LOOP trong khối BEGIN ... END, mặc dù nó là bình thường (vì nếu không thì sẽ rất khó để thực hiện bất kỳ khởi tạo vòng lặp bắt buộc nào).

Trong trường hợp của bạn, nơi bạn dường như muốn chèn dữ liệu vào một bảng từ một cấu trúc vòng lặp, bạn sẽ hoặc là cần phải:

  • xác định một chương trình lưu trữ trong đó bạn sử dụng LOOP;

  • lặp lại vòng lặp trong chương trình bên ngoài thực thi truy vấn cơ sở dữ liệu trên mỗi lần lặp; hoặc

  • xác định lại logic của bạn theo các tập hợp mà trên đó SQL có thể hoạt động trực tiếp.

+0

Tại sao vòng lặp chỉ tồn tại trong một proc được lưu trữ? Có vẻ chậm phát triển phải tạo một tệp lưu trữ tạm thời chỉ để thực hiện chèn vòng lặp đơn giản ..... – Pacerier

+0

@Pacerier: bởi vì đó là logic nghiệp vụ thuộc về mã ứng dụng của bạn, không phải lớp cơ sở dữ liệu. – eggyal

+0

@eggyal trong khi tôi hoàn toàn đồng ý với bạn Pacerier có một điểm rất hợp lệ, tại sao mysql hoạt động khác với các chương trình được lưu trữ so với truy vấn chuẩn –

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