web-dev-qa-db-fra.com

Vérifier si une table temporaire existe et supprimer si elle existe avant de créer une table temporaire

J'utilise le code suivant pour vérifier si la table temporaire existe et supprimer la table si elle existe avant de créer à nouveau. Cela fonctionne bien tant que je ne change pas les colonnes. Si j'ajoute une colonne plus tard, cela donnera une erreur disant "colonne invalide". S'il vous plaît laissez-moi savoir ce que je fais mal.

IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    DROP TABLE #Results

CREATE TABLE #Results
(
    Company                CHAR(3),
    StepId                TINYINT,
    FieldId                TINYINT,
)

select company, stepid, fieldid from #Results

--Works fine to this point

IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    DROP TABLE #Results

CREATE TABLE #Results
(
    Company                CHAR(3),
    StepId                TINYINT,
    FieldId                TINYINT,
    NewColumn            NVARCHAR(50)
)

select company, stepid, fieldid, NewColumn from #Results

--Does not work
609
Sridhar

Je ne peux pas reproduire l'erreur.

Peut-être que je ne comprends pas le problème.

Ce qui suit me convient parfaitement dans SQL Server 2005, avec la colonne supplémentaire "foo" qui apparaît dans le deuxième résultat de sélection:

IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
GO
CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT )
GO
select company, stepid, fieldid from #Results
GO
ALTER TABLE #Results ADD foo VARCHAR(50) NULL
GO
select company, stepid, fieldid, foo from #Results
GO
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
GO
676
pmac72

La déclaration devrait être de l'ordre

  1. Modifier l'instruction pour la table
  2. ALLER
  3. Sélectionnez une déclaration.

Sans 'GO' entre les deux, le tout sera considéré comme un seul script et lorsque l'instruction select recherchera la colonne, elle ne sera pas trouvée.

Avec 'GO', il considérera la partie du script allant jusqu'à 'GO' comme un seul lot et s'exécutera avant d'entrer dans la requête après le mot 'GO'.

72
SDS

Au lieu de dropping et de recréer la table temporaire, vous pouvez truncate et le réutiliser.

IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    Truncate TABLE #Results
else
    CREATE TABLE #Results
    (
        Company             CHAR(3),
        StepId              TINYINT,
        FieldId             TINYINT,
    )

Si vous utilisez Sql Server 2016 ou Azure Sql Database, utilisez la syntaxe ci-dessous pour supprimer la table temporaire et la recréer. Plus d'infos ici MSDN

Syntaxe

DROP TABLE [IF EXISTS] [nom_bdd. [nom_schéma]. | nom_schéma. ] nom_table [ ... n]

Requête:

DROP TABLE IF EXISTS tempdb.dbo.#Results
CREATE TABLE #Results
  (
   Company             CHAR(3),
   StepId              TINYINT,
   FieldId             TINYINT,
  )
51
Pரதீப்

Je pense que le problème est que vous devez ajouter une instruction GO entre les deux pour séparer l'exécution en lots. En tant que deuxième script de suppression, IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results n'a pas supprimé la table temporaire faisant partie d'un seul lot. Pouvez-vous s'il vous plaît essayer le script ci-dessous.

IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    DROP TABLE #Results

CREATE TABLE #Results
(
    Company                CHAR(3),
    StepId                TINYINT,
    FieldId                TINYINT,
)

GO

select company, stepid, fieldid from #Results

IF OBJECT_ID('tempdb..#Results') IS NOT NULL
DROP TABLE #Results

CREATE TABLE #Results
(
    Company                CHAR(3),
    StepId                TINYINT,
    FieldId                TINYINT,
    NewColumn            NVARCHAR(50)
)

GO

select company, stepid, fieldid, NewColumn from #Results
49
vikas

Cela a fonctionné pour moi: social.msdn.Microsoft.com/Forums/en/transactsql/thread/02c6da90-954d-487d-a823-e24b891ec1b0?prof=required

if exists (
    select  * from tempdb.dbo.sysobjects o
    where o.xtype in ('U') 

   and o.id = object_id(N'tempdb..#tempTable')
)
DROP TABLE #tempTable;
28
user219628

Juste un petit commentaire de mon côté puisque le OBJECT_ID ne fonctionne pas pour moi. Il retourne toujours que

