fout, string- of binaire gegevens zouden worden afgekapt wanneer u probeert

Ik gebruik data.bat-bestand met de volgende regels:

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

De inhoud van het bestand Data.SQL is:

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

Er zijn nog 8 vergelijkbare regels voor het toevoegen van records.

Wanneer ik dit met start& GT; run& gt; cmd& gt; c:\data.bat, ik krijg dit foutbericht:

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>

Ook, ik ben een newbie natuurlijk, maar wat doen Level #, en state #gemiddelde, en hoe kijk ik foutberichten op, zoals hierboven: 8152?


1, Autoriteit 100%

van @ gmmastros’s antwoord

Wanneer u het bericht ziet ….

String of binaire gegevens zouden worden afgekapt

Denk aan jezelf … Het veld is niet groot genoeg om mijn gegevens vast te houden.

Controleer de tafelstructuur voor de klantentafel. Ik denk dat u zult merken dat de lengte van een of meer velden NIET groot genoeg is voor de gegevens die u probeert in te voegen. Als het veld Phone bijvoorbeeld een varchar(8)-veld is en u probeert er 11 tekens in te plaatsen, krijgt u deze foutmelding.


Antwoord 2, autoriteit 4%

Ik had dit probleem, hoewel de gegevenslengte korter was dan de veldlengte.
Het bleek dat het probleem zat in het hebben van een andere logtabel (voor audit trail), gevuld door een trigger op de hoofdtabel, waarbij ook de kolomgrootte moest worden gewijzigd.


Antwoord 3, autoriteit 3%

In een van de INSERT-instructies probeert u een te lange tekenreeks in een tekenreeks (varcharof nvarchar) kolom in te voegen.

Als het niet duidelijk is welke INSERTde overtreder is door alleen maar naar het script te kijken, kunt u de <1 row affected>regels tellen die voorkomen voorde foutmelding. Het verkregen getal plus één geeft je het afschriftnummer. In jouw geval lijkt het de tweede INSERT te zijn die de fout veroorzaakt.


Antwoord 4, autoriteit 2%

Sommige van uw gegevens passen niet in uw databasekolom (klein). Het is niet eenvoudig om te vinden wat er mis is. Als u C# en Linq2Sql gebruikt, kunt u het veld weergeven dat wordt afgekapt:

Maak eerst een hulpklasse:

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

Maak vervolgens de wrapper klaar voor 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;
        }
    }
}

Bereid globale uitzonderingshandler en logafkortingsdetails voor:

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

Gebruik ten slotte de code:

Datamodel.SubmitChangesWithDetailException();

Antwoord 5

Ik wil gewoon een bijdrage leveren met aanvullende informatie: ik had hetzelfde probleem en het was omdat het veld niet groot genoeg was voor de binnenkomende gegevens en deze thread heeft me geholpen om het op te lossen (het bovenste antwoord verduidelijkt alles).

MAAR het is erg belangrijk om te weten wat de mogelijke redenen zijn die dit kunnen veroorzaken.

In mijn geval was ik de tabel aan het maken met een veld als dit:

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

Daarom had het veld “Periode” een lengte van nul en zorgde ervoor dat de invoegbewerkingen mislukten. Ik heb het veranderd in “XXXXXX”, dat is de lengte van de binnenkomende gegevens en het werkte nu naar behoren (omdat het veld nu een lengte van 6 had).

Ik hoop dat dit iedereen helpt met hetzelfde probleem 🙂


Antwoord 6

Een andere situatie waarin u deze fout kunt krijgen, is de volgende:

Ik had dezelfde fout en de reden was dat in een INSERT-instructie die gegevens van een UNION ontving, de volgorde van de kolommen anders was dan in de oorspronkelijke tabel. Als je de volgorde in #table3 verandert in a, b, c, herstel je de fout.

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

Antwoord 7

op sql-server kun je SET ANSI_WARNINGS OFF als volgt gebruiken:

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

8

Ik had hetzelfde probleem. De lengte van mijn kolom was te kort.

Wat u kunt doen is ofwel verhogen de lengte of verkorten De tekst die u in de database wilt plaatsen.


9

Ik had hetzelfde probleem, zelfs na het verhogen van de omvang van de problematische kolommen in de tabel.

TL; DR: De lengte van de overeenkomende kolommen in bijbehorende tafeltypen moet ook worden verhoogd.

In mijn geval kwam de fout uit de gegevensuitvoerdienst in Microsoft Dynamics CRM, waarmee CRM-gegevens kunnen worden gesynchroniseerd met een SQL Server DB of Azure SQL DB.

Na een langdurig onderzoek concludeerde ik dat de gegevensuitvoerdienst Tabelwaarde parameters :

U kunt tabelwaardeparameters gebruiken om meerdere rijen gegevens naar een transact-SQL-instructie of een routine te verzenden, zoals een opgeslagen procedure of functie, zonder een tijdelijke tabel of veel parameters te maken.

Zoals u in de bovenstaande documentatie kunt zien, worden tafeltypen gebruikt om de gegevensopnameprocedure te maken:

CREATE TYPE LocationTableType AS TABLE (...);
CREATE PROCEDURE dbo.usp_InsertProductionLocation
  @TVP LocationTableType READONLY

Helaas is er geen manier om een ​​tafeltype te wijzigen, dus het moet worden laten vallen en ampère; volledig opnieuw gemaakt. Aangezien mijn tabel meer dan 300 velden (😱) heeft, creëerde ik een query om de oprichting van het overeenkomstige tabeltype te vergemakkelijken op basis van de kolommendefinitie van de tabel (vervang gewoon [table_name]met de naam van uw tabel):

