C#:通过ODBC读取数据算术溢出
C#: arithmetic overflow by reading data via ODBC
在我的实际项目中,我正在从 Filemaker v14 数据库中读取数据。
我得到这样的数据:
command.CommandText = "SELECT * FROM CAR";
//Create new SqlDataReader object and read data from the command.
using (OdbcDataReader reader = command.ExecuteReader())
{
/*
* Get and cast the ID
*/
int counter = 0;
while (reader.Read() && counter < numberOfOrders)
{
SalesOrder s = new SalesOrder();
s.abNR = reader["Auftrags Nr."].ToString();
s.artNr = reader["Artikel nr."].ToString();
s.quantity = reader["Menge"].ToString();
s.city_country_Coustomer = reader["Stadt"].ToString();
}
}
此代码 运行 在我正在开发的计算机上完美无缺。
如果我将我的项目放入 IIS,则会出现此错误:
Arithmetic operation resulted in an overflow.
这一行:s.abNR = reader["Auftrags Nr."].ToString();
我已经检查了我的计算机和服务器上的 dsn。两者似乎是一样的。
连接是这样创建的:
conn = new OdbcConnection("DSN=FILEMAKER1;Uid=Test;Pwd=tset");
conn.Open();
command = conn.CreateCommand();
期待您的回答!
编辑:
这是我的销售订单-Class:
public class SalesOrder
{
public string abNR { get; set; }
public string artNr { get; set; }
public string quantity { get; set; }
public string city_country_Coustomer { get; set; }
}
编辑 2:
销售订单的示例数据:
Aufrags Nr. | Artikel nr. | Menge | Stadt |
------------+-------------+-------+---------+
168953 | 508800 | 2 | Berlin |
------------+-------------+-------+---------+
167996 | 508850 | 4 | München |
------------+-------------+-------+---------+
FF8957 | 509010 | 1 | Berlin |
编辑 3:
[OverflowException: Die arithmetische Operation hat einen Überlauf
verursacht.] System.Data.Odbc.OdbcDataReader.GetSqlType(Int32 i)
+359 System.Data.Odbc.OdbcDataReader.GetValue(Int32 i) +57 System.Data.Odbc.DbCache.AccessIndex(Int32 i) +82
System.Data.Odbc.OdbcDataReader.GetValue(Int32 i) +38
Produktionscockpit.SQL.FilemakerController.getActualSalesOrders(Int32
numberOfOrders) in
c:\Dev\ProductionCockpit\Produktionscockpit\SQL\FilemakerController.cs:56
Produktionscockpit.Home.addSalesOrderTabelContent() in
c:\Dev\ProductionCockpit\Produktionscockpit\default.aspx.cs:79
Produktionscockpit.Home.Page_Load(Object sender, EventArgs e) in
c:\Dev\ProductionCockpit\Produktionscockpit\default.aspx.cs:21
System.Web.UI.Control.LoadRecursive() +116
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
+2910
如果您收到 ArithmeticOverflow
,这听起来像是 .NET 无法确定您的 Aufttrags Nr.
列的类型并且猜测不正确。
如果此列是 Number
则 there are a wide range of .NET data types that it could map to :
您可能会考虑在将其作为字符串输出之前通过 Convert.ToInt64()
方法将其显式读取为 Int64
:
s.abNR = Convert.ToInt64(reader["Auftrags Nr."]).ToString();
或者如果您希望该值为 floating-point 数字,您可以尝试通过 Convert.ToDecimal()
方法使用 Decimal
:
s.abNR = Convert.ToDecimal(reader["Auftrags Nr."]).ToString();
关于连接
由于您的问题标题明确询问有关连接到 FileMaker 数据库的问题,因此您可以查看 ensure that your connection string is correct here 和下面的 Filemaker Pro 连接字符串示例:
Driver=FileMaker Pro;AllAsText=0;ApplicationUsingThreads=1;FetchChunkSize=100;
FileOpenCache=0;IntlSort=0;MaxTextlength=255;ServerAddress=127.0.0.1;
TranslationOption=0;UseRemoteConnection=1;
尽管您的主要问题似乎与连接无关。
您提供的堆栈跟踪 System.Data.Odbc.OdbcDataReader.GetSqlType(Int32 i)
让我得出结论,问题是 TEXT 类型确实被 ODBC GetSqlType 识别。不同版本的 ODBC 驱动程序或其默认设置可能会导致行为差异。检查两个环境中的版本和设置。
作为解决方法,您可以尝试将您的字段转换为某些已知类型。例如,
SELECT CAST(C.[Aufrags Nr.] as NVARCHAR(MAX)) as [Aufrags Nr.], .... FROM CAR C
根据您查询的 SQL 服务器(或 ODBC 源)选择适当的列类型。
我曾经遇到过几乎类似的问题,在尝试了很多事情(例如转换为 long 等)之后,这终于解决了我的问题,尽管我不确定它是如何解决的?
abNR = reader["Auftrags Nr."] + "";
我用 + "" 替换了 ToString();
我阅读了一些相关内容,32 位和 64 位之间的连接存在问题。您的应用程序是否针对 x86 进行编译?假设您使用的是 32 位 ODBC 数据源。
根据我在遇到同样问题的其他人身上看到的情况(我从未遇到过这种情况),您可以通过将应用程序移动到 32 位(如果数据源是 32 位)或有人卸载 64-位版本的 filemaker 并安装了 32 位。
这可能是问题所在,但由于我不了解您的环境,因此无法真正为您提供合适的解决方案。
64 位 ODBC DSN 有一些问题我刚刚通过 运行 C:\WINDOWS\SYSWOW64\odbc32.exe
在 64 位 Windows 上创建了 32 位 DSN,而不是默认的 ODBC 工具。工作正常。
您的列命名约定可能有问题:为此请将您的查询更改为此
command.CommandText = "SELECT *, [Auftrags Nr.] as AuftragsNr, [Artikel nr.] as ArtikelNr FROM CAR";
//Create new SqlDataReader object and read data from the command.
using (OdbcDataReader reader = command.ExecuteReader())
{
int counter = 0;
while (reader.Read() && counter < numberOfOrders)
{
SalesOrder s = new SalesOrder();
s.abNR = reader["AuftragsNr"].ToString();
s.artNr = reader["ArtikelNr"].ToString();
s.quantity = reader["Menge"].ToString();
s.city_country_Coustomer = reader["Stadt"].ToString();
}
}
ODBC 驱动程序将名为 AuftragsNr 的列的数据类型确定为 int,但在第 3 行失败。尝试使用 GetString 方法。
在我的实际项目中,我正在从 Filemaker v14 数据库中读取数据。 我得到这样的数据:
command.CommandText = "SELECT * FROM CAR";
//Create new SqlDataReader object and read data from the command.
using (OdbcDataReader reader = command.ExecuteReader())
{
/*
* Get and cast the ID
*/
int counter = 0;
while (reader.Read() && counter < numberOfOrders)
{
SalesOrder s = new SalesOrder();
s.abNR = reader["Auftrags Nr."].ToString();
s.artNr = reader["Artikel nr."].ToString();
s.quantity = reader["Menge"].ToString();
s.city_country_Coustomer = reader["Stadt"].ToString();
}
}
此代码 运行 在我正在开发的计算机上完美无缺。
如果我将我的项目放入 IIS,则会出现此错误:
Arithmetic operation resulted in an overflow.
这一行:s.abNR = reader["Auftrags Nr."].ToString();
我已经检查了我的计算机和服务器上的 dsn。两者似乎是一样的。
连接是这样创建的:
conn = new OdbcConnection("DSN=FILEMAKER1;Uid=Test;Pwd=tset");
conn.Open();
command = conn.CreateCommand();
期待您的回答!
编辑:
这是我的销售订单-Class:
public class SalesOrder
{
public string abNR { get; set; }
public string artNr { get; set; }
public string quantity { get; set; }
public string city_country_Coustomer { get; set; }
}
编辑 2:
销售订单的示例数据:
Aufrags Nr. | Artikel nr. | Menge | Stadt |
------------+-------------+-------+---------+
168953 | 508800 | 2 | Berlin |
------------+-------------+-------+---------+
167996 | 508850 | 4 | München |
------------+-------------+-------+---------+
FF8957 | 509010 | 1 | Berlin |
编辑 3:
[OverflowException: Die arithmetische Operation hat einen Überlauf verursacht.] System.Data.Odbc.OdbcDataReader.GetSqlType(Int32 i) +359 System.Data.Odbc.OdbcDataReader.GetValue(Int32 i) +57 System.Data.Odbc.DbCache.AccessIndex(Int32 i) +82
System.Data.Odbc.OdbcDataReader.GetValue(Int32 i) +38
Produktionscockpit.SQL.FilemakerController.getActualSalesOrders(Int32 numberOfOrders) in c:\Dev\ProductionCockpit\Produktionscockpit\SQL\FilemakerController.cs:56 Produktionscockpit.Home.addSalesOrderTabelContent() in c:\Dev\ProductionCockpit\Produktionscockpit\default.aspx.cs:79
Produktionscockpit.Home.Page_Load(Object sender, EventArgs e) in c:\Dev\ProductionCockpit\Produktionscockpit\default.aspx.cs:21
System.Web.UI.Control.LoadRecursive() +116
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2910
如果您收到 ArithmeticOverflow
,这听起来像是 .NET 无法确定您的 Aufttrags Nr.
列的类型并且猜测不正确。
如果此列是 Number
则 there are a wide range of .NET data types that it could map to :
您可能会考虑在将其作为字符串输出之前通过 Convert.ToInt64()
方法将其显式读取为 Int64
:
s.abNR = Convert.ToInt64(reader["Auftrags Nr."]).ToString();
或者如果您希望该值为 floating-point 数字,您可以尝试通过 Convert.ToDecimal()
方法使用 Decimal
:
s.abNR = Convert.ToDecimal(reader["Auftrags Nr."]).ToString();
关于连接
由于您的问题标题明确询问有关连接到 FileMaker 数据库的问题,因此您可以查看 ensure that your connection string is correct here 和下面的 Filemaker Pro 连接字符串示例:
Driver=FileMaker Pro;AllAsText=0;ApplicationUsingThreads=1;FetchChunkSize=100;
FileOpenCache=0;IntlSort=0;MaxTextlength=255;ServerAddress=127.0.0.1;
TranslationOption=0;UseRemoteConnection=1;
尽管您的主要问题似乎与连接无关。
您提供的堆栈跟踪 System.Data.Odbc.OdbcDataReader.GetSqlType(Int32 i)
让我得出结论,问题是 TEXT 类型确实被 ODBC GetSqlType 识别。不同版本的 ODBC 驱动程序或其默认设置可能会导致行为差异。检查两个环境中的版本和设置。
作为解决方法,您可以尝试将您的字段转换为某些已知类型。例如,
SELECT CAST(C.[Aufrags Nr.] as NVARCHAR(MAX)) as [Aufrags Nr.], .... FROM CAR C
根据您查询的 SQL 服务器(或 ODBC 源)选择适当的列类型。
我曾经遇到过几乎类似的问题,在尝试了很多事情(例如转换为 long 等)之后,这终于解决了我的问题,尽管我不确定它是如何解决的?
abNR = reader["Auftrags Nr."] + "";
我用 + "" 替换了 ToString();
我阅读了一些相关内容,32 位和 64 位之间的连接存在问题。您的应用程序是否针对 x86 进行编译?假设您使用的是 32 位 ODBC 数据源。
根据我在遇到同样问题的其他人身上看到的情况(我从未遇到过这种情况),您可以通过将应用程序移动到 32 位(如果数据源是 32 位)或有人卸载 64-位版本的 filemaker 并安装了 32 位。
这可能是问题所在,但由于我不了解您的环境,因此无法真正为您提供合适的解决方案。
64 位 ODBC DSN 有一些问题我刚刚通过 运行 C:\WINDOWS\SYSWOW64\odbc32.exe
在 64 位 Windows 上创建了 32 位 DSN,而不是默认的 ODBC 工具。工作正常。
您的列命名约定可能有问题:为此请将您的查询更改为此
command.CommandText = "SELECT *, [Auftrags Nr.] as AuftragsNr, [Artikel nr.] as ArtikelNr FROM CAR";
//Create new SqlDataReader object and read data from the command.
using (OdbcDataReader reader = command.ExecuteReader())
{
int counter = 0;
while (reader.Read() && counter < numberOfOrders)
{
SalesOrder s = new SalesOrder();
s.abNR = reader["AuftragsNr"].ToString();
s.artNr = reader["ArtikelNr"].ToString();
s.quantity = reader["Menge"].ToString();
s.city_country_Coustomer = reader["Stadt"].ToString();
}
}
ODBC 驱动程序将名为 AuftragsNr 的列的数据类型确定为 int,但在第 3 行失败。尝试使用 GetString 方法。