Selon cette discussion de forum En effet, le serveur SQL (j'utilise 2005 mais je suppose que cela s'applique également à 2000 et 2008) tronque silencieusement les données de l'utilisateur. varchar
que vous spécifiez en tant que paramètres de procédure stockée à la longueur de la variable, même si l'insertion directe de cette chaîne à l'aide d'un fichier de type INSERT
provoquerait en fait une erreur. Par exemple, si je crée cette table :
CREATE TABLE testTable(
[testStringField] [nvarchar](5) NOT NULL
)
alors quand j'exécute ce qui suit :
INSERT INTO testTable(testStringField) VALUES(N'string which is too long')
Je reçois une erreur :
String or binary data would be truncated.
The statement has been terminated.
Super. L'intégrité des données est préservée, et l'appelant le sait. Maintenant, définissons une procédure stockée pour insérer ça :
CREATE PROCEDURE spTestTableInsert
@testStringField [nvarchar](5)
AS
INSERT INTO testTable(testStringField) VALUES(@testStringField)
GO
et l'exécuter :
EXEC spTestTableInsert @testStringField = N'string which is too long'
Aucune erreur, 1 ligne affectée. Une ligne est insérée dans la table, avec testStringField
comme "strin". Le serveur SQL a tronqué silencieusement les données de la procédure stockée. varchar
paramètre.
Ce comportement peut parfois s'avérer pratique, mais je suppose qu'il n'existe AUCUN moyen de le désactiver. C'est extrêmement ennuyeux, car je veulent le truc qui provoque une erreur si je passe une chaîne trop longue à la procédure stockée. Il semble qu'il y ait deux façons de traiter ce problème.
Tout d'abord, déclarez l'objet de la proc stockée @testStringField
comme une taille 6, et vérifiez si sa longueur est supérieure à 5. Cela semble être un peu compliqué et implique une quantité irritante de code passe-partout.
Deuxièmement, déclarez simplement que TOUS les paramètres varchar de la procédure stockée doivent être varchar(max)
et ensuite laisser le INSERT
dans la procédure stockée échoue.
Ce dernier semble fonctionner correctement. Ma question est donc la suivante : est-ce une bonne idée d'utiliser varchar(max)
TOUJOURS pour les chaînes de caractères dans les procédures stockées du serveur SQL, si je veux que la procédure stockée échoue lorsqu'une chaîne de caractères trop longue est passée ? Serait-ce même une bonne pratique ? La troncature silencieuse qui ne peut pas être désactivée me semble stupide.
1 votes
Les instructions préparées avec les pilotes dérivés de Sybase, tels que DBD::Sybase de Perl, fonctionnent en créant une procédure stockée temporaire puis en l'appelant, de sorte que vous pouvez également rencontrer la troncature silencieuse avec les instructions préparées. Je ne sais pas si d'autres pilotes, comme ODBC, gèrent mieux les instructions préparées.
1 votes
Apparemment, le même comportement existe pour les fonctions et les variables. Selon la note de msdn.microsoft.com/fr/us/library/ms187926.aspx : " SET ANSI_WARNINGS " n'est pas honoré lors du passage de paramètres dans une procédure, une fonction définie par l'utilisateur, ou lors de la déclaration et de la définition de variables dans une instruction batch. Par exemple, si une variable est définie comme char(3), puis définie à une valeur supérieure à trois caractères, les données sont tronquées à la taille définie et l'instruction INSERT ou UPDATE réussit." .