web-dev-qa-db-fra.com

La multiples instance de procédure peut-elle créer la même image #temp simultanément?

J'ai une procédure qui insère des données dans la table #Temp. Après avoir effectué certaines manipulations aux données, il stocke les données de #Temp Table à une autre table.

Je ne peux pas exécuter simultanément plusieurs instances de cette procédure. Pourquoi? Nous créons une table #Temp avec le même nom dans plusieurs onglets, puis pourquoi les instances multiples de la table TEMP sont-elles capables de faire de même?

Y a-t-il une solution?

Exemple:

--exec dbo.testing_temp_table
CREATE PROCEDURE [dbo].[testing_temp_table]
AS
BEGIN

    SET NOCOUNT ON;

    -- Insert statements for procedure here
    IF OBJECT_ID('tempdb..#temp_1') IS NOT NULL drop table #temp_1
    select  * into #temp_1 from dbo.Emp

END
2
RISHABH GOYAL

"Je ne peux pas exécuter simultanément plusieurs instances de cette procédure. Pourquoi?"

Que voulez-vous dire ne peut pas courir, si vous le faites, obtenez-vous une erreur? La fumée sort-elle du serveur?

Maintenant, vous n'avez pas besoin de vérifier l'existence de la table dans votre procédure stockée avec la chose si objet_id ().

SQL Server créera une instance de la table Temp par instance de la procédure stockée et ne sera visible que pour la création d'une étendue, qui est la procédure stockée dans ce cas et aux champs internes, tels que si vous appelez un autre sous- procédure dans votre code. Une fois la procédure terminée, la table temporaire sera partie.

Sous les couvertures, le processeur de requête ajoute une chaîne unique au nom de la table dans TEMPDB pour chaque instance.

Bol a tous les détails: Créer une table (transact-sql)

- En réponse au commentaire OP concernant la procédure stockée générant le même suffixe. - Vous n'abandonnez pas assez de crédit SQL Server ici. Si votre demande était vraie, cela aurait été un bug majeur qui aurait soulevé l'enfer, ne pouvant pas exécuter de multiples instances d'une procédure stockée qui utilise des tables TEMP.

Je soupçonne que vous le testez sur une seule connexion et que vous voyez que lors de la rééclusion du même proc, vous obtenez le même suffixe. Il s'agit d'une optimisation de la réutilisation des suffixes pour les exécutions répétées de la même session. Ce que vous devriez tester est:

CREATE PROCEDURE P 
AS
BEGIN
CREATE TABLE #T(Col1 INT);
WAITFOR DELAY '00:00:10';
SELECT * FROM TempDB.sys.tables;
END

Puis sur deux ou plusieurs liaisons, exécutez simultanément

EXEC P

Voici ce qui se pose pour moi:

name
#T____<Trimmed>_________000000000004
#T____<Trimmed>_________000000000005

Ht

7
SQLRaptor

Votre problème est la portée. @Sqlraptor est complètement correct dans sa réponse ci-dessus, mais cela pourrait aider si vous le regardez comme ceci:

Si vous créez une table Temp, il est spécifié à votre session. En d'autres termes, il existera jusqu'à ce que votre session soit fermée ou que vous le déposez. Ce que vous attendez, c'est que votre table TEMP soit définie sur votre procédure stockée (ce qui n'est pas le cas) comme une variable de table serait. Exemple:

-- Query window (otherwise known as session in this case)
Create #temp1 (temp table)
Create @temp1 (table variable)
     -- Run a stored procedure
     Create #temp2 (temp table)
     Create @temp2 (table variable)
     -- Currently all four exist.
-- On leaving the stored procedure the following exist:
-- #temp1
-- #temp2
-- @temp1
    -- Rerun the same stored procedure
    You attempt to create #temp2 but it fails because #temp2 still exists.

Maintenant, si vous quittez la session (fenêtre de la requête) entièrement, les toutes disparaissent.

Il existe également des tables Temps globales. Ceux avec ## au début. Celles-ci sont scopées à toutes les sessions et disparaîtront que lorsque personne ne les utilise plus.

Fondamentalement, à moins que vous prévoyez de réutiliser votre table temporaire pour une raison quelconque la goutte à la fin de votre sp. Donc comme ça:

--exec dbo.testing_temp_table
CREATE PROCEDURE [dbo].[testing_temp_table]
AS
BEGIN

    SET NOCOUNT ON;

    -- Insert statements for procedure here
    select  * into #temp_1 from dbo.Emp

    -- The rest of your code goes here

    DROP TABLE #temp_1
END
0
Kenneth Fisher