web-dev-qa-db-fra.com

Devrais-je vérifier l'existence de tables temporaires dans les procédures stockées?

Existe-t-il un cas de bord dans lequel il serait recommandé de rechercher explicitement, de déposer et de créer des tables TEMP au début d'une procédure stockée au lieu de les créer?

De même, y a-t-il une affaire lorsque vous les laissez explicit explicitement à la fin de la procédure stockée est préférable de laisser SQL Server les nettoyer?

7
Akash

Sur la vérification de #tbl

Il ne peut pas blessé pour vérifier l'existence de la table (et le laisser tomber si elle existe) au début de la procédure, mais cela dépend de la façon dont vous Voulez-vous gérer ce scénario, et dans la plupart des cas, il n'est pas possible de l'exister de toute façon (au moins si nous parlons de même #TEMP tableau tel que défini dans cette procédure stockée).

Vous vérifiez l'existence d'une table en utilisant:

IF OBJECT_ID('tempdb..#tablename') IS NOT NULL

Vous ne pouvez pas vérifier templdb.sys.tables car le nom réel est #tablename__________some hex code, Et vous ne devez pas utiliser OBJECT_ID('...') > 0à cause de cela .

Bien sûr, il y a des exceptions. Deux qui viennent à l'esprit:

  • si vous appelez tout #temp ou #t ou #x, il est possible qu'un tel tableau existe déjà d'une portée extérieure avant d'appeler la procédure. Vous pouvez faire un cas que vous devriez simplement le laisser tomber et créer votre nouveau dans ce cas, mais vous pouvez également faire en sorte que ceci est une condition d'erreur que vous souhaitez connaître - alors peut-être que c'est bien que CREATE TABLE #x échoue.

  • vous pouvez réellement vouloir utiliser une table #TEpp créée dans une portée extérieure et en créer un seul s'il n'a pas été défini dans cette portée extérieure. C'est possible et j'utilise cette technique tout le temps, mais seulement lorsque je souhaite capturer des données à partir de procédures système que je ne peux pas me manipuler facilement (par exemple, sp_helptext). Donc, je pourrais faire cela:

    CREATE TABLE #x([Text] NVARCHAR(MAX));
    GO
    CREATE PROCEDURE dbo.myhelp @p SYSNAME
    AS
      INSERT #x EXEC sp_helptext @p;
    GO
    EXEC dbo.myhelp N'dbo.myhelp'; -- inception
    GO
    SELECT [Text] FROM #x;
    

    Cela fonctionne même si #x Est défini à l'extérieur. C'est un exemple terrible parce que je préférerais utiliser sys.sql_modules, Mais je suis sûr que vous obtenez le point et je peux envisager comment vous pourriez le faire avec vos propres procédures.

Sur la table de goutte #tbl;

Je pense que vous devriez explicitement supprimer des tables #TEpp à la fin de la procédure, c'est beaucoup au débat, et il serait donc fermé comme étant principalement basé sur l'opinion; Voir ces excellents poteaux de blogs par Paul White , lisez-les soigneusement et revenez et formulez une question spécifique si tous les vôtres ne répondent pas:

7
Aaron Bertrand

Je pense que cela dépend de la façon dont vous utilisez des tables TEMP. Si SELECT INTO est utilisé que je testerais avant et drop il à la fin. Les tests avant la main et la chute empêchent les problèmes indésirables sur la route qui peuvent ou non ramper, c'est juste une bonne pratique de code pour moi.

Si vous utilisez CREATE TABLE Pour créer d'abord la table Temp, je pense que je ferais la même chose juste à l'abri et essayant de conserver une norme quant à la manière dont je développe des procédures. Avec cela, vous pouvez probablement obtenir simplement avec simplement la déclaration de chute à la fin de la procédure, avez-vous vu du code effectué avec juste des gouttes à la fin.

Si vous êtes en équipe, ou même si c'est juste vous, faites une standard et tenez-y.

2
user507