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)
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.
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.
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
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
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
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.
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.
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.
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.
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]
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.