[英]SQL: Specified cast is not valid
注意:我正在尋找為什么會發生這種情況以及如何解決它,我不是在尋找解決方法。 這似乎是服務器(SQL Server或連接字符串)問題。
我有一個程序連接到一個sql 2008數據庫(數據庫A),我有內聯sql運行,其中有int和字符串返回,它工作正常。 但我被要求切換到另一個2008數據庫(數據庫B),現在一切都以字符串形式返回,我從C#獲取指定的強制轉換,當我連接到sql 2008(數據庫A)時不說這個。 這是一個內聯sql語句,因此sql語句不會更改,並且數據庫的表模式是相同的。 它在int主鍵上執行此操作任何人都有任何想法?
我原本以為這是2000年至2008年的問題,但我現在也有一些問題。 兩個數據庫都在sql server的同一個實例上,這些是連接字符串
連接字符串
Server=Server01\instance;Database=Fraud_Micah; Trusted_Connection=yes <- Server 2008 (this one does not)
Server=Server02\instance;Database=Fraud; Trusted_Connection=yes <- Server 2008 (this one works)
兩個數據庫的DB compatibility_level均為100
選擇聲明
select *, delimeter, file_filetype.LocalPath, ArchiveDir, EmailList
from file_importtable
join file_filetype on file_importtable.FileTypeID = file_filetype.ID
where importsuccessdate is null and transferdate is not null
and remotediscoverdate is not null
and OriginalFileName in ('Test987.xml.pgp')
fileTypeID
是其中斷的地方 - > InvalidCastException: Specified cast is not valid.
C#代碼(注釋閱讀器是類型SQLDataReader)
if (!(reader.IsDBNull(reader.GetOrdinal("FileTypeID"))))
{
file.FileTypeID = reader.GetInt32(reader.GetOrdinal("FileTypeID"));
}
這是列定義: [FileTypeID] [int] NULL
,表中沒有空值。
我不認為C#代碼來自於它,它是一個int? public int? FileTypeID { get; set; }
在調試模式下: reader["FileTypeID"]
- >“1”它實際上是一個字符串,但為什么當我連接到2008數據庫時它會返回1個“1”的實例
2008表A Def
[ProcessSuccessDate] [datetime] NULL,
[ProcessSuccessUser] [datetime] NULL,
[FileTypeID] [int] NULL,
[HoldDate] [datetime] NULL,
2008年表B Def
ProcessSuccessDate] [datetime] NULL,
[ProcessSuccessUser] [datetime] NULL,
[FileTypeID] [int] NULL,
[HoldDate] [datetime] NULL,
file.FileTypeID = (int)reader["FileTypeID"];
產生相同的結果。
做一個
file.FileTypeID (int)reader.GetInt32(reader.GetOrdinal("FileTypeID"));
確實有效但我不想為每一個已經應該作為int返回的列也這樣做,也寫這樣的sql
select Convert(int, FileTypeID) as FileTypeId, delimeter, file_filetype.LocalPath, ArchiveDir, EmailList
我也可以解決這個問題,但是如果我已經在表格中將類型設置為int,我想知道為什么我必須這樣做。 我不妨把所有類型作為字符串放在表中。 在這一點上,我不是在尋找一種解決方法,我想要理解為什么它不應該像它一樣工作。
您列出的兩個表都顯示int
作為數據類型,但聽起來這些是兩個不同數據庫中同一個表的兩個版本。
我相信OTHER表,你JOIN
表,在一個數據庫中有不同的數據類型。
兩個DB中File_fileType.Id
的數據類型是什么?
你的JOIN
:
join file_filetype on file_importtable.FileTypeID = file_filetype.ID
導致隱式轉換。
上圖顯示了SQL Server如何允許或執行數據類型轉換。
你能在上面的JOIN
顯示兩個版本的兩個版本的DDL嗎?
對我而言,聽起來有一些古怪的配置設置很難找到。 有一個名為Redgate SQL Compare的工具在檢測數據庫模式之間的差異方面做得非常出色。
他們進行了為期14天的試驗。 我會嘗試下載它並在您的數據庫之間進行比較。
SQL排序規則是否匹配? 如果您在數據庫之間遇到不同的行為,這可能是您的問題。 右鍵單擊每個數據庫並選擇屬性,排序規則應指定為* Latin1_General_CI_AS *如果它們不同則肯定要排除。
你必須從字符串中強制轉換。
file.FileTypeID = int.Parse((string)reader["FileTypeID"]);
編輯:如果你想要一個適用於BOTH sql server 2008和2000的解決方法
file.FileTypeID = Convert.ToInt32(reader["FileTypeID"]);
Visual Studio(根據此版本為Premium和Ultimate)附帶了一個數據庫比較工具 - 您選擇兩個數據庫,它會顯示差異並為您提供一組腳本,將一個腳本移動到另一個狀態。 從那里開始,嘗試嗅出不同的配置(因為我希望這是一個配置問題)。 在Visual Studio中查看Data \\ Schema Compare和Data \\ Data Compare。
已經確認存在至少一個錯誤。 由於我沒有整個圖像,因此很難准確。 因此,我建議兩次檢查。
第一次檢查應該在兩個數據庫上使用INFORMATION_SCHEMA.COLUMNS(對於所需級別來說已經綽綽有余)來驗證模式是否相同。 您可以在http://msdn.microsoft.com/en-us/library/aa933218(v=sql.80).aspx(SQL 2000)或http://msdn.microsoft.com/上閱讀有關INFORMATION_SCHEMA.COLUMNS的更多信息。 en-us / library / ms188348 (SQL 2008)。 來自不同來源的相同信息。
樣品:
SELECT * FROM INFORMATION_SCHEMA.COLUMNS;
如果模式相同,則代碼中可能存在一個錯誤,該錯誤在您呈現的部分中不可見。 為了確保一切都正確,您可以通過更改select語句進行簡單檢查,如下所示:
select CAST(fileTypeID as int), ..., file_filetype.LocalPath, ArchiveDir, EmailList
from file_importtable
join file_filetype on file_importtable.FileTypeID = file_filetype.ID
where importsuccessdate is null and transferdate is not null
and remotediscoverdate is not null
and OriginalFileName in ('Test987.xml.pgp')
如果失敗,則在調試模式下使用斷點和F11逐步測試。 (有時回到根源可能會幫助我們看到我們眼前看不見的東西 - 在這種情況下更不可能)。
通過以上操作,您將找到原因(希望如此)。
最后一個提示(這可能是你做其他事情之前的第一步):確保你的sql服務器使用最新的服務包進行修補。
在我希望刪除表並使用它重新創建它的方案中
[腳本表為] - > [創建]
從給我問題的同一個表中,然后重新插入所有相同的數據。 這解決了這個問題。 所以我不相信表的DML發生了變化,數據也沒有改變,但這就解決了我的問題。
看來你沒有解決這個問題,也許會嘗試使用GetSqlInt32
方法。
file.FileTypeID = reader.GetSqlInt32((fieldTypeIDOrdinal).ToNullableInt32();
請注意 ,我不包括IsDBNull
從檢查,結合SqlInt32
與ToNullableInt32
與此對應。
其中ToNullableInt32
是一種擴展方法。
public static int? ToNullableInt32(this SqlInt32 value)
{
return value.IsNull ? (int?) null : value.Value;
}
作為旁注,您提到這是一個性能優先級應用程序,在這種情況下,您可能需要預先計算您的序數值,而不是使用此reader.GetOrdinal("FileTypeID")
reader.Read()
每個循環reader.Read()
file.FileTypeID = Convert.ToInt32(reader["FileTypeID"]);
而不是 file.FileTypeID = (int)reader["FileTypeID"];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.