注意:我正在寻找为什么会发生这种情况以及如何解决它,我不是在寻找解决方法。这似乎是服务器(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
是打破的地方 - &gt; 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"]
- &gt; “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,我想知道为什么必须这样做。我不妨把所有类型作为字符串放在表中。在这一点上,我不是在寻找一种解决方法,我想要理解为什么它不能像它那样工作。
答案 0 :(得分:9)
您列出的两个表都显示int
作为数据类型,但听起来好像是两个不同数据库中同一个表的两个版本。
我相信OTHER JOIN
的那个表在一个数据库中具有不同的数据类型。
两个数据库中File_fileType.Id
的数据类型是什么?
您的JOIN
:
join file_filetype on file_importtable.FileTypeID = file_filetype.ID
导致隐式转换。
上图显示了SQL Server如何允许或执行数据类型转换。
您能否在上面的JOIN
?
答案 1 :(得分:6)
对我而言,听起来有些古怪的配置设置很难找到。有一个名为Redgate SQL Compare的工具在检测数据库模式之间的差异时执行惊人的工作。
他们进行了为期14天的试验。我会尝试下载并运行数据库之间的比较。
答案 2 :(得分:3)
执行SQL排序规则的匹配吗?如果您在数据库之间遇到不同的行为,这可能是您的问题。右键单击每个数据库并选择属性,排序规则应指定为* Latin1_General_CI_AS *如果它们不同则肯定要排除。
答案 3 :(得分:1)
你必须从字符串中转换。
file.FileTypeID = int.Parse((string)reader["FileTypeID"]);
编辑:如果你想要一个适用于BOTH sql server 2008和2000的解决方法
file.FileTypeID = Convert.ToInt32(reader["FileTypeID"]);
答案 4 :(得分:1)
Visual Studio(版本Premium和Ultimate根据this)附带了一个数据库比较工具 - 您选择两个数据库,它会显示差异并为您提供一组脚本,将一个脚本移动到其他状态。从那里开始,尝试嗅出不同的配置(因为我希望这是一个配置问题)。在Visual Studio中查看Data \ Schema Compare和Data \ Data Compare。
答案 5 :(得分:1)
已经确认存在至少一个错误。由于我没有整个图像,因此很难准确。因此,我建议进行两次检查。
第一次检查应该在两个数据库上使用INFORMATION_SCHEMA.COLUMNS(对于所需级别来说已经绰绰有余)来验证模式是否相同。您可以在http://msdn.microsoft.com/en-us/library/aa933218(v=sql.80).aspx(SQL 2000)或http://msdn.microsoft.com/en-us/library/ms188348(SQL 2008)上阅读有关INFORMATION_SCHEMA.COLUMNS的更多信息。来自不同来源的相同信息。
样品:
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服务器。
答案 6 :(得分:1)
在我决定删除表格并使用
重新创建的方案中[script table as] - &gt; [创建]
从给我问题的同一个表中,然后重新插入所有相同的数据。这解决了这个问题。所以我不相信表的DML发生了变化,数据也没有改变,但这就解决了我的问题。
答案 7 :(得分:0)
看到你没有解决这个问题,或许可以试试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()
答案 8 :(得分:0)
file.FileTypeID = Convert.ToInt32(reader["FileTypeID"]);
而不是
file.FileTypeID = (int)reader["FileTypeID"];