sql - los - error, cadena o datos binarios se truncarían al intentar insertar
los datos de cadena o binarios se truncarían (11)
Algunos de sus datos no pueden encajar en la columna de su base de datos (pequeña). No es fácil encontrar lo que está mal. Si usa C # y Linq2Sql, puede enumerar el campo que se truncaría:
Primero crea una 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 prepara el envoltorio 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;
}
}
}
Prepare el manejador de excepciones global y los detalles de truncamiento de registro:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
string message = ex.Message;
//TODO - log to file
}
Finalmente usa el código:
Datamodel.SubmitChangesWithDetailException();
Estoy ejecutando el archivo data.bat con las siguientes líneas:
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
, c:/data.bat
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, obviamente soy un novato, pero ¿qué significan el Level #
y el state #
, y cómo busco mensajes de error como el de arriba: 8152?
Cuando intenté ejecutar mi procedimiento almacenado tuve el mismo problema porque el tamaño de la columna que necesito para agregar algunos datos es más corto que los datos que quiero agregar. Puede aumentar el tamaño del tipo de datos de columna o reducir la longitud de sus datos.
Cuando veas el mensaje ...
string or binary data would be truncated
Piensa a ti mismo ... El campo NO es lo suficientemente grande como para contener mis datos.
Compruebe la estructura de la tabla para la tabla de 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á intentando insertar. Por ejemplo, si el campo Teléfono es un campo varchar (8), e intenta ponerle 11 caracteres, obtendrá este error.
En una de las INSERT
está intentando insertar una cadena demasiado larga en una columna de cadena ( varchar
o nvarchar
).
Si no es obvio qué INSERT
es el delincuente con solo mirar la secuencia de comandos, podría contar las líneas <1 row affected>
que aparecen antes del mensaje de error. El número obtenido más uno le da el número del extracto. En su caso, parece ser el segundo INSERT que produce el error.
Otra situación en la que puedes obtener este error es la siguiente:
Tuve el mismo error y el motivo fue que en una declaración INSERT que recibió datos de UNION, el orden de las columnas era diferente de la tabla original. Si cambia el orden en # table3 a a, b, c, solucionará 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
Otra situación en la que se puede producir este error es en SQL Server Management Studio. Si tiene campos de "texto" o "ntext" en su tabla, no importa qué tipo de campo esté actualizando (por ejemplo, bit o entero). Parece que Studio no carga campos completos "ntext" y también actualiza TODOS los campos en lugar de los modificados. Para resolver el problema, excluya los campos "texto" o "ntext" de la consulta en Management Studio
Solo quiero contribuir con información adicional: tuve el mismo problema y fue porque el campo no era lo suficientemente grande para los datos entrantes y este hilo me ayudó a resolverlo (la respuesta principal lo aclara todo).
PERO es muy importante saber cuáles son las posibles razones que lo pueden causar.
En mi caso estaba creando la tabla con un campo como este:
Select '''' as Period, * From Transactions Into #NewTable
Por lo tanto, el campo "Período" tenía una longitud de cero y causaba que las operaciones de inserción fallaran. Lo cambié a "XXXXXX" que es la longitud de los datos entrantes y ahora funcionó correctamente (porque el campo ahora tenía una longitud de 6).
Espero que esto ayude a cualquiera con el mismo problema :)
También tuvo este problema ocurriendo en la superficie de la aplicación web. Finalmente descubrió que el mismo mensaje de error proviene de la declaración de actualización de SQL en la tabla específica.
Finalmente, luego descubrimos que la definición de columna en la (s) tabla (s) histórica (s) relacionada (es) no mapeaba la longitud de columna de la tabla original de los tipos nvarchar
en algunos casos específicos.
Espero que esta sugerencia también ayude a alguien más ...;)
Tuve el mismo problema. La longitud de mi columna era demasiado corta. Lo que puede hacer es aumentar la longitud o acortar el texto que desea colocar en la base de datos.
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 el seguimiento de auditoría), rellenada por un disparador en la tabla principal, donde también se debía cambiar el tamaño de la columna.
en el servidor SQL puede usar SET ANSI_WARNINGS OFF de esta forma:
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();
}