本文介绍了Sybase 内部错误 30016的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数据库服务器从 12.5x 版迁移到 15.03 版Sybase.Data.AseClient 版本 - 1.15.50.0

当我通过 .Net 应用程序(使用 AseClient)运行一些存储过程时,我遇到了以下异常

内部错误:30016 Unknown Dataitem Dataitem堆栈跟踪 -在 Sybase.Data.AseClient.AseDataReader.CheckResult(Int32 res)在 Sybase.Data.AseClient.AseDataReader.RetrieveNextResult()在 Sybase.Data.AseClient.AseDataReader.GetNextResult()在 Sybase.Data.AseClient.AseDataReader.NextResult()在 Sybase.Data.AseClient.AseDataReader.CloseUrsHandle()在 Sybase.Data.AseClient.AseDataReader.Close()在 Sybase.Data.AseClient.AseDataReader.Dispose(Boolean disposing)在 Sybase.Data.AseClient.AseDataReader.Dispose()在 System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand 命令, CommandBehavior 行为)在 System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand 命令, CommandBehavior 行为)在 System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable)在 HSBC.STPMapper.SybaseDAL.Utilities.SybaseHelper.ExecuteDataset(CommandType commandType, String commandText, DataSet dataset, String table, AseParameter[] commandParameters) 在 C:\Utilities\SybaseHelper.cs:line 119

注意 - 在我们迁移到新服务器之前,应用程序运行良好.

解决方案

我们遇到了这个问题,一些代码在 .NET Framework 3.5 下运行并使用 Sybase.Data.AseClient.dll(版本1.1.510.0) 当我们将生产服务器从 12.5 升级到 15 时. 升级后在开发和测试环境中一切正常,但在生产中失败,即使 ASP 经典代码和 PowerBuilder 代码能够调用生产 Sybase 服务器(大遗留系统).

如果我尝试为单个记录调用 AseDataReaderRead 方法,则一切正常.但是,如果我们允许读取所有记录,那么如果您通过 Sybase SQL Adandage 客户端调用存储过程,它将只读取 67 条记录中的 22 条记录.我把它归结为一个玩具命令行应用程序来重现这个问题.以下是 阅读 中的错误详细信息:

类型:Sybase.Data.AseClient.AseException消息:内部错误:30016堆栈跟踪:在 Sybase.Data.AseClient.AseDataReader.?(Int32 A_0)在 Sybase.Data.AseClient.AseDataReader.?(Boolean A_0)在 Sybase.Data.AseClient.AseDataReader.?()在 Sybase.Data.AseClient.AseDataReader.Read()在 SybaseError.Program.TestCall(String FriendlyName, String connectionString)在 C:\Projects\SybaseUpgradeError\SybaseError\Program.cs:line 42

假设您在 using 块中声明了 IDataReader/AseDataReader,当阅读器退出时,您实际上会收到以下错误引发 Read 中的原始错误时的范围:

类型:Sybase.Data.AseClient.AseException消息:内部错误:30016堆栈跟踪:在 Sybase.Data.AseClient.AseDataReader.?(Int32 A_0)在 Sybase.Data.AseClient.AseDataReader.?(Boolean A_0)在 Sybase.Data.AseClient.AseDataReader.?()在 Sybase.Data.AseClient.AseDataReader.?()在 Sybase.Data.AseClient.AseDataReader.?(Boolean A_0)在 Sybase.Data.AseClient.AseDataReader.NextResult()在 Sybase.Data.AseClient.AseDataReader.?()在 Sybase.Data.AseClient.AseDataReader.Close()在 Sybase.Data.AseClient.AseDataReader.?(Boolean A_0)在 Sybase.Data.AseClient.AseDataReader.Dispose()在 SybaseError.Program.TestCall(String FriendlyName, String connectionString)在 C:\Projects\SybaseUpgradeError\SybaseError\Program.cs:line 54

您会注意到 AseDataReaderDispose 方法正在抛出异常,这是一个很大的禁忌.更糟糕的是,如果您将异常作为 AseException 捕获并遍历 Errors 集合属性,读取这些将引发异常.显然,检查 AseError 对象的属性实际上会调用属性中的一些动态代码,尝试从活动连接中查找内容.这个版本的 Sybase .NET 客户端代码并没有给我留下特别深刻的印象.

问题归结为生产服务器上的数据包大小设置与开发和测试服务器上的不同.我没有管理员访问权限,但我相信它们在开发和测试服务器上设置为最小 2048 和最大 4096,但在生产服务器上最小和最大设置为 4096.这是基于我对电话会议的回忆,因此您的里程可能会有所不同.我只是想把它放在这里,以防以后对其他人有帮助.我们花了一段时间来追踪问题.更改最小数据包大小并重新启动生产数据库服务器确实为我们解决了问题.

