【问题标题】:Data source controls and parameter type conversion数据源控件和参数类型转换
【发布时间】:2023-12-28 11:39:01
【问题描述】:



Q1 - 在下面的代码示例中,运行时在两个之间转换一个值 不兼容的类型:

  <SelectParameters>
 <asp:Parameter Name="City" Type="Int32" />
 </SelectParameters>



protected void SqlDataSource2_Selecting(object sender,
       SqlDataSourceSelectingEventArgs e)
{e.Command.Parameters["@City"].Value = "100";}

我得到的异常:

“将 nvarchar 值 'Seattle' 转换为 数据类型 int。”

A) 上述异常表明运行时确实设法将 String 类型的值转换为 Int32 类型的值,因此 SqlServer 发生异常?!

B) 既然 String 和 Int32 是不兼容的类型,为什么 runtime 首先执行从String到Int32的转换?

我们正在处理不兼容类型的事实难道不是 运行时“意识到”该应用程序很可能存在错误,类似于方式 编译器“意识到”它正在处理(在下面的代码中)两个 不兼容的类型:

String s = ”something”;
int i = (int)s; //error



第二季度:

一) public void GetEmployee(int EmployeeID);

<asp:ObjectDataSource  SelectMethod=”GetEmployee” …>
  <SelectParameters>
    <asp:ControlParameter Name = ”EmployeeID” ...>
  </SelectParameters>


如果出于某种原因 EmployeeID 参数为 NULL,则 ObjectDataSource 将 Null 转换为零并将其作为参数传递给 GetEmployee() 方法。

为什么运行时会进行这样的转换?不会扔 例外更有意义?

B) “使用 ConvertEmptyStringToNull 属性来指定是否 空字符串值在数据时自动转换为null 字段在数据源中更新。”
我不太明白这个属性的用处。为什么会 空字符串表示我们希望将 null 插入到源的 数据字段?我假设这个数据字段是字符串类型的?然后 为什么不也有 ConvertZeroInt32ToNull 等?

第三季度:

<asp:SqlDataSource ID="sourceEmployees" runat="server"
     ProviderName="System.Data.SqlClient"
     ConnectionString="<%$ ConnectionStrings:Northwind %>"
     SelectCommand="SELECT EmployeeID, FirstName,LastName,
     Title, City FROM Employees WHERE City=@City">
         <SelectParameters>
             <asp:Parameter Name="City"/>
         </SelectParameters>
</asp:SqlDataSource> 

A) 我假设当你没有指定参数的类型时 实例“City”是,它自动属于 Object 类型,这意味着它 以后可以分配任何类型的值。因此,如果“City”在后面(比如说 在 SqlDataSource2_Selecting() 事件处理程序中)分配了一个值 一个错误的类型,这个错误的赋值只会在Sql上检测到 服务器,而不是之前(当然Sql server会报告那个错误 返回网络服务器)?

B) 如果我们创建一个 NVarChar(20) 类型的 SqlParameter 实例并且想要 要将这个参数传递给一个存储过程,将 Ado.net 传递给一个 存储过程只是这个参数的值,还是会它也 以某种方式通知程序此参数的确切类型( 是 NVarChar(20))?

感谢

【问题讨论】:

  • 看在上帝的份上,请把这些问题分开!
  • 我认为在一个线程中有多个问题比在多个线程中发送垃圾论坛更可取?但如果这能让我得到更多回复,我会把它们分开

标签: c# asp.net sql sql-server ado.net


【解决方案1】:

这是一个 SQL Server 错误。您遇到了datatype precedence 问题。

线索在这里:

SELECT EmployeeID, FirstName,LastName, Title, City FROM Employees WHERE
City=@City --here exactly

城市列是 nvarchar 该参数显式设置为 int

把它们加在一起,你得到:

SELECT EmployeeID, FirstName,LastName, Title, City FROM Employees WHERE
City=100

根据数据类型优先规则,数据库引擎尝试将 City 的所有值更改为“int”。当然失败了。

不过,为了您的观点:

  • Q1:同样的问题。你没有告诉 SQL Server “100”应该是字符串
  • Q2:空字符串在 SQL 中强制转换为零。如果您想要 SQL 空值,请发送 dbnull.value
  • Q3a。 SQL 没有对象数据类型。它查看 100 并决定“int”
  • Q3b。是的,使用存储过程并正确定义它。

总体而言,SQL Server 的行为与宣传的完全一样。在这种情况下,您根本没有提供足够的信息。

编辑:存储过程的使用

您在将参数添加到参数集合时告诉 SQL 数据类型是什么。您定义(并创建)存储过程以具有 nvarchar 参数。

【讨论】:

  • > Q3b。是的,使用存储过程并正确定义它。是的,因为在 Ado.net 中只会将参数的值传递给 sql server 还是会通知 sql server 这个参数的确切类型?
  • > Q3b。是的,使用存储过程并正确定义它。 是的,因为在 Ado.net 中只会将参数的值传递给 sql server 还是会通知 sql server 该参数的确切类型?
【解决方案2】:

我会试着回答你的第一个问题—— “将 nvarchar 值 'Seattle' 转换为数据类型 int 时转换失败。”

由于我没有在任何地方看到“西雅图”,我猜这个错误实际上是来自你正在调用的存储过程——即。无论您在 proc 中使用 @City 是什么,都是问题所在。听起来你不是在做“where CityID=@City”之类的事情,而是在做“where CityName=@City”,它抱怨它不能将 CityName(“Seattle”)的值之一转换为将其与@City 进行比较的整数。

【讨论】:

    【解决方案3】:

    我猜这个错误实际上来自你正在调用的存储过程——即。无论您在 proc 中使用 @City 是什么,都是问题所在。听起来你不是在做“where CityID=@City”之类的事情,而是在做“where CityName=@City”,它抱怨它不能将 CityName(“Seattle”)的值之一转换为与@City 进行比较的整数。

    我故意使用不兼容的类型只是为了表达我的观点——>这就是'为什么运行时甚至会费心尝试将一个值从一种不兼容的类型转换为另一种,因为用户将字符串分配给类型的变量整数,表明它很可能是一个错误,而不是用户故意做的事情?

    【讨论】:

    • 您可以编辑您的帖子和/或评论 Jonathan Rupp 的帖子。
    最近更新 更多