首页 > 解决方案 > SQL Server 客户端字符串到(强制)整数转换问题

问题描述

好的,我正在使用 VB.net 并添加了一个 SQL Server 连接(.mdf文件)和一个表。我已将输入类型从 int 更改为 varchar(和其他)以处理拆分邮政编码(即“101 00”,而不是“339022”)。

无论如何,现在我的表将不接受插入查询中的字符串变量,因为它告诉我 SQL Server 表需要一个整数。我已经更新了这些信息并刷新了它。不太确定我需要更改或执行此操作才能单击。我尝试了不同的变量,关闭,重新打开等。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

我尝试重建我的查询但没有运气。这是我在打开 option strict 后遇到的错误。此异常最初是在此调用堆栈中引发的:

System.Number.StringToNumber(string, System.Globalization.NumberStyles, ref System.Number.NumberBuffer, System.Globalization.NumberFormatInfo, bool)  
System.Number.ParseInt32(string, System.Globalization.NumberStyles, System.Globalization.NumberFormatInfo)   
string.System.IConvertible.ToInt32(System.IFormatProvider)  
System.Data.Common.Int32Storage.Set(int, object)   
System.Data.DataColumn.this[int].set(int, object)   

标签: sqlvb.nettype-conversion

解决方案


你有一个数据库,它有一个带有一些数字列的表:

TblAddress
--------
Street Varchar
PostalCode int

您编写(或 Visual Studio 编写)一些代码将数据放入列中。现在还不清楚您使用什么方法来访问这个数据库,但这并不重要——这个概念将保持不变。我猜它是直接插入查询,即你写了这样的东西:

Dim cmd As New SqlCommand("INSERT INTO tblAddress VALUES(@street, @postalcode", "some connection string here")
cmd.Parameters.Add("@street", SqlDbType.Varchar).Value = "Microsoft way"
cmd.Parameters.Add("@postalcode", SqlDbType.Integer).Value = 339022

等等。或者,您可能正在使用 DataSet(您的解决方案资源管理器中有一个名为 Something.XSD 的文件),当您双击它时,您会看到一些看起来像 db 的东西。重要的是要记住,DataSet 是一个客户端容器,它具有用于存储数据的数据表和用于在数据集和真实 db 之间推送数据的 tableadapter - 它可以参考 db 位创建,它不是 db,它可以发散- 一个数据表的列可以比它所关联的数据库中的表多或少,等等。所以你将被设置为一个 int 列

或者你可能正在使用实体框架,它就像数据集一样是一套客户端代码,可以在数据库上建模,但它可以发散


这里的关键点是,如果您最初在 db 表上有一个 int 列,并且您创建了针对 int 的客户端代码,那么如果您稍后更改 db 类型,则不会自动更新客户端代码。如果您直接使用插入,则必须更改参数的 SqlDbType。如果您使用的是 DataSet,则必须打开数据集,找到列并更新其类型。如果您使用的是 EF,您会找到您的客户端类实体并更新属性的类型

TLDR:即使您更改了数据库类型,您还需要在代码中进行另一项更改


一个可能让你绊倒的主要事情是 vb.net option strict 关闭。VB 语言变体的默认设置长期以来一直针对那些不一定知道或关心数字和包含数字字符的字符串之间的区别的业余程序员。它允许以下内容:

Dim i as Integer = "123"

“123”是一个字符串,而不是一个整数,存在转换的可能性,但前提是字符串中没有任何废话。默认情况下,如果您执行类似这样的操作,VB 会隐式地为您进行转换,这并不是一个好主意。通过不强迫开发人员在设计时考虑转换,这意味着他们也没有考虑在转换期间会发生的错误,也没有为它们编写任何处理。

单击您的项目属性,然后在编译器选项中打开每个具有 On 的选项。您可能会看到突然出现数十个错误,但答案不是再次关闭该选项,而是正确修复错误

它不会捕获所有内容,例如 DbParameter.Value是一个对象,它仍然会接受带有空格的邮政编码字符串,并且如果您将参数类型声明为某个数字,则会在内部失败,但请始终注意您的数据类型和不将它们视为同义词将解决很多头痛


推荐阅读