2008-12-31 27 views
31

Không phải là một người SQL. Có mã sau mà một nhà tư vấn đã viết.SQL "IF", "BEGIN", "END", "END IF"?

Đầu tiên, nó đảm bảo chỉ có một trường tiểu học đã được chọn - sau đó, sau BEGIN, nếu biến @Term bằng 3, chúng tôi muốn thực hiện công cụ theo câu lệnh IF đó. Đây là vấn đề. Khi @Term không phải là = 3 chúng tôi vẫn muốn thả xuống và làm phần SECERT INSERT INTO @Classes. FYI - Thuật ngữ là = 3 khi điều này đang được chạy, nhưng nó không làm cả hai INSERT - nên có một END IF ở phần cuối của phần "IF @Term = 3" thay vì chỉ là một END đơn giản?

IF @SchoolCategoryCode = 'Elem' 

--- We now have determined we are processing an elementary school... 

BEGIN 

---- Only do the following if the variable @Term equals a 3 - if it does not, skip just this first part 

    IF @Term = 3 

    BEGIN 

     INSERT INTO @Classes 

     SELECT  
     XXXXXX 
     FROM XXXX blah blah blah 

    END <----(Should this be ENDIF?) 

---- **always** "fall thru" to here, no matter what @Term is equal to - always do the following INSERT for all elementary schools 

    INSERT INTO @Classes  
    SELECT 
    XXXXXXXX  
    FROM XXXXXX (more code) 

END 
+0

Tôi thụt vào mã bên trong khối trong cùng Begin-End, nghĩ rằng nó có thể giúp một số. – MrBoJangles

Trả lời

2

Nếu đây là MS SQL Server sau đó những gì bạn có nên làm việc tốt ... Trong thực tế, kỹ thuật, bạn don; t cần Begin & End ở tất cả, snce chỉ có một tuyên bố trong begin- End Block ... (Tôi giả định @Classes là một biến bảng?)

If @Term = 3 
    INSERT INTO @Classes 
    SELECT     XXXXXX 
    FROM XXXX blah blah blah 
-- ----------------------------- 

-- This next should always run, if the first code did not throw an exception... 
INSERT INTO @Classes  
SELECT XXXXXXXX   
FROM XXXXXX (more code) 
0

Nếu tôi nhớ chính xác, và thường thì tôi không ... không có hỗ trợ END IF trong Transact-Sql. BEGIN và END sẽ thực hiện công việc. Bạn có gặp lỗi không?

0

Dựa trên mô tả của bạn về những gì bạn muốn làm, mã có vẻ đúng. ENDIF không phải là một từ khóa kiểm soát vòng lặp SQL hợp lệ. Bạn có chắc chắn rằng INSERTS đang thực sự kéo dữ liệu để đưa vào @Classes không? Trong thực tế, nếu nó là xấu nó sẽ không chạy.

Điều bạn có thể muốn thử là đặt một vài câu lệnh PRINT vào đó. Đặt một IN ở trên mỗi INSERTS chỉ xuất ra một số văn bản ngớ ngẩn để cho thấy rằng dòng đó đang thực hiện. Nếu bạn nhận được cả hai kết quả đầu ra, sau đó SELECT của bạn ... INSERT ... là nghi ngờ. Bạn cũng có thể thực hiện lệnh SELECT thay cho PRINT (nghĩa là, không có INSERT) và xem chính xác dữ liệu nào đang được kéo.

18

Không có ENDIF trong SQL.

Câu lệnh trực tiếp theo dõi IF chỉ được thực hiện khi biểu thức if là đúng.

BEGIN ... Cấu trúc END tách biệt với IF. Nó liên kết nhiều câu lệnh với nhau thành một khối có thể được xử lý như thể chúng là một câu lệnh đơn. Do đó BEGIN ... END có thể được sử dụng trực tiếp sau một IF và do đó toàn bộ khối mã trong chuỗi BEGIN .... END sẽ được thực hiện hoặc bỏ qua.

Trong trường hợp của bạn, tôi nghi ngờ "(thêm mã)" sau TỪ XXXXX là nơi xảy ra sự cố của bạn.

29

Nó phải làm với Biểu mẫu thông thường cho ngôn ngữ SQL. Câu lệnh IF có thể, theo định nghĩa, chỉ cần duy nhất câu lệnh SQL. Tuy nhiên, có một loại câu lệnh SQL đặc biệt có thể chứa nhiều câu lệnh SQL, khối BEGIN-END.

Nếu bạn bỏ qua khối bắt đầu, SQL của bạn sẽ chạy tốt, nhưng nó sẽ chỉ thực thi câu lệnh đầu tiên như một phần của IF.

Về cơ bản, điều này:

IF @Term = 3 
    INSERT INTO @Classes 
    SELECT    
     XXXXXX 
    FROM XXXX blah blah blah 

tương đương với điều tương tự với khối BEGIN-END, bởi vì bạn chỉ thực hiện một tuyên bố duy nhất. Tuy nhiên, vì lý do tương tự mà không bao gồm dấu ngoặc nhọn trên câu lệnh if trong ngôn ngữ giống như C là một ý tưởng tồi, nó là luôn luôn thích hợp hơn để sử dụng BEGIN và END.

+0

Vô cùng hữu ích. – VSO

4

Tắt tay mã có vẻ đúng. Nếu bạn thử sử dụng 'Khác' và xem điều gì sẽ xảy ra?

IF @SchoolCategoryCode = 'Elem' 

--- We now have determined we are processing an elementary school... 

BEGIN 

---- Only do the following if the variable @Term equals a 3 - if it does not, skip just this first part 

    IF @Term = 3 
    BEGIN 
     INSERT INTO @Classes 

     SELECT    
      XXXXXX 
     FROM XXXX blah blah blah 

     INSERT INTO @Classes  
     SELECT 
     XXXXXXXX  
     FROM XXXXXX (more code) 
    END <----(Should this be ENDIF?) 
    ELSE 
    BEGIN 


     INSERT INTO @Classes  
     SELECT 
     XXXXXXXX  
     FROM XXXXXX (more code) 
    END 
END 
+0

Tôi một lần nữa. Tôi không thể thêm "ELSE". Bởi vì, tôi luôn muốn thực hiện câu lệnh INSERT thứ hai cho dù có hay không @Term = 3 –

1

Lần duy nhất chèn lần thứ hai vào @clases sẽ không thành công nếu xảy ra lỗi trong câu lệnh chèn đầu tiên.

Nếu trường hợp đó xảy ra, thì bạn cần quyết định xem câu lệnh thứ hai có nên chạy trước OR đầu tiên hay không nếu bạn cần một giao dịch để thực hiện khôi phục.

2

Bạn cũng có thể viết lại mã để xóa hoàn toàn câu lệnh 'If' lồng nhau.

INSERT INTO @Classes  
SELECT XXXXXX  
FROM XXXX 
Where @Term = 3 

---- **always** "fall thru" to here, no matter what @Term is equal to - always do 
---- the following INSERT for all elementary schools  
INSERT INTO @Classes   
SELECT XXXXXXXX   
FROM XXXXXX (more code) 
+0

Suy nghĩ tốt. Bước logic tiếp theo sẽ là để giảm điều này thành một chèn với một lựa chọn UNION ALL. –

-9

Thẳng thắn mà nói này có vẻ như cái gì đó nên được trên lớp ứng dụng, không phải là lớp cơ sở dữ liệu ...

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