J'ai une simple table de pays utilisant une colonne d'identité pour la clé primaire. Il y a également des colonnes utilisées pour contenir les codes de pays ISO-3166 à 2 lettres et 3 lettres. Chacune de ces colonnes est définie comme un index unique.T-SQL Reporting Duplicate Key Exception à l'utilisateur de manière simple
Sur insertions/mises à jour Je souhaite simplement informer l'utilisateur si le code ISO entré est déjà utilisé. Je compte sur l'exception de base de données pour déclencher le processus. Je ne veux pas submerger les utilisateurs avec les détails techniques. Je veux juste lui dire que la valeur ISO entrée ne peut pas être utilisée.
Voici le T-SQL dans le Procès stocké que j'ai écrit. Il semble long et sujet à de futurs bugs et/ou à une maintenance continue au fur et à mesure que l'application se développe et que les choses changent. Y a-t-il un moyen meilleur ou plus simple? Je pourrais être un peu mouillé derrière les oreilles avec .net, mais je pensais que ce serait plus facile.
BEGIN TRY
UPDATE [Country] SET [CountryName] = @CountryName, [CountryISO] = @CountryISO, [CountryISO3] = @CountryISO3, [UpdateDate] = @updateDate WHERE (([CountryID] = @CountryID) AND ([RowVersion] = @Original_RowVersion));
END TRY
BEGIN CATCH
DECLARE @ErrSeverity int, @ErrNumber int, @ErrLine int
DECLARE @ErrMsg nvarchar(4000)
SELECT @ErrSeverity = ERROR_SEVERITY(), @ErrNumber = ERROR_NUMBER(),@ErrState = ERROR_STATE(),
@ErrMsg =
CASE WHEN ERROR_NUMBER() = 2601
THEN
CASE
WHEN ISNULL(CHARINDEX('IX_COUNTRYISO3', ERROR_MESSAGE()), 0) > 0
THEN 'The 3 letter ISO-3166 value entered is already in use. Please enter a unique 3 letter ISO-3166 value.'
WHEN ISNULL(CHARINDEX('IX_COUNTRYISO', ERROR_MESSAGE()), 0) > 0
THEN 'The 2 letter ISO-3166 value entered is already in use. Please enter a unique 2 letter ISO-3166 value.'
ELSE
ERROR_MESSAGE() + '(SQL ErrNo: ' + CONVERT(varchar(50), ERROR_NUMBER()) + ')'
END
ELSE
ERROR_MESSAGE() + '(SQL ErrNo: ' + CONVERT(varchar(50), ERROR_NUMBER()) + ')'
END;
RAISERROR(@ErrMsg, @ErrSeverity, @ErrState)
END CATCH
Ma solution est-elle viable?
Quelle est la meilleure façon de partager ce code d'exception entre l'insertion et la mise à jour StoredProcs?
Je suppose que je demande essentiellement une révision de code.
Merci beaucoup Mike
@Aaronaught: La vérification des valeurs par rapport à la base de données avant la soumission semble être une bonne stratégie. Peut-être ajouterai-je un appel AJAX lorsque les valeurs des deux zones de texte changent. Cela me permettra également d'utiliser une stratégie plus générique pour afficher et collecter des informations d'exception. Merci pour vos commentaires. Je posterai avec tout progrès que je fais. Cela peut ne pas être pour plusieurs jours cependant. – MikeSullivan
Dans un environnement multi-utilisateur, vous ne pouvez pas compter sur des contrôles en double au niveau de l'interface utilisateur. Les réglages de l'interface utilisateur devraient être là, mais le traitement de l'erreur de la clé en double devrait l'être aussi. Maintenant, puisque l'ajustement d'index est une tâche courante pour un DBA, laisser le client analyser le message d'erreur est une mauvaise idée. Généralement, c'est une très mauvaise idée de montrer des erreurs SQL à l'utilisateur. Je pense vraiment que la solution de MikeSullivan est viable. – l33t
@ l33t: Ceci n'analyse pas l'erreur * message *, il regarde l'erreur * code *. C'est ce que les codes d'erreur sont * pour *. Et comme c'est une mauvaise idée de montrer des erreurs SQL à l'utilisateur, c'est une mauvaise idée de montrer * toutes les erreurs spécifiques à l'utilisateur. La plupart des applications modernes utilisent des opérations fire-and-forget avec une cohérence éventuelle, de sorte que les erreurs sont un problème de développeur plutôt que d'utilisateur et lorsqu'elles doivent montrer une erreur interne, elles le font avec une erreur générique. écran et quelques étapes de dépannage, comme "actualiser la page et réessayer votre dernière action". – Aaronaught