188 votes

SQL Server Les chaînes ou les données binaires seraient tronquées.

Je suis impliqué dans un projet de migration de données. J'obtiens l'erreur suivante lorsque j'essaie d'insérer des données d'une table dans une autre table (SQL Server 2005) :

Msg 8152, Niveau 16, État 13, Ligne 1
Les données de type chaîne ou binaire seraient tronquées.

Les colonnes des données sources correspondent au type de données et sont comprises dans les définitions de longueur des colonnes de la table de destination. Je ne vois donc pas ce qui pourrait causer cette erreur.

0 votes

Pourriez-vous afficher un peu de code et des informations sur chaque table ?

0 votes

Les tableaux sont tous les deux assez grands - je ne vais donc poster que la partie des définitions de tableaux qui sont concernées et le code - est-ce acceptable ?

0 votes

Les définitions des tableaux et le code seraient parfaits.

221voto

BiggsTRC Points 10362

Vous devez nous fournir les définitions des tables source et destination pour que nous puissions déterminer où se situe le problème. le résultat final est qu'une de vos colonnes dans la table source est plus grande que vos colonnes de destination. . Il se peut que vous changiez de format d'une manière dont vous n'étiez pas conscient. Le modèle de base de données que vous quittez est également important pour le déterminer.

3 votes

J'ai été confronté au même problème et j'ai dû comparer tous les types et tailles de colonnes des deux tableaux pour résoudre le problème.

1 votes

Après avoir rassemblé les définitions partielles des tables et obtenu mon code sproc, la colonne incriminée m'a sauté aux yeux comme un éclair... Merci à tous pour votre contribution.

13 votes

C'est vraiment génial que SQL ne prenne pas la peine de vous dire quelle colonne est à l'origine du problème. J'ai commencé à supprimer les informations utiles de tous mes messages d'erreur pour tenter d'imiter ce coup de génie.

131voto

Rudi Points 2888

Comme d'autres l'ont déjà dit, l'un des types de données de vos colonnes dans la table source est plus grand que vos colonnes de destination.

Une solution simple consiste à désactiver l'avertissement et à laisser la troncature s'effectuer. Donc, si vous recevez cette erreur mais que vous êtes sûr qu'il est acceptable que les données de votre ancienne base de données/table soient tronquées (coupées à la taille), vous pouvez simplement faire ce qui suit ;

SET ANSI_WARNINGS OFF;
-- Your insert TSQL here.
SET ANSI_WARNINGS ON;

Comme ci-dessus, n'oubliez jamais de rallumer les avertissements par la suite. J'espère que cela vous aidera.

3 votes

Il en va de même ici. Il m'arrive de devoir stocker dans une table des données provenant, par exemple, d'un service web, dont le type de données n'est défini que comme une "chaîne". Je ne peux pas faire de tout a Varchar(MAX)...

0 votes

Cela n'a pas travail mais j'ai obtenu des résultats qui m'ont permis de résoudre le problème (en augmentant la longueur des variables) ! Merci donc.

67voto

Thomas Points 42973

Le problème est assez simple : une ou plusieurs des colonnes de la requête source contiennent des données qui dépassent la longueur de leur colonne de destination. Une solution simple serait de prendre votre requête source et d'exécuter Max(Len( source col )) sur chaque colonne. Par exemple,

Select Max(Len(TextCol1))
    , Max(Len(TextCol2))
    , Max(Len(TextCol3))
    , ...
From ...

Comparez ensuite ces longueurs aux longueurs des types de données dans votre table de destination. L'un d'entre eux au moins dépasse la longueur de sa colonne de destination.

Si vous êtes absolument certain que ce n'est pas le cas et ne se soucient pas de savoir si ce n'est pas le cas Dans ce cas, une autre solution consiste à adapter de force les colonnes de la requête source à leur longueur de destination (ce qui tronquera les données trop longues) :

Select Cast(TextCol1 As varchar(...))
    , Cast(TextCol2 As varchar(...))
    , Cast(TextCol3 As varchar(...))
    , ...
From ...

1 votes

