【问题标题】:Why do I have to SET ARITHABORT ON when using xml in sql server 2005?为什么在 sql server 2005 中使用 xml 时必须设置 ARITHABORT ON?
【发布时间】:2010-11-09 03:55:08
【问题描述】:

为什么在 sql server 2005 中使用 xml 时必须设置 ARITHABORT ON? 我尝试研究为什么我必须设置它,但找不到告诉我原因的答案。只是它需要设置。

这是我在取出 SET ARITHABORT ON 行时收到的具体错误消息:

参数错误:无法解析插入列表 - 插入失败 因为以下 SET 选项的设置不正确: “阿里萨博特”。验证 SET 选项是否适用于索引 计算列和/或查询通知上的视图和/或索引 和/或 xml 数据类型方法。

在一个环境中使用 odbc 从 asp.net 调用我的存储过程运行良好。然后当我将它移到另一个时,我不得不在存储过程的开头添加 SET ARITHABORT ON。我在下面包含了存储过程的相关部分。以及调用它的代码。

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           

调用代码

  ' 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) 

【问题讨论】:

    标签: sql-server xml


    【解决方案1】:

    这是我在从 .Net 客户端调用带有 xml 输入参数的存储过程时发现的 ARITHABORT 问题的解决方案。

    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))  
    

    【讨论】:

    • 你不能在存储过程中明确说明正确的选项吗? 'SET ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON SET ARITHABORT ON SET CONCAT_NULL_YIELDS_NULL ON SET NUMERIC_ROUNDABORT OFF SET QUOTED_IDENTIFIER ON'
    【解决方案2】:

    我认为在线书籍中的这句话暗示了这一点:“当您在计算列或索引视图上创建或更改索引时,SET ARITHABORT 必须为 ON。”所以节点方法必须在内部创建索引视图或其他东西。但这只是一个有根据的猜测。

    【讨论】:

      【解决方案3】:

      根据这个线程(在底部),它可能取决于您的兼容性级别:

      http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/a874b4b2-05ad-4066-9811-30939188d695

      【讨论】:

        【解决方案4】:

        Will Rickards 和 John Gilmer 的回答非常可靠。他们回答了“为什么”和“何时”。我将稍微扩展一下约翰的答案:

        我刚遇到同样的问题,想知道为什么 ARITHABORT 设置很重要 - 特别是因为我在其他几台服务器上运行相同的软件而没有问题。使用两个不同的服务器,我执行了以下操作:

        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
        

        原来两台服务器的区别在于数据库兼容级别:

         80: Error
        100: Okay
        

        【讨论】:

          【解决方案5】:

          除非您正在创建 XML 索引,否则您不需要将 ARITHABORT 设置为 ON。这就是说我知道使用 ADO.NET 时存在一些性能问题(我相信将 ARITHABORT 设置为 OFF)它不会伤害它,因为它会在查询期间发生溢出或被零除错误时终止查询执行。

          【讨论】:

            【解决方案6】:

            为了解决这个问题,我将数据库的 de Compatility 级别从 2000 年更改为 2005 年,并且可以正常工作。

            【讨论】:

              猜你喜欢
              • 2011-02-27
              • 1970-01-01
              • 2011-01-13
              • 2014-06-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多