2009-07-08 25 views
13

Tại sao tôi phải SET ARITHABORT ON khi sử dụng xml trong máy chủ sql 2005? Tôi đã cố gắng nghiên cứu tại sao tôi phải thiết lập điều này nhưng không thể tìm thấy câu trả lời cho tôi biết lý do. Chỉ cần thiết lập nó.Tại sao tôi phải SET ARITHABORT ON khi sử dụng xml trong máy chủ sql 2005?

Dưới đây là thông báo lỗi cụ thể tôi nhận được khi tôi đưa ra các ARITHABORT SET ON dòng:

PARAMETER ERROR: INSERT LIST COULD NOT BE PARSED - INSERT failed because the following SET options have incorrect settings: 'ARITHABORT'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or query notifications and/or xml data type methods.

thủ tục lưu trữ của tôi làm việc tốt gọi từ asp.net sử dụng odbc trong một môi trường. Sau đó, khi tôi chuyển nó sang cái khác, tôi phải thêm SET ARITHABORT ON vào đầu thủ tục đã lưu. Tôi bao gồm các phần có liên quan của quy trình được lưu trữ bên dưới. Và mã đang gọi nó.

CREATE PROCEDURE [dbo].[myproc] 
    @ruserid    varchar(8), 
    @folder_list   xml, 
    @insert_list   xml 
AS 

SET NOCOUNT ON 
SET ARITHABORT ON 

DECLARE @rindex integer 
DECLARE @errormsg nvarchar(4000) 
DECLARE @folder_cnt integer 
DECLARE @insert_cnt integer 


SET @rindex = -1 

-- temp table to hold inserts 
CREATE TABLE #insert_list (rowidx integer IDENTITY(1,1), insertdesc varchar(96) COLLATE database_default, insertfolder integer) 

-- temp table to hold folders 
CREATE TABLE #folder_list (rowidx integer IDENTITY(1,1), folderdesc varchar(144) COLLATE database_default, insertfolder integer) 

-- insert inserts to make sure data is compatible in type 
BEGIN TRY 
    INSERT INTO #insert_list (insertdesc, insertfolder) 
    SELECT insert_list.listitem.value('@insertdesc', 'varchar(96)'), insert_list.listitem.value('@insertfolder', 'integer') 
    FROM @insert_list.nodes('/Root/Insert') AS insert_list(listitem) 
END TRY 
BEGIN CATCH 
    SET @errormsg = N'PARAMETER ERROR: INSERT LIST COULD NOT BE PARSED - ' + ERROR_MESSAGE() 
    RAISERROR(@errormsg, 16, 1) 
    RETURN 
END CATCH 

-- insert folders to make sure data is compatible in type 
BEGIN TRY 
    INSERT INTO #folder_list (insertfolder, folderdesc) 
    SELECT folder_list.listitem.value('@insertfolder', 'integer'), folder_list.listitem.value('@folderdesc', 'varchar(144)') 
    FROM @folder_list.nodes('/Root/Folder') AS folder_list(listitem) 
END TRY 
BEGIN CATCH 
    SET @errormsg = N'PARAMETER ERROR: FOLDER LIST COULD NOT BE PARSED - ' + ERROR_MESSAGE() 
    RAISERROR(@errormsg, 16, 1) 
    RETURN 
END CATCH 

-- insert rows 
BEGIN TRANSACTION 

BEGIN TRY 

INSERT INTO my_folder_request (ruserid) 
VALUES (@ruserid) 

SET @rindex = SCOPE_IDENTITY() 

INSERT INTO my_insert_request (rindex, insertdesc, insertfolder) 
SELECT @rindex, #insert_list.insertdesc, #insert_list.insertfolder 
FROM #insert_list 
ORDER BY #insert_list.rowidx 

INSERT INTO my_folder_desc (rindex, insertfolder, folderdesc) 
SELECT @rindex, #folder_list.insertfolder, #folder_list.folderdesc 
FROM #folder_list 
ORDER BY #folder_list.rowidx 

END TRY 
BEGIN CATCH 
    IF @@TRANCOUNT > 0 
     ROLLBACK TRANSACTION 
    SET @errormsg = N'DATA INSERTION FAILED WITH MESSAGE - ' + ERROR_MESSAGE() 
    RAISERROR(@errormsg, 16, 1) 
    RETURN 
END CATCH 

IF @@TRANCOUNT > 0 
    COMMIT TRANSACTION 

-- return result 
SELECT @rindex AS rindex 

