错误,string或二进制数据在尝试插入时会被截断

我使用以下几行运行data.bat文件:

Rem Tis batch file will populate tables cd\program files\Microsoft SQL Server\MSSQL osql -U sa -P Password -d MyBusiness -ic:\data.sql 

data.sql文件的内容是:

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

有8个更多的类似的行添加logging。

当我运行此与start > run > 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> 

另外,我明显是一个新手,但是Level #state #是什么意思呢,我怎么看上面的错误信息:8152?

提前致谢!

从@ gmmastros的答案

每当你看到消息….

 string or binary data would be truncated 

想想自己……这个领域还不够大,无法保存我的数据。

检查客户表的表结构。 我想你会发现一个或多个字段的长度不足以容纳你试图插入的数据。 例如,如果Phone字段是一个varchar(8)字段,并且您尝试将11个字符input到该字段中,则会出现此错误。

在其中一个INSERT语句中,您试图将太长的string插入到string( varcharnvarchar )列中。

如果仅仅通过查看脚本就不清楚哪一个INSERT是违规者,则可以计数错误消息之前发生的<1 row affected>行。 所获得的数字加1就是你的语句编号。 在你的情况下,似乎是产生错误的第二个INSERT。

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

有些数据无法放入数据库列(小)。 find错误并不容易。 如果您使用C#和Linq2Sql,您可以列出将被截断的字段:

首先创build助手类:

 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; } } } 

准备全局exception处理程序和日志截断详细信息:

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

最后使用代码:

 Datamodel.SubmitChangesWithDetailException(); 

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

最后,我们发现在一些特定情况下,相关历史表中的列定义没有映射nvarchartypes的原始表列长度。

希望这个提示可以帮助别人..;)

只是想提供额外的信息:我有同样的问题,这是因为该领域是不够大的传入数据,这促使我解决它(最好的答案澄清了这一切)。

但是知道可能导致什么原因是非常重要的。

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

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

因此,“期间”字段的长度为零,导致插入操作失败。 我将它改为“XXXXXX”,即传入数据的长度,现在它正常工作(因为字段现在有6个字节)。

我希望这可以帮助任何人有同样的问题:)

在sql server上,你可以像这样使用SET ANSI_WARNINGS OFF:

  using (SqlConnection conn = new SqlConnection("Data Source=XRAYGOAT\\SQLEXPRESS;Initial Catalog='Healthy Care';Integrated Security=True")) { conn.Open(); using (var trans = conn.BeginTransaction()) { try { using cmd = new SqlCommand("", conn, trans)) { cmd.CommandText = "SET ANSI_WARNINGS OFF"; cmd.ExecuteNonQuery(); cmd.CommandText = "YOUR INSERT HERE"; cmd.ExecuteNonQuery(); cmd.Parameters.Clear(); cmd.CommandText = "SET ANSI_WARNINGS ON"; cmd.ExecuteNonQuery(); trans.Commit(); } } catch (Exception) { trans.Rollback(); } } conn.Close(); } 

你可以得到这个错误的另一种情况如下:

我有同样的错误,原因是在从UNION接收数据的INSERT语句中,列的顺序与原始表的顺序不同。 如果您将#table3中的顺序更改为a,b,c,则将修复错误。

 select a, b, c into #table1 from #table0 insert into #table1 select a, b, c from #table2 union select a, c, b from #table3 

我遇到过同样的问题。 我的专栏太短了。 你可以做的是增加长度或缩短你想放在数据库中的文字。