Mon processus quotidien a commencé à s'interrompre avec cette erreur. Les données que j'insère sont toujours assez courtes pour tenir et j'ai toujours d'autres lignes (dans le tableau d'où je tire les données) avec des chaînes de caractères trop grandes qui n'ont jamais été insérées à cause de mon filtre. Peut-être qu'un index a été reconstruit, ou que les statistiques ont été mises à jour, mais le fantôme dans la machine a décidé un jour qu'il n'aimait plus le plan de requête, parce qu'il l'a emmené sur un chemin où les données (qui étaient trop larges) "pouvaient" être insérées avant qu'elles ne soient filtrées par le prédicat dans la clause Where. Pour contourner ce problème, j'ai utilisé LEFT() au lieu de CAST - il y a moins de caractères à taper.

1 votes

Merci Thomas, c'est étrange, même si je n'ai pas de données trop longues, je dois quand même les adapter à la nouvelle taille de la colonne de destination, dès que j'ai fait cela, cela a fonctionné.

31voto

lad2025 Points 38168

SQL Server 2019 renverra finalement un message d'erreur plus significatif.

Les données binaires ou les chaînes de caractères seraient tronquées => amélioration du message d'erreur

si vous avez cette erreur (en production), il n'est pas évident de voir de quelle colonne ou ligne provient cette erreur, et comment la localiser exactement.

Pour activer un nouveau comportement, vous devez utiliser DBCC TRACEON(460) . Nouveau texte d'erreur de sys.messages :

SELECT * FROM sys.messages WHERE message_id = 2628

2628 - Une chaîne ou des données binaires seraient tronquées dans la table '%.*ls', colonne '%.*ls'. Valeur tronquée : '%.*ls'.

Les données de type String ou Binary seraient tronquées : remplacement de la fameuse erreur 8152

Ce nouveau message est également reporté dans SQL Server 2017 CU12 (et dans une prochaine CU de SQL Server 2016 SP2), mais pas par défaut. Vous devez activer l'indicateur de suivi 460 pour remplacer le message ID 8152 par 2628, soit au niveau de la session, soit au niveau du serveur.

Notez que pour l'instant, même dans SQL Server 2019 CTP 2.0, le même drapeau de trace 460 doit être activé. Dans une future version de SQL Server 2019, le message 2628 remplacera le message 8152 par défaut.


SQL Server 2017 CU12 prend également en charge cette fonctionnalité.

Amélioration : Remplacement optionnel du message "String or binary data would be truncated" par des informations étendues dans SQL Server 2017

Cette mise à jour de SQL Server 2017 introduit un message facultatif qui contient les informations contextuelles supplémentaires suivantes.

Msg 2628, Level 16, State 6, Procedure ProcedureName, Line Linenumber
String or binary data would be truncated in table '%.*ls', column '%.*ls'.
Truncated value: '%.*ls'.

Le nouvel ID du message est 2628. Ce message remplace le message 8152 dans toute sortie d'erreur si l'indicateur de suivi 460 est activé.

db<>démonstration


MODIFIER LA CONFIGURATION DE LA PORTÉE DE LA BASE DE DONNÉES

VERBOSE_TRUNCATION_WARNINGS = { ON | OFF }

S'APPLIQUE À : SQL Server (à partir de SQL Server 2019 (15.x)) et Azure SQL Database.

Vous permet d'activer ou de désactiver le nouveau String ou les données binaires seraient tronquées. SQL Server 2019 (15.x) introduit un nouveau message d'erreur plus spécifique. nouveau message d'erreur plus spécifique (2628) pour ce scénario :

String or binary data would be truncated in table '%.*ls', column'%.*ls'. Truncated value: '%.*ls'.

Lorsqu'elle est définie sur ON sous le niveau 150 de compatibilité de la base de données, la troncature de troncature génèrent le nouveau message d'erreur 2628 afin de fournir plus de contexte et de simplifier le processus de dépannage.

Lorsqu'il est défini sur OFF sous le niveau de compatibilité 150 de la base de données, les erreurs de troncature augmentent le niveau précédent de la base de données. font apparaître le message d'erreur précédent 8152.

Pour le niveau de compatibilité de la base de données 140 ou inférieur, message d'erreur 2628 reste un message d'erreur opt-in qui nécessite l'activation de l'indicateur de suivi 460. activé, et cette configuration de la base de données n'a aucun effet.

2 votes

Cette fonction est désormais également disponible pour SQL Azure : azure.microsoft.com/en-gb/updates/

1 votes

Merci pour les liens - c'est très utile de connaître ces changements.

9voto

Brian Points 81

Une autre raison potentielle de ce problème est que vous avez configuré une valeur par défaut pour une colonne qui dépasse la longueur de la colonne. Il semble que quelqu'un ait créé une colonne dont la longueur était de 5, mais dont la valeur par défaut dépassait cette longueur. Cela m'a rendu fou car j'essayais de comprendre pourquoi cela ne fonctionnait sur aucune insertion, même si tout ce que j'insérais était une seule colonne avec un entier de 1. Parce que la valeur par défaut sur le schéma de la table avait cette valeur par défaut violante, cela a tout gâché - ce qui je suppose nous amène à la leçon apprise - éviter d'avoir des tables avec des valeurs par défaut dans le schéma :)

1 votes

Je ne pense pas qu'éviter les valeurs par défaut soit une bonne solution. Les valeurs par défaut sont très utiles. Je ne résoudrais pas les "problèmes" de base de données causés par les fautes de frappe en supprimant les valeurs par défaut...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X