DROP TABLE #insert_list 
DROP TABLE #folder_list 

GO   

Calling Mã

' build odbc command for inserting creation request 
    intRequestIndex = 0 
    cmdAddRequest = New System.Data.Odbc.OdbcCommand 
    cmdAddRequest.CommandType = CommandType.StoredProcedure 
    cmdAddRequest.CommandTimeout = 60 
    cmdAddRequest.CommandText = "{CALL myproc (?, ?, ?)}" 

    ' add parameters to odbc command 
    cmdAddRequest.Parameters.Add("@ruserid", OdbcType.VarChar, 8).Value = SafeODBCParamString(m_strUID) 
    cmdAddRequest.Parameters.Add("@folder_list", OdbcType.NText).Value = System.Text.Encoding.Unicode.GetString(strmFolderList.ToArray()) 
    cmdAddRequest.Parameters.Add("@insert_list", OdbcType.NText).Value = System.Text.Encoding.Unicode.GetString(strmInsertList.ToArray()) 

    ' run odbc command returning info about results 
    cmdAddRequest.Connection = Me.ODBCConnection() 
    Try 
    rdrRequestData = cmdAddRequest.ExecuteReader(CommandBehavior.CloseConnection) 

Trả lời

6

Tôi đang nghĩ câu lệnh này từ các loại sách trực tuyến gợi ý: "SET ARITHABORT phải BẬT khi bạn đang tạo hoặc thay đổi chỉ mục trên cột được tính toán hoặc chế độ xem được lập chỉ mục". Vì vậy, các phương pháp nút phải tạo ra một cái nhìn được lập chỉ mục nội bộ hoặc một cái gì đó. Nhưng đây chỉ là một phỏng đoán được giáo dục.

0

Trừ khi bạn đang tạo ra các chỉ mục XML bạn không nên cần phải thiết lập ARITHABORT sang ON. Điều đó nói rằng tôi biết rằng có một số vấn đề hiệu suất khi sử dụng ADO.NET (mà tôi tin rằng đặt ARITHABORT thành OFF) Nó không làm tổn thương nó ON vì nó sẽ chấm dứt một truy vấn khi một lỗi tràn hoặc chia cho không xảy ra trong khi truy vấn chấp hành.

4

Đây là giải pháp tôi đã tìm thấy vấn đề ARITHABORT khi gọi thủ tục được lưu trữ với thông số đầu vào xml từ máy khách .Net.

using (var conn = new SqlConnection(dbConnectionString)) 
{ 
    SqlCommand command = new SqlCommand("[stored procedure name here]", conn); 
    command.CommandType = CommandType.StoredProcedure; 
    command.Parameters.AddWithValue("@parameter_name", parameter_xml_value); 

    conn.Open(); 

    SqlCommand arithabortCommand = new SqlCommand("SET ARITHABORT ON", conn); 
    arithabortCommand.ExecuteNonQuery(); 

    command.ExecuteNonQuery(); 
    conn.Close(); 
} // using (var conn = new SqlConnection(dbConnectionString)) 
+0

Không thể bạn chỉ cần nói rõ các tùy chọn chính xác trong proc được lưu trữ? 'SET ANSI_NULLS ON SET ANSI_PADDING ON ANSI_WARNINGS SET ON SET ARITHABORT ON SET CONCAT_NULL_YIELDS_NULL ON SET NUMERIC_ROUNDABORT OFF SET QUOTED_IDENTIFIER ON' –

2

Will Rickards' và John Gilmer của câu trả lời là rắn. Họ trả lời 'tại sao' và 'khi nào'. Tôi sẽ mở rộng câu trả lời của John một chút:

Tôi chỉ gặp vấn đề tương tự này và tự hỏi tại sao cài đặt ARITHABORT lại quan trọng - đặc biệt là vì tôi có phần mềm giống hệt nhau đang chạy mà không gặp sự cố trên một số máy chủ khác. Sử dụng hai máy chủ khác nhau, tôi thực hiện như sau:

SET ARITHABORT OFF 
DECLARE @message XML 
SELECT @message = (SELECT '1' As Bar FOR XML PATH('Foo'), TYPE) 
SELECT @@Version, @@Options, compatibility_level from sys.databases where name='xxxx' 
SELECT @message.exist('/Foo/Bar') -- This line fails on only one server 

Hóa ra sự khác biệt giữa hai máy chủ là mức phù hợp cơ sở dữ liệu:

80: Error 
100: Okay 
Các vấn đề liên quan