web-dev-qa-db-fra.com

SQLException: une chaîne ou des données binaires seraient tronquées

J'ai un code C # qui fait beaucoup d'insertion d'instructions dans un lot. Lors de l’exécution de ces instructions, j’ai reçu l’erreur "Une transaction ou des données binaires tronquées" et une transaction roledback. 

Pour savoir quelle instruction insert a provoqué cela, je dois insérer un par un dans le serveur SQL jusqu'à ce que l'erreur apparaisse.

Existe-t-il un moyen intelligent de déterminer quelle instruction et quel champ ont provoqué ce problème en utilisant la gestion des exceptions? (SqlException)

54
ramanasv

En général, il n’existe aucun moyen de déterminer quelle déclaration particulière a causé l’erreur. Si vous en utilisez plusieurs, vous pouvez regarder le profileur, consulter la dernière déclaration complétée et voir quelle pourrait être la déclaration suivante, bien que je ne sache pas si cette approche est réalisable pour vous.

Dans tous les cas, l'une de vos variables de paramètre (et les données qu'il contient) est trop grande pour le champ dans lequel elle tente de stocker des données. Vérifiez la taille de vos paramètres par rapport à la taille des colonnes et le (s) champ (s) en question devraient apparaître assez rapidement.

69
Adam Robinson

Ce type d'erreur se produit lorsque le type de données de la colonne SQL Server a une longueur inférieure à la longueur des données entrées dans le formulaire de saisie.

17
Jasmin Chauhan

ce type d'erreur se produit généralement lorsque vous devez placer des caractères ou des valeurs supérieures à celles spécifiées dans Table de base de données, comme dans ce cas: vous spécifiez transaction_status varchar (10) mais vous essayez réellement de stocker _ transaction_status qui contient 19 caractères. c'est pourquoi vous avez rencontré ce type d'erreur dans ce code

7
jaideep
BEGIN TRY
    INSERT INTO YourTable (col1, col2) VALUES (@val1, @val2)
END TRY
BEGIN CATCH
    --print or insert into error log or return param or etc...
    PRINT '@val1='+ISNULL(CONVERT(varchar,@val1),'')
    PRINT '@val2='+ISNULL(CONVERT(varchar,@val2),'')
END CATCH
3
KM.

En règle générale, vous insérez une valeur supérieure à la valeur maximale autorisée. Ex, la colonne de données ne peut contenir que 200 caractères, mais vous insérez une chaîne de 201 caractères

3
ismail baig
  1. Obtenez la requête à l'origine des problèmes (vous pouvez également utiliser SQL Profiler si vous n'avez pas le source)
  2. Supprimez toutes les clauses WHERE et autres parties sans importance jusqu'à ce qu'il ne vous reste plus que les parties SELECT et FROM
  3. Ajouter WHERE 0 = 1 (cela ne sélectionnera que la structure du tableau)
  4. Ajouter INTO [MyTempTable] juste avant la clause FROM

Vous devriez vous retrouver avec quelque chose comme 

SELECT
 Col1, Col2, ..., [ColN]
INTO [MyTempTable]
FROM
  [Tables etc.]
WHERE 0 = 1

Cela créera une table appelée MyTempTable dans votre base de données que vous pourrez comparer à la structure de votre table cible, c’est-à-dire que vous pourrez comparer les colonnes des deux tables pour voir en quoi elles diffèrent. C'est un peu une solution de contournement, mais c'est la méthode la plus rapide que j'ai trouvée. 

2
profMamba

Cela dépend de la façon dont vous effectuez les appels d'insertion. Tout cela en un seul appel ou en tant qu'appels individuels dans une transaction? Si vous appelez individuellement, alors oui (pendant que vous parcourez les appels, prenez celui qui a échoué). Si un grand appel, alors non. SQL traite l'intégralité de l'instruction, elle ne relève donc pas du code.

2
CodeMonkey1313

C'est peut-être aussi parce que vous essayez de réintégrer une valeur null dans la base de données. Donc, une de vos transactions pourrait avoir des valeurs nulles.

0
Fandango68

La plupart des réponses ici consistent à vérifier de façon évidente que la longueur de la colonne telle que définie dans la base de données n’est pas inférieure à celle des données que vous essayez de lui transmettre.

Plusieurs fois, j'ai été piqué en allant dans SQL Management Studio, en faisant un rapide:

sp_help 'mytable'

et soyez confus pendant quelques minutes jusqu'à ce que je réalise que la colonne en question est un nvarchar , ce qui signifie que la longueur indiquée par sp_help est vraiment le double de la longueur réelle prise en charge car il s'agit d'un type de données à double octet (unicode).

c'est-à-dire si sp_help rapporte nvarchar Longueur 40, vous pouvez stocker 20 caractères maximum.

0
Chris Amelinckx

Avec Linq To SQL, j'ai débogué en enregistrant le contexte, par exemple. Context.Log = Console.Out Puis analysé le SQL pour vérifier les erreurs évidentes, il y avait deux:

-- @p46: Input Char (Size = -1; Prec = 0; Scale = 0) [some long text value1]
-- @p8: Input Char (Size = -1; Prec = 0; Scale = 0) [some long text value2]

le dernier que j'ai trouvé en scannant le schéma de la table avec les valeurs, le champ était nvarchar (20) mais la valeur était de 22 caractères

-- @p41: Input NVarChar (Size = 4000; Prec = 0; Scale = 0) [1234567890123456789012]

0
sdjfhueryeiur

Dans notre cas, j'augmente la taille de caractère ou de champ autorisée de la table SQL, qui est inférieure au nombre total de caractères affichés depuis le début. D'où cela résoudre le problème.

0
Ibrahim Mohammed