我运行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?


当前回答

此错误仅当任何字段长度大于sql server数据库表结构中指定的字段长度时出现。

为了克服这个问题,你必须减少字段值的长度。 或者增加数据库表字段的长度。

其他回答

凯文·波普在公认答案下的评论正是我所需要的。

在我的例子中,问题是我在我的表上定义了触发器,将更新/插入事务插入到审计表中,但审计表有一个数据类型不匹配,其中原始表中具有VARCHAR(MAX)的列存储为审计表中的VARCHAR(1),因此当我在原始表列中插入大于VARCHAR(1)的任何内容时,我的触发器失败,并且我会得到这个错误消息。

有些数据无法放入数据库列中(小)。要发现哪里有问题并不容易。如果你使用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();

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

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

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

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

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

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

在其中一个INSERT语句中,您试图将一个太长的字符串插入到字符串(varchar或nvarchar)列中。

如果仅仅通过查看脚本还不清楚哪个INSERT是违规者,那么可以计算错误消息之前出现的<1行受影响的>行。得到的数字加1就是陈述号。在您的例子中,似乎是第二个INSERT产生了错误。

当我试图执行我的存储过程时,我遇到了同样的问题,因为我需要添加一些数据的列的大小比我想要添加的数据要短。

您可以增加列数据类型的大小或减少数据的长度。