我运行data.bat文件与以下行:

Rem Tis batch file will populate tables

cd\program files\Microsoft SQL Server\MSSQL
osql -U sa -P Password -d MyBusiness -i c:\data.sql

数据的内容。SQL文件是:

   insert Customers
            (CustomerID, CompanyName, Phone)
             Values('101','Southwinds','19126602729')

还有8个类似的行用于添加记录。

当我运行这个开始>运行> cmd > c:\data.bat,我得到这个错误信息:

1>2>3>4>5>....<1 row affected>
Msg 8152, Level 16, State 4, Server SP1001, Line 1
string or binary data would be truncated.

<1 row affected>

<1 row affected>

<1 row affected>

<1 row affected>

<1 row affected>

<1 row affected>

此外,我显然是一个新手,但级别#和状态#意味着什么,我如何查找错误消息,如上面的一个:8152?


当前回答

也有这个问题发生在web应用程序表面。 最终发现相同的错误消息来自特定表中的SQL更新语句。

最后发现在某些特定情况下,相关历史表中的列定义没有映射nvarchar类型的原始表列长度。

其他回答

也有这个问题发生在web应用程序表面。 最终发现相同的错误消息来自特定表中的SQL更新语句。

最后发现在某些特定情况下,相关历史表中的列定义没有映射nvarchar类型的原始表列长度。

有些数据无法放入数据库列中(小)。要发现哪里有问题并不容易。如果你使用c#和Linq2Sql,你可以列出将被截断的字段:

首先创建helper类:

public class SqlTruncationExceptionWithDetails : ArgumentOutOfRangeException
{
    public SqlTruncationExceptionWithDetails(System.Data.SqlClient.SqlException inner, DataContext context)
        : base(inner.Message + " " + GetSqlTruncationExceptionWithDetailsString(context))
    {
    }

    /// <summary>
    /// PArt of code from following link
    /// http://stackoverflow.com/questions/3666954/string-or-binary-data-would-be-truncated-linq-exception-cant-find-which-fiel
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    static string GetSqlTruncationExceptionWithDetailsString(DataContext context)
    {
        StringBuilder sb = new StringBuilder();

        foreach (object update in context.GetChangeSet().Updates)
        {
            FindLongStrings(update, sb);
        }

        foreach (object insert in context.GetChangeSet().Inserts)
        {
            FindLongStrings(insert, sb);
        }
        return sb.ToString();
    }

    public static void FindLongStrings(object testObject, StringBuilder sb)
    {
        foreach (var propInfo in testObject.GetType().GetProperties())
        {
            foreach (System.Data.Linq.Mapping.ColumnAttribute attribute in propInfo.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), true))
            {
                if (attribute.DbType.ToLower().Contains("varchar"))
                {
                    string dbType = attribute.DbType.ToLower();
                    int numberStartIndex = dbType.IndexOf("varchar(") + 8;
                    int numberEndIndex = dbType.IndexOf(")", numberStartIndex);
                    string lengthString = dbType.Substring(numberStartIndex, (numberEndIndex - numberStartIndex));
                    int maxLength = 0;
                    int.TryParse(lengthString, out maxLength);

                    string currentValue = (string)propInfo.GetValue(testObject, null);

                    if (!string.IsNullOrEmpty(currentValue) && maxLength != 0 && currentValue.Length > maxLength)
                    {
                        //string is too long
                        sb.AppendLine(testObject.GetType().Name + "." + propInfo.Name + " " + currentValue + " Max: " + maxLength);
                    }

                }
            }
        }
    }
}

然后为SubmitChanges准备包装器:

public static class DataContextExtensions
{
    public static void SubmitChangesWithDetailException(this DataContext dataContext)
    {
        //http://stackoverflow.com/questions/3666954/string-or-binary-data-would-be-truncated-linq-exception-cant-find-which-fiel
        try
        {
            //this can failed on data truncation
            dataContext.SubmitChanges();
        }       
        catch (SqlException sqlException) //when (sqlException.Message == "String or binary data would be truncated.")
        {

            if (sqlException.Message == "String or binary data would be truncated.") //only for EN windows - if you are running different window language, invoke the sqlException.getMessage on thread with EN culture
                throw new SqlTruncationExceptionWithDetails(sqlException, dataContext);
            else
                throw;
        }
    }
}

准备全局异常处理程序和日志截断细节:

protected void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    string message = ex.Message;
    //TODO - log to file
}

最后使用代码:

Datamodel.SubmitChangesWithDetailException();

我有这个问题,尽管数据长度比字段长度短。 事实证明,问题在于有另一个日志表(用于审计跟踪),由主表上的触发器填充,其中的列大小也必须更改。

这种错误可能发生的另一种情况是 SQL Server Management Studio。如果你的表中有"text"或"ntext"字段, 不管你要更新什么类型的字段(例如位或整数)。 似乎工作室不加载整个“ntext”字段,也更新所有字段,而不是修改的字段。 要解决这个问题,请从Management Studio的查询中排除“text”或“ntext”字段

只是想提供额外的信息:我也有同样的问题,这是因为字段对传入的数据不够大,这个线程帮助我解决了这个问题(上面的答案澄清了一切)。

但是,了解可能导致它的可能原因是非常重要的。

在我的情况下,我创建了一个字段像这样的表:

Select '' as  Period, * From Transactions Into #NewTable

因此,字段“Period”的长度为零,导致插入操作失败。我将其更改为“XXXXXX”,这是输入数据的长度,现在它可以正常工作(因为字段现在的长度为6)。

我希望这对有同样问题的人有帮助:)