Sybase 内部错误 30016

Sri*_*Sri 1 stack-trace sap-ase

数据库服务器从 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

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

Dan*_*now 5

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

如果我尝试为单个记录调用AseDataReaderRead方法,则一切正常。但是,如果我们允许读取所有记录,那么如果您通过 Sybase SQL Adandage 客户端调用存储过程,它将只读取 67 条记录中的 22 条记录。我把它归结为一个玩具命令行应用程序来重现这个问题。以下是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
Run Code Online (Sandbox Code Playgroud)

假设您在using块中声明了IDataReader / AseDataReader,当引发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.?()
   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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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);
                //}
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)