Tables temporaires dans les procédures stockées
je me suis posé des questions sur les tables de temps dans les sp et comment tout cela peut affecter la concurrence. SP fait sur un serveur MSSQL 08.
Si j'ai un PS où je créer une table temporaire et de le déposer à nouveau comme ceci:
BEGIN
CREATE TABLE #MyTempTable
(
someField int,
someFieldMore nvarchar(50)
)
... Use of temp table here
... And then..
DROP TABLE #MyTempTable
END
ce SP sera appelé très souvent, donc ma question est peut-il jamais se produire des problèmes de concurrence ici?
7 réponses
Non. Des instances indépendantes de la table temporaire seront créées pour chaque connexion.
Peut-être.
les tables temporaires préfixées par un # (#example) sont conservées par session. Ainsi, si votre code appelle à nouveau la procédure stockée alors qu'un autre appel est en cours d'exécution (par exemple les threads en arrière-plan), alors l'appel create échouera car il est déjà là.
si vous êtes vraiment inquiet utilisez une variable de table à la place
DECLARE @MyTempTable TABLE
(
someField int,
someFieldMore nvarchar(50)
)
ceci sera spécifique à l '"instance" de cet appel de procédure stocké.
pas vraiment et je parle de SQL Server. La table temporaire (avec un seul #) existe et est visible à l'intérieur de la portée qu'elle est créée (liée à la portée). Chaque fois que vous appelez votre procédure stockée il crée une nouvelle portée et donc que la table temporaire n'existe que dans cette portée. Je crois que les tables de température sont également visibles pour les procédures stockées et udfs qui sont appelés dans cette portée aussi bien. Si vous utilisez cependant double pound ( # # ), alors ils deviennent globaux au sein de votre session et donc visibles pour autres processus d'exécution dans le cadre de la session dans laquelle la table temp est créée et vous devrez penser si la possibilité d'accéder à la table temp simultanément est souhaitable ou non.
pour tous ceux qui recommandent l'utilisation de variables de tableau, soyez prudent en le faisant. La variable Table ne peut pas être indexée, alors qu'une table temporaire peut l'être. Une variable de table est préférable lorsque vous travaillez avec de petites quantités de données, mais si vous travaillez sur des ensembles plus grands de données (par exemple 50K enregistrements) une table de température sera beaucoup plus rapide qu'une variable de table.
gardez également à l'esprit que vous ne pouvez pas compter sur un essai/Capture pour forcer un nettoyage dans la procédure stockée. certains types d'échecs ne peuvent pas être détectés dans un try/catch (par exemple compiler les échecs en raison de la résolution de nom retardée) si vous voulez être vraiment certain, vous pouvez avoir besoin de créer une procédure stockée wrapper qui peut faire un try/catch de la procédure stockée worker et faire le nettoyage là.
e.g. créer proc travailleur COMMENCER -- faire quelque chose ici Fin
create proc wrapper AS
BEGIN
Create table #...
BEGIN TRY
exec worker
exec worker2 -- using same temp table
-- etc
END TRY
END CATCH
-- handle transaction cleanup here
drop table #...
END CATCH
END
selon SQL Server 2008 livres Vous pouvez créer des tables temporaires locales et globales. Les tables temporaires locales ne sont visibles qu'à la session en cours, et les tables temporaires globales sont visibles à toutes les sessions.
' #table_temporal
'##table_global
si une table temporaire locale est créée dans une procédure stockée ou une application qui peut être exécutée en même temps par plusieurs utilisateurs, le moteur de base de données doit être capable de distinguer les tables créées par les différents utilisateurs. Le moteur de base de données le fait en ajoutant un suffixe numérique à chaque nom de table temporaire local.
alors il n'y a pas de problème.
la base de données utilise la même serrure pour toutes les tables #temp donc si vous utilisez beaucoup, vous aurez des problèmes d'impasse. Il est préférable d'utiliser les variables @ table pour la simultanéité.
utilisez les tables @ temp autant que possible--c'est-à-dire que vous n'avez besoin que d'une seule clé primaire et vous n'avez pas besoin d'accéder aux données à partir d'un proc stocké subordonné.
utilisez les tables # temp si vous avez besoin d'accéder aux données à partir d'un proc stocké subordonné (c'est une variable globale diabolique à la chaîne d'appel stockée proc) et vous n'avez aucun autre moyen propre de passer les données entre les procs stockés. Aussi l'utiliser si vous avez besoin d'un index secondaire (bien que, posez-vous vraiment si c'est une table #temp si vous avez besoin de plus index)
Si vous faites cela, toujours déclarer votre table #temp en haut de la fonction. SQL va forcer une recompilation de votre proc stocké quand il voit la déclaration de table créer....donc, si vous avez la déclaration #temp table au milieu du proc stocké, vous stocké proc doit arrêter le traitement et recompiler.