`#tempTable n'existe pas

..même si elle existe existe. Je viens de trouver qu'il est stocké avec un nom différent (postfixé par _ underscores) comme ceci:

#tempTable________

Cela fonctionne bien pour moi:

IF EXISTS(SELECT [name] FROM tempdb.sys.tables WHERE [name] like '#tempTable%') BEGIN
   DROP TABLE #tempTable;
END;
17
Ivan Sivak

pmac72 utilise GO pour scinder la requête en lots et utilise ALTER.

Vous semblez exécuter le même lot mais l'exécuter deux fois après l'avoir changé: DROP ... CREATE ... edit ... DROP ... CREATE ..

Peut-être poster votre code exact afin que nous puissions voir ce qui se passe.

10
gbn

Cela pourrait être accompli avec une seule ligne de code:

IF OBJECT_ID('tempdb..#tempTableName') IS NOT NULL DROP TABLE #tempTableName;   
8
S Krishna

Je frappe généralement cette erreur quand j'ai déjà créé la table temporaire; le code qui vérifie les erreurs dans l'instruction SQL voit "l'ancienne" table temporaire en place et renvoie un montant erroné sur le nombre de colonnes des instructions ultérieures, comme si la table temporaire n'avait jamais été supprimée.

Après avoir modifié le nombre de colonnes dans une table temporaire après avoir déjà créé une version comportant moins de colonnes, supprimez la table et exécutez votre requête.

7
Jacob Griffin

Vous pouvez maintenant utiliser la syntaxe ci-dessous si vous utilisez l'une des nouvelles versions de SQL Server (2016+).

DROP TABLE IF EXISTS schema.yourtable(even temporary tables #...)
5

J'ai récemment vu un administrateur de base faire quelque chose de similaire à ceci:

begin try
    drop table #temp
end try

begin catch 
    print 'table does not exist'
end catch 

create table #temp(a int, b int)
4
anonxen

Mon code utilise une table Source qui change et une table Destination qui doit correspondre à ces modifications.

-- 
-- Sample SQL to update only rows in a "Destination" Table
--  based on only rows that have changed in a "Source" table
--


--
-- Drop and Create a Temp Table to use as the "Source" Table
--
IF OBJECT_ID('tempdb..#tSource') IS NOT NULL drop table #tSource
create table #tSource (Col1 int, Col2 int, Col3 int, Col4 int)

--
-- Insert some values into the source
--
Insert #tSource (Col1, Col2, Col3, Col4) Values(1,1,1,1)
Insert #tSource (Col1, Col2, Col3, Col4) Values(2,1,1,2)
Insert #tSource (Col1, Col2, Col3, Col4) Values(3,1,1,3)
Insert #tSource (Col1, Col2, Col3, Col4) Values(4,1,1,4)
Insert #tSource (Col1, Col2, Col3, Col4) Values(5,1,1,5)
Insert #tSource (Col1, Col2, Col3, Col4) Values(6,1,1,6)

--
-- Drop and Create a Temp Table to use as the "Destination" Table
--
IF OBJECT_ID('tempdb..#tDest') IS NOT NULL drop Table #tDest
create table #tDest (Col1 int, Col2 int, Col3 int, Col4 int)

--
-- Add all Rows from the Source to the Destination
--
Insert #tDest
Select Col1, Col2, Col3, Col4 from #tSource


--
-- Look at both tables to see that they are the same
--
select *
from #tSource
Select *
from #tDest

--
-- Make some changes to the Source
--
update #tSource
    Set Col3=19
    Where Col1=1
update #tSource
    Set Col3=29
    Where Col1=2
update #tSource
    Set Col2=38
    Where Col1=3
update #tSource
    Set Col2=48
    Where Col1=4

--
-- Look at the Differences
-- Note: Only 4 rows are different. 2 Rows have remained the same.
--
Select Col1, Col2, Col3, Col4
from #tSource
except
Select Col1, Col2, Col3, Col4
from #tDest

--
-- Update only the rows that have changed
-- Note: I am using Col1 like an ID column
--
Update #tDest
    Set Col2=S.Col2,
        Col3=S.Col3,
        Col4=S.Col4
From    (   Select Col1, Col2, Col3, Col4
            from #tSource
            except
            Select Col1, Col2, Col3, Col4
            from #tDest
        ) S
Where #tDest.Col1=S.Col1 

--
-- Look at the tables again to see that
--  the destination table has changed to match
--  the source table.

select *
from #tSource
Select *
from #tDest

--
-- Clean Up
--
drop table #tSource
drop table #tDest
3
Mike Lewis

Oui, "colonne non valide", cette erreur est générée à partir de la ligne "sélectionnez la société, stepid, fieldid, NewColumn from #Results".

Il y a deux phases de fonctionnement t-sql,

tout d’abord, lors de l’analyse, dans cette phase, le serveur SQL vérifie la correction de la chaîne SQL que vous avez soumise, y compris la colonne de la table, et optimise votre requête pour une récupération plus rapide.

deuxièmement, en cours d'exécution, en récupérant les données.

Si la table #Results existe, le processus d'analyse vérifie si les colonnes spécifiées sont correctes ou non. Sinon, l'analyse (la table n'existe pas) sera analysée en passant les colonnes de vérification comme spécifié.

0
pnbps