จากเอกสาร RAISERROR (การเน้นของฉัน):
ผู้ใช้สามารถระบุระดับความรุนแรงตั้งแต่ 0 ถึง 18 ระดับความรุนแรงตั้งแต่ 19 ถึง 25 สามารถระบุได้โดยสมาชิกของบทบาทเซิร์ฟเวอร์ถาวร sysadmin หรือผู้ใช้ที่มีสิทธิ์ ALTER TRACE สำหรับระดับความรุนแรงตั้งแต่ 19 ถึง 25 ต้องใช้ตัวเลือก WITH LOG
เป็นไปได้สูงว่าตัวการที่คุณรันสคริปต์นั้นไม่เป็นไปตามเกณฑ์เหล่านี้
ไม่มีอะไรผิดปกติกับการใช้RAISERROR
; คุณแค่ใช้ระดับความรุนแรงที่มากเกินไป ฉันใช้ระดับ 16 เป็นค่าเริ่มต้นสำหรับข้อผิดพลาดที่ยกขึ้นและลำดับจะถูกยกเลิก หากคุณต้องการความแม่นยำมากขึ้นคุณสามารถทำตามระดับที่ Microsoft กำหนดเอง:
ตอนนี้การพูดทั้งหมดนั้นขึ้นอยู่กับบริบทของสคริปต์การใช้RAISERROR
อาจไม่เพียงพอเนื่องจากไม่ได้ "ออก" สคริปต์ด้วยตัวเอง (ใช้ระดับความรุนแรงปกติ)
ตัวอย่างเช่น:
RAISERROR(N'Test', 16, 1);
SELECT 1; /* Executed! */
นี้จะทั้งยกระดับข้อผิดพลาดและกลับชุดผลลัพธ์
หากต้องการยุติสคริปต์ทันทีฉันชอบที่จะใช้RETURN
(โดยใช้GOTO
-type constructs มักจะหมดกำลังใจในแวดวงการเขียนโปรแกรมส่วนใหญ่ที่มีทางเลือกอื่น):
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
หรือจัดการกับข้อผิดพลาดในการใช้TRY/CATCH
ซึ่งจะทำให้การประมวลผลข้ามไปยังCATCH
บล็อกถ้าความรุนแรงเป็น 11 หรือสูงกว่า:
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
ปัญหาแยกคือถ้าสคริปต์ขยายหลายแบตช์ - RETURN
จะออกจากแบทช์เท่านั้น:
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
GO
SELECT 2; /* Executed! */
ในการแก้ไขปัญหานี้คุณสามารถตรวจสอบได้@@ERROR
ที่จุดเริ่มต้นของทุกชุด:
RAISERROR(N'Test', 16, 1);
RETURN;
SELECT 1; /* Not executed */
GO
IF (@@ERROR != 0)
RETURN;
SELECT 2; /* Not executed */
แก้ไข: มาร์ตินสมิ ธ ชี้ให้เห็นอย่างถูกต้องในความคิดเห็นนี้ใช้งานได้เพียง 2 ชุด ในการขยายแบตช์ 3 ชุดขึ้นไปคุณสามารถเรียงซ้อนข้อผิดพลาดที่เกิดขึ้นได้เช่นนั้น (หมายเหตุ: GOTO
วิธีการนี้ไม่สามารถแก้ปัญหานี้ได้เนื่องจากต้องกำหนดฉลากเป้าหมายภายในแบตช์):
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 */
หรืออย่างที่เขาชี้ให้เห็นคุณสามารถใช้SQLCMD
วิธีนี้หากเหมาะสมกับสภาพแวดล้อมของคุณ