SQL komut dosyası yürütme nasıl kırılır


16

Ben sql script üzerinde çalışıyorum ve bazı koşullar memnun değilse senaryoya devam etmeyi durdurmak zorundayım.

Google'ı kullandığımda, 20 şiddeti olan RaisError'ı sona erdireceğini buldum. Ancak bazı nedenlerden dolayı bu seçeneği kullanamıyorum.

Lütfen bana SQL komut dosyası yürütmeyi durdurmak için olası alternatifler neler sağlayabilir.


1
Bir hatayı neden yükseltmek kabul edilemez? Ayrıca bu komut dosyası bir saklı yordam mı?
Namphibian

İlk sorunuzu net olarak anlamadım. İkinci soru için; hayır bu bir SP değil
Yeni Geliştirici

1
Senaryo nedir? Birden fazla parti içeriyor mu? Cevapları burada gördün mü?
Martin Smith

Yanıtlar:


8

Gönderen RAISERROR belgelerinde (vurgu benim):

0 ile 18 arasındaki önem dereceleri herhangi bir kullanıcı tarafından belirlenebilir. 19 ile 25 arasındaki önem dereceleri yalnızca sysadmin sabit sunucu rolünün üyeleri veya ALTER TRACE izinlerine sahip kullanıcılar tarafından belirlenebilir. 19 ile 25 arasındaki önem dereceleri için WITH LOG seçeneği gereklidir.

Bu ölçütleri karşılamadığı için komut dosyasını yürüttüğünüz esastır.

Kullanmanın yanlış bir yanı yok RAISERROR; sadece aşırı önem derecesini kullanıyorsunuz. Yükseltilen bir hata için seviye 16'yı varsayılan olarak kullanıyorum ve sıra sonlandırılacak. Daha doğru olmak istiyorsanız, Microsoft'un kendisi tarafından verilen seviyeleri takip edebilirsiniz:

resim açıklamasını buraya girin

Şimdi, komut dosyasının içeriğine bağlı RAISERRORolarak, komut dosyasının kendi başına "normal önem düzeylerini kullanarak" çıkmadığı için kullanmak yeterli olmayabilir.

Örneğin:

RAISERROR(N'Test', 16, 1);

SELECT 1;   /* Executed! */

Bu olacak , hem bir hata yükseltmek ve bir sonuç kümesi döndürür.

Komut dosyasını hemen sonlandırmak için kullanmayı tercih ederim RETURN( GOTO-type yapılarını kullanmak genellikle alternatiflerin bulunduğu çoğu programlama çemberinde önerilmez):

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */

Veya şiddeti 11 veya daha yüksekse TRY/CATCHyürütmenin CATCHbloğa atlamasına neden olacak hatayı kullanarak işleyin:

BEGIN TRY
    RAISERROR(N'Test', 16, 1);
    SELECT 1;   /* Not executed */
END TRY
BEGIN CATCH
    SELECT 2;   /* Executed */
END CATCH

BEGIN TRY
    RAISERROR(N'Test', 10, 1);
    SELECT 1;   /* Executed */
END TRY
BEGIN CATCH
    SELECT 2;   /* Not executed */
END CATCH

Ayrı bir sorun komut birden çok toplu yayılan eğer - RETURNsadece çıkılacak toplu :

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */
GO

SELECT 2;   /* Executed! */

Bunu düzeltmek için @@ERRORher partinin başlangıcında kontrol edebilirsiniz :

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */
GO

IF (@@ERROR != 0)
    RETURN;

SELECT 2;   /* Not executed */

Edit: Martin Smith yorumlarda doğru bir şekilde işaret ettiği gibi, bu sadece 2 parti için çalışır. 3 veya daha fazla gruba genişletmek için, yükseltme hatalarını aşağıdaki gibi arttırabilirsiniz (not: GOTOyöntem, hedef etiketin parti içinde tanımlanması gerektiği için bu sorunu çözmez):

RAISERROR(N'Test', 16, 1);
RETURN;

SELECT 1;   /* Not executed */
GO

IF (@@ERROR != 0)
BEGIN
    RAISERROR(N'Error already raised. See previous errors.', 16, 1);
    RETURN;
END

SELECT 2;   /* Not executed */
GO

IF (@@ERROR != 0)
BEGIN
    RAISERROR(N'Error already raised. See previous errors.', 16, 1);
    RETURN;
END

SELECT 3;   /* Not executed */

Ya da belirttiği gibi , ortamınız için uygunsa SQLCMDyöntemi kullanabilirsiniz .


Bu son öneri işe yaramıyor. Bkz . Burada sqlcmd yöntemini
Martin Smith

6

İfadeyi GOTOistediğiniz yerde atlamak için kullanabilirsiniz . Başka bir deyişle, bir hata veya başka bir koşulla karşılaşırsınız ve komut dosyasının alt kısmında bir etiket olabilir (yani TheEndOfTheScript:) ve sadece bir goto TheEndOfTheScript;ifade yayınlayabilirsiniz .

İşte hızlı bir örnek:

print 'here is the first statement...';

print 'here is the second statement...';

-- substitute whatever conditional flow determining factor
-- you'd like here. I have chosen a dummy statement that will
-- always return true
--
if (1 = 1)
    goto TheEndOfTheScript;

print 'here is the third statement...';

print 'here is the fourth statement...';


TheEndOfTheScript:
print 'here is the end of the script...';

Bu yürütmenin çıktısı aşağıdaki gibi olacaktır:

here is the first statement...
here is the second statement...
here is the end of the script...

Gördüğünüz gibi GOTO, üçüncü ve dördüncü ifadeleri yazdırmayı atladı ve doğrudan etikete ( TheEndOfTheScript) atladı .


7
Yalnızca tek bir toplu iş olduğunda çalışır, GO ifadeniz olur olmaz kesilir.
Gabriel


0

Kabul SET NOEXEC ON/OFF, ancak Saklı Procs (tek bir blok içeren) ben sadece ifade kullanın RETURN.

Uyarılar: Birden varsa bir komut dosyası dosyasında GOifadeleri, RETURNyalnızca geçerli bloğun ortaya çıkacak ve bir sonraki blok / toplu devam edin.

Not: GOTOKötü bir kodlama uygulaması olduğu varsayılırsa, TRY..CATCHSQL Server 2008'den bu yana tanıtıldığı gibi " " kullanılması önerilir THROW.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.