【问题标题】:Stored procedure with ADO.NET - String or binary data would be truncated使用 ADO.NET 的存储过程 - 字符串或二进制数据将被截断
【发布时间】:2014-07-03 02:10:08
【问题描述】:

我有一个包含以下字段的 SQL 表(在括号中输入)

  • id (varchar(255)) 主键
  • dateStarted(日期)
  • dateFirstPayement(日期)
  • 金额(十进制)
  • numberPayments (int)
  • telNum (varchar(20)) 外键
  • VIN (varchar(255)) 外键

这些都不接受 NULL。

我正在尝试从 C# 程序中插入一些值,这是我从 WPF 表单中获取值的方式。

id
string id = textBox_id.Text;

startingDate, firstPaymentDate
DateTime startDate = Convert.ToDateTime(datePicker_startDate1.SelectedDate);
DateTime dateFirstP= Convert.ToDateTime(datePicker_firstP.SelectedDate);

telNum,NIV
string telNum = comboBox_telNum.SelectedValue.ToString();
string VIN = comboBox_VIM.SelectedValue.ToString();

金额,数字支付
Decimal amount = Convert.ToDecimal(textBox_amount.Text);
int numberPayments = Convert.ToInt32(textBox_numberPayment.Text);

这是我的 C# 代码,用于执行插入值的存储过程:

        SqlConnection connection = new SqlConnection();
        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();

        builder.DataSource = "D106213";
        builder.InitialCatalog = "ML645";
        builder.IntegratedSecurity = true;

        connection.ConnectionString = builder.ConnectionString; 
        connection.Open();

        SqlCommand newLocation = new SqlCommand("nouvelleLocation", connection);
        newLocation.CommandType = CommandType.StoredProcedure;

        newLocation.Parameters.AddWithValue("@idLocation", id);
        newLocation.Parameters.AddWithValue("@dateDebut", startDate);
        newLocation.Parameters.AddWithValue("@datePremierPaiement", dateFirstP);
        newLocation.Parameters.AddWithValue("@montantPremierPaiement", amount);
        newLocation.Parameters.AddWithValue("@nombrePaiement", numberPayments);
        newLocation.Parameters.AddWithValue("@numTel", telNum);
        newLocation.Parameters.AddWithValue("@NIV", VIN);

        newLocation.ExecuteNonQuery();

这是我尝试通过 WPF 表单插入信息时遇到的错误:

System.Data.SqlClient.SqlException (0x80131904): String or binary data would be truncated

连接到数据库的代码很好,因为它适用于我使用相同 ConnectionString 的所有其他过程。为了清楚起见,我没有将其全部发布,但它是 try/catch 块中的包装器以处理异常。

我假设 SQL 和 C# 中的数据类型是不等价的,其中一种会导致问题。我确定数据的大小(例如:字符串)不超过 SQL 中定义的最大长度。

抱歉,文本格式混乱,我是使用 StackOverflow 的新手,还没有掌握它的窍门。

非常感谢大家的帮助,祝你有美好的一天。

编辑

现在已修复。我的问题是,在存储过程中,我反转/交换了两个值(telNum 和 VIN),因此它试图在 telNum 列中插入 VIN 值。 telNum 最初只接受 VARCHAR(20),而 VIN 是 23 个字符长..

我几乎错过了,我最初将 telNum 的数据类型更改为 VARCHAR(50)(因此我没有遇到错误),但是当我收到外键错误时,我意识到出了点问题。

感谢您的大力帮助,非常感谢。

【问题讨论】:

  • 如果您确定数据没有超过最大长度。然后使用分析器查看发送到数据库的调用。您正在将日期时间传递给日期字段。这可能是个问题。
  • 尝试添加 .Trim() 看看是否解决了问题?
  • 也许问题出在您的程序上?您是否尝试使用这些参数在 sql server 端执行它?
  • 我会怀疑组合框中的值。您是否在调试模式下检查过它们?添加几个 debug.asserts 来验证检索到的字符串的长度可能是值得的。
  • 尽管您似乎确定没有一个字符串太长,但 SQL 实际上是在告诉您“其中一个字符串太长”。你只需要弄清楚哪一个比你想象的要长。您是否尝试过单步执行代码?分析 SQL 活动?

标签: c# sql sql-server


【解决方案1】:

问题在于存储过程的输入参数数据类型(如果没有发布 proc 签名很难判断),或者可能是在 C# 中将值添加到 SqlParameterCollection。

首先要检查的是 3 个字符串字段:

  • id (varchar(255))
  • telNum (varchar(20))
  • VIN (varchar(255))

在表和存储过程之间定义为相同的最大长度。 SQL Server 存储过程的一个被忽视的技术细微差别是它们默默地截断值。这意味着只要表和输入参数之间的最大长度(以及所有数据类型,真的)匹配,就不可能得到“字符串或二进制数据将被截断”错误(除非您在值进入 proc 之后但在 INSERT / UPDATE 语句之前对其进行操作)。

如果这些都匹配,那么问题就不是程序了。接下来要检查的是SqlParameterCollection 的AddWithValue 方法的使用。我记得在某处读到它在字符串长度方面并不总是按预期工作。尝试将这 3 个字段更改为传入 new SqlParameter("@idLocation", SqlDbType.VarChar, 255) 的直接 Add 调用,您可以在其中指定每个字段的确切最大长度。

【讨论】:

  • 我明确建议为您的字符串输入明确创建 SQL 参数,确保为它们提供预期的大小。
  • 谢谢,我编辑了我的代码,现在可以正常工作了。我不认为这是 AddWithValue 的问题,但我还是更改了它以避免任何进一步的问题。
【解决方案2】:

我会使用 SQL Profiler 来准确查看传递给存储过程的数据。否则很难知道哪个变量超出了预期的参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    相关资源
    最近更新 更多