SELECT 'CREATE TYPE [table_name]Type AS TABLE (' + STRING_AGG(CAST(field AS VARCHAR(max)), ',' + CHAR(10)) + ');' AS create_type
FROM (
  SELECT TOP 5000 COLUMN_NAME + ' ' + DATA_TYPE
      + IIF(CHARACTER_MAXIMUM_LENGTH IS NULL, '', CONCAT('(', IIF(CHARACTER_MAXIMUM_LENGTH = -1, 'max', CONCAT(CHARACTER_MAXIMUM_LENGTH,'')), ')'))
      + IIF(DATA_TYPE = 'decimal', CONCAT('(', NUMERIC_PRECISION, ',', NUMERIC_SCALE, ')'), '')
      AS field
  FROM INFORMATION_SCHEMA.COLUMNS
  WHERE TABLE_NAME = '[table_name]'
  ORDER BY ORDINAL_POSITION) AS T;

Na het bijwerken van het tabeltype begon de gegevensexportservice weer naar behoren te functioneren! 🙂


Antwoord 10

Toen ik mijn opgeslagen procedure probeerde uit te voeren, had ik hetzelfde probleem, omdat de grootte van de kolom die ik nodig heb om gegevens toe te voegen, korter is dan de gegevens die ik wil toevoegen.

U kunt het gegevenstype van de kolom vergroten of de lengte van uw gegevens verkleinen.


Antwoord 11

Een andere situatie waarin deze fout kan optreden is in
Studio voor SQL Server-beheer. Als je “text” of “ntext” velden in je tabel hebt,
ongeacht het soort veld dat u bijwerkt (bijvoorbeeld bit of integer).
Het lijkt erop dat de Studio geen volledige “ntext”-velden laadt en ook ALLE velden bijwerkt in plaats van de gewijzigde.
Om het probleem op te lossen, sluit u “text”- of “ntext”-velden uit van de query in Management Studio


Antwoord 12

Kevin Pope’sopmerking onder het geaccepteerde antwoord was wat ik nodig had.

Het probleem in mijn geval was dat ik triggers had gedefinieerd op mijn tabel die bijwerk-/invoegtransacties in een controletabel zouden invoegen, maar de controletabel had een niet-overeenkomend gegevenstype waarbij een kolom met VARCHAR(MAX)in de originele tabel werd opgeslagen als VARCHAR(1)in de controletabel, dus mijn triggers faalden toen ik iets groters dan VARCHAR(1)in de originele tabelkolom en ik zou deze foutmelding krijgen.


Antwoord 13

Ik heb een andere tactiek gebruikt, velden waaraan op sommige plaatsen 8K is toegewezen. Hier worden slechts ongeveer 50/100 gebruikt.

declare @NVPN_list as table 
nvpn            varchar(50)
,nvpn_revision  varchar(5)
,nvpn_iteration INT
,mpn_lifecycle  varchar(30)
,mfr            varchar(100)
,mpn            varchar(50)
,mpn_revision   varchar(5)
,mpn_iteration  INT
-- ...
) INSERT INTO @NVPN_LIST 
SELECT  left(nvpn           ,50)    as nvpn
        ,left(nvpn_revision ,10)    as nvpn_revision
        ,nvpn_iteration
        ,left(mpn_lifecycle ,30)
        ,left(mfr           ,100)
        ,left(mpn           ,50)
        ,left(mpn_revision  ,5)
        ,mpn_iteration
        ,left(mfr_order_num ,50)
FROM [DASHBOARD].[dbo].[mpnAttributes] (NOLOCK) mpna

Ik wilde snelheid, aangezien ik in totaal 1 miljoen records heb en er 28K van laad.


Antwoord 14

Deze fout kan te wijten zijn aan een kleinere veldgrootte dan uw ingevoerde gegevens.

Voor bijv. als u het gegevenstype nvarchar(7)heeft en als uw waarde ‘aaaaddddf’ is, wordt de fout weergegeven als:

tekenreeks of binaire gegevens worden afgekapt


Antwoord 15

Een update van 2016/2017 toont u de slechte waarde en kolom.

Een nieuwe traceringsvlag verwisselt de oude fout voor een nieuwe 2628-fout en drukt de kolom en de overtredende waarde af. Traceflag 460 is beschikbaar in de laatste cumulatieve update voor 2016 en 2017:

https://support.microsoft.com/en-sg/help/4468101/optionele-replacement-for-string-or-binary-data-would-be-truncated

Zorg ervoor dat u, nadat u de CU hebt geïnstalleerd, de traceringsvlag inschakelt, ofwel globaal/permanent op de server:

… of met DBCC Traceon:

https://docs.microsoft.com/en-US/SQL/T-SQL/DATABASE-CONSOLE-COMMANDS/DBCC-TRACEON-TRACE-FLAGS-Transact-SQL?View = SQL-SERVER-VER15


16

U kunt SQL Server hier eenvoudig over verslaan.

U kunt in een nieuwe tabel invoegen:

select foo, bar
into tmp_new_table_to_dispose_later
from my_table

en Vergelijk de tabeldefinitie met de echte tabel waarop u de gegevens wilt invoegen.

Soms is het nuttig, soms is het niet.

Als u probeert in te voegen in de laatste / reële tabel vanaf die tijdelijke tabel, kan het gewoon werken (als gevolg van data-conversie die bijvoorbeeld anders werkt dan SSMS).

Een ander alternatief is om de gegevens in brokken in te voegen, in plaats van alles meteen in te voegen, voegt u in met top 1000en u herhaalt het proces, totdat u een stuk met een fout. Je hebt tenminste een betere zichtbaarheid op wat er niet in de tabel zit.

Other episodes