如果有帮助,这里是我的测试控制台应用程序,连接字符串已删除.同样,如果取消注释,底部的注释行会抛出错误.希望能帮到你!

使用系统;使用 System.Data;使用 Sybase.Data.AseClient;命名空间 SybaseError{公开课计划{public static void Main(string[] args){const string DevelopmentConnection = "Data Source='**********';Port='****';UID='**********';PWD='**********';数据库='************';";const string ReportConnection = "更多秘密的东西";const string ProductionConnection = "还有更多秘密的东西";TestCall("开发", DevelopmentConnection);TestCall("Report", ReportConnection);TestCall("Production", ProductionConnection);Console.ReadKey();}私有静态无效测试调用(字符串友好名称,字符串连接字符串){Console.WriteLine("调用程序" +friendlyName + ".");int 记录读取 = 0;尝试{使用 (var connection = new AseConnection(connectionString)){连接.打开();使用 (var 命令 = connection.CreateCommand()){配置命令(命令);使用 (var reader = command.ExecuteReader(CommandBehavior.CloseConnection)){尝试{而 (reader.Read()){//通常会在这里阅读...记录读取++;}}捕获(异常 exRead){Console.WriteLine("读取错误:");ShowError(exRead);扔;}}}}Console.WriteLine("成功调用程序" +friendlyName + ".");}捕获(异常前){Console.WriteLine("外部错误:");ShowError(ex);Console.WriteLine("" +friendlyName + ".");}Console.WriteLine("完成对" +friendlyName + "的调用过程.读取" + recordsRead + "记录.");Console.WriteLine(string.Empty);}私有静态无效配置命令(AseCommand 命令){command.CommandText = "sp_s_eductor_route_tests";command.CommandType = CommandType.StoredProcedure;var spidParameter = new AseParameter("@spid", AseDbType.Integer);spidParameter.Value = 1355945;命令.Parameters.Add(spidParameter);var vendorIdParameter = new AseParameter("@vendor_id", AseDbType.Integer);供应商IdParameter.Value = 1;命令.Parameters.Add(vendorIdParameter);}私有静态无效 ShowError(异常前){Console.WriteLine("类型:" + ex.GetType());Console.WriteLine("消息:" + ex.Message);Console.WriteLine("StackTrace:" + ex.StackTrace);var exAse = ex as AseException;if (exAse != null){//foreach(exAse.Errors 中的 AseError 错误)//{//Console.WriteLine("SqlState: " + error.SqlState);//Console.WriteLine("State: " + error.State);//}}}}}

Database server is migrated from version 12.5x to version 15.03Sybase.Data.AseClient version - 1.15.50.0

I am getting below exception when I run few stored procedures through .Net app (using AseClient)

Internal Error :30016 Unknown Dataitem Dataitem

Stack Trace -

   at Sybase.Data.AseClient.AseDataReader.CheckResult(Int32 res)
   at Sybase.Data.AseClient.AseDataReader.RetrieveNextResult()
   at Sybase.Data.AseClient.AseDataReader.GetNextResult()
   at Sybase.Data.AseClient.AseDataReader.NextResult()
   at Sybase.Data.AseClient.AseDataReader.CloseUrsHandle()
   at Sybase.Data.AseClient.AseDataReader.Close()
   at Sybase.Data.AseClient.AseDataReader.Dispose(Boolean disposing)
   at Sybase.Data.AseClient.AseDataReader.Dispose()
   at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
   at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, String srcTable)
   at HSBC.STPMapper.SybaseDAL.Utilities.SybaseHelper.ExecuteDataset(CommandType commandType, String commandText, DataSet dataset, String table, AseParameter[] commandParameters) in C:\Utilities\SybaseHelper.cs:line 119

Note - Application was working fine before we migrated to new server.

解决方案

We were running into this issue with some code running under .NET Framework 3.5 and using Sybase.Data.AseClient.dll (version 1.1.510.0) when we upgraded our production server from 12.5 to 15. Everything worked well in the dev and test environments after upgrading, but failed in production, even though ASP classic code and PowerBuilder code was able to call the production Sybase server (big legacy system).

If I tried calling the Read method of the AseDataReader for a single record, everything was fine. But if we allowed all the records to be read, it would read only 22 out of the 67 records that would be retrieved if you invoked the stored procedure via the Sybase SQL Advandage client. I boiled it down to a toy command line app to reproduce the issue. Here are the error details that would come out of the Read:

Type: Sybase.Data.AseClient.AseException
Message: Internal Error: 30016
StackTrace:    at Sybase.Data.AseClient.AseDataReader.?(Int32 A_0)
   at Sybase.Data.AseClient.AseDataReader.?(Boolean A_0)
   at Sybase.Data.AseClient.AseDataReader.?()
   at Sybase.Data.AseClient.AseDataReader.Read()
   at SybaseError.Program.TestCall(String friendlyName, String connectionString)
 in C:\Projects\SybaseUpgradeError\SybaseError\Program.cs:line 42

Assuming that you declared your IDataReader / AseDataReader in a using block, you would actually get the following error when the reader went out of scope when the original error from the Read was thrown:

Type: Sybase.Data.AseClient.AseException
Message: Internal Error: 30016
StackTrace:    at Sybase.Data.AseClient.AseDataReader.?(Int32 A_0)
   at Sybase.Data.AseClient.AseDataReader.?(Boolean A_0)
   at Sybase.Data.AseClient.AseDataReader.?()
   at Sybase.Data.AseClient.AseDataReader.?()
   at Sybase.Data.AseClient.AseDataReader.?(Boolean A_0)
   at Sybase.Data.AseClient.AseDataReader.NextResult()
   at Sybase.Data.AseClient.AseDataReader.?()
   at Sybase.Data.AseClient.AseDataReader.Close()
   at Sybase.Data.AseClient.AseDataReader.?(Boolean A_0)
   at Sybase.Data.AseClient.AseDataReader.Dispose()
   at SybaseError.Program.TestCall(String friendlyName, String connectionString)
 in C:\Projects\SybaseUpgradeError\SybaseError\Program.cs:line 54

You'll notice that the Dispose method of the AseDataReader is throwing an exception, which is a big no-no. Even worse is that if you catch the exception as an AseException and iterate over the Errors collection property, reading those will throw exceptions. Apparently, checking the properties of an AseError object actually invokes some dynamic code in the property that tries to look things up from an active connection. I'm not particularly impressed by this version of the Sybase .NET client code.

The issue boiled down to a packet size setting that was different on the production server than on the dev and test servers. I don't have admin access, but I believe they were set to min 2048 and max 4096 on the dev and test servers but both min and max set to 4096 on the production server. That's based on my recollection of a conference call, so your mileage may vary. I just wanted to put it out here in case it helps somebody else later. It took us a while to track the problem down. Changing the minimum packet size and rebooting the production database server did fix the problem for us.

In case it helps, here's my test console app with the connection strings scrubbed. Again, the commented lines at the bottom would throw errors if uncommented. Hope this helps you!

using System;
using System.Data;
using Sybase.Data.AseClient;

namespace SybaseError
{
    public class Program
    {
        public static void Main(string[] args)
        {
            const string DevelopmentConnection = "Data Source='**********';Port='****';UID='**********';PWD='**********';Database='**********';";
            const string ReportConnection = "more secret stuff";
            const string ProductionConnection = "yet more secret stuff";

            TestCall("Development", DevelopmentConnection);
            TestCall("Report", ReportConnection);
            TestCall("Production", ProductionConnection);

            Console.ReadKey();
        }

        private static void TestCall(string friendlyName, string connectionString)
        {
            Console.WriteLine("Calling procedure on " + friendlyName + ".");

            int recordsRead = 0;

            try
            {
                using (var connection = new AseConnection(connectionString))
                {
                    connection.Open();

                    using (var command = connection.CreateCommand())
                    {
                        ConfigureCommand(command);

                        using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
                        {
                            try
                            {
                                while (reader.Read())
                                {
                                    // Would usually read things here...
                                    recordsRead++;
                                }
                            }
                            catch (Exception exRead)
                            {
                                Console.WriteLine("Error on read:");
                                ShowError(exRead);
                                throw;
                            }
                        }
                    }
                }

                Console.WriteLine("Success calling procedure on " + friendlyName + ".");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Outer error:");
                ShowError(ex);
                Console.WriteLine("Failure calling procedure on " + friendlyName + ".");
            }

            Console.WriteLine("Finished calling procedure on " + friendlyName + ".  Read " + recordsRead + " records.");
            Console.WriteLine(string.Empty);
        }

        private static void ConfigureCommand(AseCommand command)
        {
            command.CommandText = "sp_s_educator_route_tests";
            command.CommandType = CommandType.StoredProcedure;

            var spidParameter = new AseParameter("@spid", AseDbType.Integer);
            spidParameter.Value = 1355945;
            command.Parameters.Add(spidParameter);

            var vendorIdParameter = new AseParameter("@vendor_id", AseDbType.Integer);
            vendorIdParameter.Value = 1;
            command.Parameters.Add(vendorIdParameter);
        }

        private static void ShowError(Exception ex)
        {
            Console.WriteLine("Type: " + ex.GetType());
            Console.WriteLine("Message: " + ex.Message);
            Console.WriteLine("StackTrace: " + ex.StackTrace);

            var exAse = ex as AseException;

            if (exAse != null)
            {
                //foreach (AseError error in exAse.Errors)
                //{
                //    Console.WriteLine("SqlState: " + error.SqlState);
                //    Console.WriteLine("State: " + error.State);
                //}
            }
        }
    }
}

这篇关于Sybase 内部错误 30016的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 19:57