รายการข้อผิดพลาดการยกเลิกแบทช์ในเซิร์ฟเวอร์ SQL


9

ใน SQL Server ถ้า XACT_ABORT ปิดอยู่ข้อผิดพลาดบางอย่างจะยุติคำสั่งปัจจุบัน (ตัวอย่างเช่นการจัดหาจำนวนพารามิเตอร์ที่ไม่ถูกต้องให้กับกระบวนงานที่เก็บไว้ซึ่งใช้พารามิเตอร์บางตัว) และข้อผิดพลาดบางอย่างจะยกเลิกชุดทั้งหมด (ตัวอย่างเช่น ขั้นตอนที่ไม่ใช้พารามิเตอร์) [อ้างอิง]: http://www.sommarskog.se/error-handling-I.html#scope-abortion

สิ่งที่ฉันอยากรู้คือว่ามีรายการที่ชัดเจนของข้อผิดพลาดที่มีการยกเลิกชุดและคนที่มีคำสั่งยกเลิก

คำตอบ:


6

ฉันเชื่อว่ามีข้อยกเว้นบางประการ แต่จากความผิดพลาดของ Engine Database (MSDN) :

ข้อความแสดงข้อผิดพลาดที่มีระดับความรุนแรงตั้งแต่ 19 ขึ้นไปจะหยุดการทำงานของแบตช์ปัจจุบัน

ข้อผิดพลาดที่ยุติการเชื่อมต่อฐานข้อมูลซึ่งมักจะมีระดับความรุนแรงตั้งแต่ 20 ถึง 25 จะไม่ถูกจัดการโดยบล็อก CATCH เนื่องจากการดำเนินการจะถูกยกเลิกเมื่อการเชื่อมต่อสิ้นสุดลง

ดังนั้นดูเหมือนว่าคุณจะได้รับรายการที่ชัดเจนจากแบบสอบถามต่อไปนี้ (แน่นอนว่าสิ่งนี้จะไม่อนุญาตให้คุณกรองสิ่งที่ผู้ใช้อาจเกิดจาก T-SQL):

SELECT message_id, severity, [text]
FROM sys.messages
WHERE language_id = 1033 
AND severity >= 19
ORDER BY severity, message_id;

ใน SQL Server 2012 จะสร้าง 210 แถว

ใน SQL Server 2016 จะสร้าง 256 แถว

