2011-04-08 25 views
165

Me postulo data.bat archivo con las siguientes líneas:de error, datos de cadena o binarios se trunca cuando se trata de insertar

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 

El contenido del archivo data.sql es:

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

Hay 8 líneas más similares para agregar registros.

Cuando ejecuto esto con start>run>cmd>c:\data.bat, me sale este mensaje de error:

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> 

Además, yo soy muy novato, obviamente, pero lo hago Level # y state # media, y cómo hacerlo Busco mensajes de error como el de arriba: 8152?

Respuesta

455

De @gmmastros's answer

Siempre que vea el mensaje ....

string or binary data would be truncated 

piensa a sí mismo ... El campo no es lo suficientemente grande como para contener mis datos.

Compruebe la estructura de la tabla para clientes. Creo que encontrará que la longitud de uno o más campos NO es lo suficientemente grande como para contener los datos que está tratando de insertar. Por ejemplo, si el campo Teléfono es un campo varchar (8) e intenta ingresar 11 caracteres, obtendrá este error.

+9

También tenga en cuenta que los campos afectados podrían estar en un disparador. Espero que recuerde esto la próxima vez que esto suceda ... –

+1

¿Hay alguna manera de ver en la depuración qué campo se truncará? – DailyFrankPeter

16

En una de las declaraciones INSERT está intentando insertar una cadena demasiado larga en una columna de cadena (varchar o nvarchar).

Si no es obvio, que INSERT es el delincuente por un simple vistazo a la secuencia de comandos, se podían contar las líneas <1 row affected> que se producen antes de el mensaje de error. El número obtenido más uno le da el número de extracto. En su caso, parece ser el segundo INSERT que produce el error.

3

Otra situación en la que se puede obtener este error es el siguiente:

que tenían el mismo error y la razón era que en una instrucción INSERT que recibe datos de un sindicato, el orden de las columnas era diferente de la mesa original. Si cambia el orden en # table3 a a, b, c, corregirá el error.

select a, b, c into #table1 
from #table0 

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

Tuve este problema aunque la longitud de los datos era más corta que la longitud del campo. Resultó que el problema era tener otra tabla de registro (para la pista de auditoría), rellenada por un desencadenante en la tabla principal, donde también se tenía que cambiar el tamaño de la columna.

+0

Gracias. El mío fue porque la columna sql en la tabla A es varchar (100). También se inserta en otra tabla, en la cual, la columna es varchar (50). –

9

Algunos de sus datos no caben en la columna de su base de datos (pequeña). No es fácil encontrar lo que está mal.Si utiliza C# y Linq2Sql, puede listar el campo que se trunca:

En primer lugar crear clase de ayuda:

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

       } 
      } 
     } 
    } 
} 

luego preparar la envoltura para 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; 
     } 
    } 
} 

Preparar excepción mundial datos de truncado de controladores y registros:

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

Por último, utilice el código:

Datamodel.SubmitChangesWithDetailException(); 
5

También se ha producido este problema en la superficie de la aplicación web. Finalmente descubrió que el mismo mensaje de error proviene de la instrucción SQL de actualización en la tabla específica.

Finalmente, descubrimos que la definición de la columna en la (s) tabla (s) de historial relacionada no correlacionaba la longitud original de la columna de la tabla de tipos nvarchar en algunos casos específicos.

Esperanza esta receta ayuda a otra persona también ..;)

4

Sólo quiero contribuir con información adicional: Tuve el mismo problema y que era debido a que el campo no era lo suficientemente grande para el entrante datos y esto me ayudó a resolverlo (la respuesta principal lo aclara todo).

pero es muy importante saber cuáles son las posibles razones que pueden provocar.

En mi caso yo estaba creando la tabla con un campo de la siguiente manera:

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

Por lo tanto el campo "Periodo" tenían una longitud de cero y haciendo que las operaciones de inserción fallen. He cambiado a "XXXXXX", que es la longitud de los datos entrantes y ahora funcionado correctamente (porque el campo tenía ahora un des tiempo de 6).

espero que esto ayuda a cualquier persona con mismo problema :)

4

en el servidor SQL se puede utilizar SET ANSI_WARNINGS OFF así:

 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(); 

     } 
0

que tenían el mismo problema. La longitud de mi columna era demasiado corto. Lo que puede hacer es o bien aumento la longitud o acortar el texto que desea poner en la base de datos.

Cuestiones relacionadas