我正在嘗試使用 IfxDataReader 從 IBM 資料庫中獲取資料,如下所示:
Using myCon As New IfxConnection("CONSTRING")
Dim myQuery = "SELECT decimalValue FROM exampletable"
Using myCmd As New IfxCommand(myQuery, myCon)
myCon.Open()
Using myReader As IfxDataReader = myCmd.ExecuteReader
While myReader.Read
' error occurs below
Dim myVariable As Double = myReader("decimalValue")
End While
End Using
End Using
End Using
我收到一個 System.FormatException 在myReader("decimalValue")。在除錯期間將滑鼠懸停在這段代碼上,也會顯示這個例外,甚至在執行代碼行之前。該例外具有以下堆疊跟蹤。
在 System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
在 System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
在 IBM.Data.Informix.IfxDataReader.GetSytemTypeFromCacheType(Type systemType, Type cacheEntryType, Object cacheEntry)
at IBM.Data.Informix.IfxDataReader.GetValue(Int32 i)
at IBM.Data.Informix.IfxDataReader.get_Item(String value)
我Imports IBM.Data.Informix在我的檔案中使用并在我的專案中參考了同名的 DLL。DLL 的檔案版本為4.0.1000.2,其產品版本為4.00.01000.2.
我發現了這個看起來相似的問題,但是在這里檢查提到的框并沒有解決問題。Dim b As Integer = Integer.Parse("1") 導致“System.FormatException:'輸入字串的格式不正確。'”
顯然這個問題只發生在我自己的電腦上。我已經在我的兩位同事的計算機以及我們的一臺服務器上執行了完全相同的代碼,但他們都沒有遇到問題。
起初我認為它有事可做,因為我沒有安裝 Informix Client SDK,因為我在 ibm.com 上發現了一個類似的問題,建議更新 SDK: https ://www.ibm.com/support/pages /apar/IC60254 但是在安裝了SDK之后它仍然沒有作業,我還發現它可以在一個沒有安裝SDK的同事的PC上作業。因此,我很困惑,不知道為什么會出現這個問題,為什么只對我來說。
有沒有人有線索,可能是什么導致了這個錯誤?
uj5u.com熱心網友回復:
擴展 G3nt_M3caj 所說的內容。
某些資料型別(如十進制或日期)的格式取決于您的本地化設定(語言/地區)。在英語(美國)中,小數點分隔符是“.”。(千是一個“,”)但在其他語言(和地區)中它們可能會有所不同。相反,在意大利語或西班牙語中,“,”表示十進制,“。” 為數千人。
.NET 將使用 Windows 中的默認設定,但您可以使用 System.Globalization.CultureInfo 覆寫它。
但是,對于 Informix 客戶端(如 .NET 和 ODBC),還有其他設定可以控制客戶端如何將資料回傳給應用程式。例如, CLIENT_LOCALE用于指定您希望驅動程式(在本例中為 .NET)將資料回傳給應用程式的語言、區域和代碼集。
如果您不指定 CLIENT_LOCALE,它將采用默認的“EN_US.1252”(Windows 上為 1252,這因平臺而異)這意味著驅動程式將“期望”EN_US 格式的小數(“.”和“,” ) 如果您的 Windows 機器沒有使用相同的設定,則在嘗試從資料庫中獲取小數時會出錯(這同樣適用于日期時間)
看下面的例子:
// ---- dec2.cs ----
// compile with: csc.exe /R:%INFORMIXDIR%\bin\netf40\IBM.Data.Informix.dll /nologo dec2.cs
//
using System;
using System.IO;
using System.Data;
using System.Text;
using System.Threading;
using IBM.Data.Informix;
class sample {
static void Main(string[] args) {
IfxConnection conn;
try {
//conn = new IfxConnection("Server=ids1410;Database=sysmaster;CLIENT_LOCALE=en_US.1252");
conn = new IfxConnection("Server=ids1410;Database=sysmaster;CLIENT_LOCALE=it_IT.1252");
Console.WriteLine(conn.ConnectionString);
conn.Open();
IfxCommand cmmd = conn.CreateCommand();
cmmd.CommandText = "SELECT 1.234 from table (set{1}) ";
Console.WriteLine(cmmd.CommandText);
IfxDataReader drdr;
drdr = cmmd.ExecuteReader();
drdr.Read();
Console.WriteLine("System.Globalization.CultureInfo(\"en-US\")");
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
try {
Console.WriteLine("\tGetDecimal (en-US):\t" drdr.GetDecimal(0));
}
catch (Exception e) {
Console.WriteLine("\t" e.Message);
Console.WriteLine("\t" e.StackTrace);
}
Console.WriteLine("System.Globalization.CultureInfo(\"it-IT\")");
Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("it-IT");
try {
Console.WriteLine("\tGetDecimal (it-IT):\t" drdr.GetDecimal(0));
}
catch (Exception e) {
Console.WriteLine("\t" e.Message);
Console.WriteLine("\t" e.StackTrace);
}
conn.Close();
}
catch (Exception e) {
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
}
// ---- dec2.cs ----
如果您使用默認的 en_US.1252 運行它,則只有在 CultureInfo 設定為“en-US”時才能執行 GetDecimal(),因為十進制格式必須匹配(客戶端回傳的用途和 .net 期望的內容)。
d:\Infx\work\cs>dec2
Server=ids1410;Database=sysmaster;CLIENT_LOCALE=en_US.1252
SELECT 1.234 from systables
System.Globalization.CultureInfo("en-US")
GetDecimal (en-US): 1.234
System.Globalization.CultureInfo("it-IT")
Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
at IBM.Data.Informix.IfxDataReader.GetDecimal(Int32 i)
at sample.Main(String[] args)
d:\Infx\work\cs>
如果您將設定更改為“it-IT”(意大利語/意大利),它將失敗,您在原始帖子中提到的例外情況。因為他們不會匹配。.NET 需要一個“1,234”,但它得到一個“1.234”
如果您更改連接字串中的 CLIENT_LOCALE 值,則相反:
d:\Infx\work\cs>dec2
Server=ids1410;Database=sysmaster;CLIENT_LOCALE=it_IT.1252
SELECT 1.234 from systables
System.Globalization.CultureInfo("en-US")
Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
at IBM.Data.Informix.IfxDataReader.GetDecimal(Int32 i)
at sample.Main(String[] args)
System.Globalization.CultureInfo("it-IT")
GetDecimal (it-IT): 1,234
d:\Infx\work\cs>
此鏈接討論了這一點(與 .NET 相關),但它可能會變得更復雜一些,因為還有其他 Informix 設定可以改變它,比如 DBMONEY。DBMONEY 可用于指定十進制格式,而無需指定 CLIENT_LOCALE(因此不會影響代碼集順序等其他內容)。
uj5u.com熱心網友回復:
這里的問題可能有兩個:
- 價值總是被重視的嗎?可能是 Nothing 或 DbNull?
- 您的 PC/機器是否與您的同事使用相同的區域設定/語言?
希望它是這兩個問題之一,此代碼將有助于解決您的問題。您必須設定存盤資料的正確“默認小數分隔符”以及正確的語言/iso代碼來轉換/格式化它(在我的SO是意大利語中,意味著存盤的資料有“,”作為小數分隔符和語言/iso -代碼是“it-IT”)
讓我們知道這是否解決了:)
Private Function ConvertToDecimal(ByVal value As Object) As Decimal
If value Is DBNull.Value Then Return 0
If value Is Nothing Then Return 0
Dim dValue As String = CStr(value)
'Specify here the default decimal separator and locale that data was stored before
Dim localeDefaultSeparator As String = ","
Dim localeDefaultCultureId As String = "it-IT"
Dim separators As String = System.Text.RegularExpressions.Regex.Replace(dValue, "[0-9]", "")
Dim decimalseparator As String = ""
If Not String.IsNullOrEmpty(separators) Then decimalseparator = Char.ToString(separators.Last())
Dim style As System.Globalization.NumberStyles = System.Globalization.NumberStyles.AllowDecimalPoint Or System.Globalization.NumberStyles.AllowThousands
Dim provider As System.Globalization.CultureInfo = If(Not String.IsNullOrEmpty(decimalseparator) AndAlso decimalseparator = localeDefaultSeparator, New System.Globalization.CultureInfo(localeDefaultCultureId), System.Globalization.CultureInfo.InvariantCulture)
Dim retValue As Decimal
If Decimal.TryParse(dValue, style, provider, retValue) Then Return retValue
Return 0
End Function
用法:
Dim myVariable As Double = ConvertToDecimal(myReader("decimalValue"))
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/490845.html
上一篇:(VB.NET)有沒有辦法在Win7中檢查Windows安全更新?
下一篇:構建訊息