โดยวิธีการที่ฉันไม่เชื่อว่าสองสถานการณ์ที่คุณอธิบายในคำถามของคุณทำงานอย่างที่คุณคิดว่าอย่างน้อยไม่ได้อยู่ในรุ่นที่ทันสมัยของ SQL Server ฉันลองสิ่งนี้ทั้งในปี 2555 และ 2559 (ฉันเชื่อว่าบทความของ Erland อธิบายพฤติกรรมของ SQL Server 2000 ซึ่งฉันจำไม่ได้ว่ามันแตกต่างกันหรือไม่

USE tempdb;
GO

CREATE PROCEDURE dbo.pA -- no parameters
AS PRINT 1
GO
CREATE PROCEDURE dbo.pB -- two parameters
@x INT, @y INT
AS PRINT 1
GO

SET XACT_ABORT OFF;
GO

EXEC dbo.pA @foo = 1; 
PRINT '### Calling procedure that doesn''t take parameters with a parameter';
GO

EXEC dbo.pB; 
PRINT '### Calling procedure that takes 2 parameters with no parameters';
GO

EXEC dbo.pB @x = 1; 
PRINT '### Calling procedure that takes 2 parameters with not enough parameters';
GO

EXEC dbo.pB @x = 1, @y = 2, @z = 3; 
PRINT '### Calling procedure that takes 2 parameters with too many parameters';
GO

สิ่งเหล่านี้สร้างข้อผิดพลาดของระดับความรุนแรง 16 และทั้งหมดดำเนินการกับแบทช์ดังที่เห็นได้จากผลลัพธ์การพิมพ์:

เกี่ยวกับข่าวสาร 8146 ระดับ 16 สถานะ 2 โพรซีเดอร์ pA โพรซีเดอร์บรรทัด 11
pA ไม่มีพารามิเตอร์และอาร์กิวเมนต์ถูกระบุ
### ขั้นตอนการโทรที่ไม่รับพารามิเตอร์ด้วยพารามิเตอร์
ข่าวสารเกี่ยวกับ 201 ระดับ 16 สถานะ 4 ขั้นตอน pB กระบวนงานบรรทัดที่ 14
หรือฟังก์ชัน 'pB' คาดว่าพารามิเตอร์ '@x' ซึ่งไม่ได้ระบุไว้
### ขั้นตอนการโทรที่ใช้ 2 พารามิเตอร์โดยไม่มีพารามิเตอร์
ข่าวสารเกี่ยวกับ 201, ระดับ 16, สถานะ 4, โพรซีเดอร์ pB, โพรซีเดอร์บรรทัด 18
หรือฟังก์ชัน 'pB' คาดว่าพารามิเตอร์ '@y' ซึ่งไม่ได้ระบุไว้
### ขั้นตอนการโทรที่ใช้ 2 พารามิเตอร์ที่มีพารามิเตอร์ไม่เพียงพอ
ข่าวสารเกี่ยวกับ 8144, ระดับ 16, สถานะ 2, โพรซีเดอร์ pB, โพรซีเดอร์บรรทัดที่ 22,
หรือฟังก์ชัน pB มีการระบุอาร์กิวเมนต์มากเกินไป
### ขั้นตอนการโทรที่ใช้ 2 พารามิเตอร์ที่มีพารามิเตอร์มากเกินไป

อย่างที่ฉันสงสัยว่ามีข้อยกเว้นแน่นอนตามที่ระบุไว้ในความคิดเห็น ความล้มเหลวในการแปลงคือความรุนแรง 16 แต่ยกเลิกแบทช์:

SET XACT_ABORT OFF;
SELECT CONVERT (INT, 'foo');
PRINT 'Made it.'; -- no print happens

ผลลัพธ์ไม่รวมเอาท์พุทการพิมพ์ในครั้งนี้:

ข่าวสารเกี่ยวกับ 245, ระดับ 16, สถานะ 1
การแปลงล้มเหลวเมื่อแปลงค่า varchar 'foo' เป็นชนิดข้อมูล int


ขอบคุณมาก! ฉันคิดว่าฉันจะไม่สามารถใช้ระดับความรุนแรงเป็นตัวบ่งชี้เนื่องจากความไม่สอดคล้องกันก่อนหน้านี้ ดีใจมากที่ได้ยินเช่นนั้น
เจมี่อัลฟอร์ด

aargh! ยังมีข้อผิดพลาดระดับ 16 ระดับความรุนแรงที่จะยกเลิกชุดงานได้ ถ้าฉันเลือกและดำเนินการ: เริ่ม tran print @@ TRANCOUNT การแปลงการพิมพ์ (int, 'abc') ตามด้วย: print @@ TRANCOUNT จะมีข้อผิดพลาดระดับ 16 แต่ชุดจะถูกยกเลิก
Jamie Alford

BTW หากคุณค้นพบกรณีที่มีข้อยกเว้นยกระดับความรุนแรงแตกต่างจากกรณีที่ประกาศไว้โปรดรายงานผ่านการเชื่อมต่อ
Remus Rusanu

2

นอกเหนือจากประเภทของข้อผิดพลาดที่บันทึกโดย @Aaron (เช่นความรุนแรง> = 19 และความล้มเหลวในการแปลง) ประเภทของข้อผิดพลาดต่อไปนี้ซึ่งระบุไว้ในหน้า MSDN สำหรับTRY ... CATCHจะยกเลิกชุด:

ข้อผิดพลาดประเภทต่อไปนี้ไม่ได้รับการจัดการโดยบล็อก CATCH เมื่อเกิดขึ้นที่ระดับการดำเนินการเดียวกันกับโครงสร้าง TRY … CATCH

  • ข้อผิดพลาดในการคอมไพล์เช่นข้อผิดพลาดทางไวยากรณ์ที่ป้องกันไม่ให้ชุดงานทำงาน

  • ข้อผิดพลาดที่เกิดขึ้นในระหว่างการคอมไพล์ระดับคำสั่งเช่นข้อผิดพลาดในการแก้ไขชื่อวัตถุที่เกิดขึ้นหลังจากการรวบรวมเนื่องจากการจำแนกชื่อที่เลื่อนออกไป

ข้อผิดพลาดเหล่านี้จะกลับสู่ระดับที่รันแบตช์กระบวนงานที่เก็บไว้หรือทริกเกอร์

ในตัวอย่างด้านล่างโปรดทราบว่าสามในสามนั้นมีระดับความรุนแรงเท่ากับ 15

ตัวอย่าง 1

SET XACT_ABORT OFF;
SELECT @NotDeclared; -- parse error
PRINT 'Do you see me?';

ผลตอบแทน:

ข่าวสารเกี่ยวกับ 137, ระดับ 15, สถานะ 2, บรรทัด 2
ต้องประกาศตัวแปรสเกลาร์ "@NotDeclared"

ตัวอย่าง 2

SET XACT_ABORT OFF;
InvalidSQL; -- parse error
PRINT 'Do you see me?';

ผลตอบแทน:

ข่าวสารเกี่ยวกับ 102 ระดับ 15 สถานะ 1 บรรทัด 2
ไวยากรณ์ไม่ถูกต้องใกล้ 'InvalidSQL'

ตัวอย่าง 3

SET XACT_ABORT OFF;
SELECT 1 -- statement preceding THROW not terminated by semicolon
THROW 50505, N'Error, yo', 1; -- parse error
PRINT 'Do you see me?';

ผลตอบแทน:

ข่าวสารเกี่ยวกับ 102 ระดับ 15 สถานะ 1 บรรทัด 3
ไวยากรณ์ที่ไม่ถูกต้องใกล้กับ '50505'

ตัวอย่าง 4

SET XACT_ABORT OFF;
SELECT NoSuchColumn FROM sys.objects; -- compilation error
PRINT 'Do you see me?';

ผลตอบแทน:

ข่าวสารเกี่ยวกับ 207, ระดับ 16, สถานะ 1, บรรทัด 3
ชื่อคอลัมน์ไม่ถูกต้อง 'NoSuchColumn'

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.