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
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
La déclaration devrait être de l'ordre
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'.
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,
)
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
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;
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;
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.
Cela pourrait être accompli avec une seule ligne de code:
IF OBJECT_ID('tempdb..#tempTableName') IS NOT NULL DROP TABLE #tempTableName;
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.
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 #...)
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)
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
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é.