it-swarm.com.de

Überprüfen Sie, ob eine temporäre Tabelle vorhanden ist, und löschen Sie diese, bevor Sie eine temporäre Tabelle erstellen

Mit dem folgenden Code überprüfe ich, ob die temporäre Tabelle vorhanden ist, und lösche sie, bevor ich sie erneut erstelle. Es funktioniert einwandfrei, solange ich die Spalten nicht ändere. Wenn ich später eine Spalte hinzufüge, wird der Fehler "ungültige Spalte" angezeigt. Bitte lassen Sie mich wissen, was ich falsch mache.

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

Ich kann den Fehler nicht reproduzieren.

Vielleicht verstehe ich das Problem nicht.

Das Folgende funktioniert in SQL Server 2005 einwandfrei, wobei die zusätzliche Spalte "foo" im zweiten Auswahlergebnis angezeigt wird:

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

Die Aussage sollte in der Reihenfolge sein

  1. Ändern Sie die Anweisung für die Tabelle
  2. GEHEN
  3. Anweisung auswählen.

Ohne 'GO' dazwischen wird das Ganze als ein einziges Skript betrachtet und wenn die select-Anweisung nach der Spalte sucht, wird sie nicht gefunden.

Mit 'GO' wird der Teil des Skripts bis zu 'GO' als ein einzelner Stapel betrachtet und ausgeführt, bevor die Abfrage nach 'GO' ausgeführt wird.

72
SDS

Anstatt dropping und die temporäre Tabelle neu zu erstellen, können Sie truncate und sie wiederverwenden

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

Wenn Sie Sql Server 2016 oder Azure Sql Database verwenden, verwenden Sie die folgende Syntax, um die temporäre Tabelle zu löschen und neu zu erstellen. Mehr Infos hier MSDN

Syntax

DROP TABLE [WENN EXISTS] [Datenbankname. [schema_name]. | schema_name. ] Tabellenname [ ... n]

Abfrage:

DROP TABLE IF EXISTS tempdb.dbo.#Results
CREATE TABLE #Results
  (
   Company             CHAR(3),
   StepId              TINYINT,
   FieldId             TINYINT,
  )
51

Ich denke, das Problem ist, dass Sie eine GO-Anweisung dazwischen hinzufügen müssen, um die Ausführung in Batches zu unterteilen. Da das zweite Drop-Skript, d. H. IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results, die temporäre Tabelle nicht als Teil eines einzelnen Stapels gelöscht hat. Können Sie bitte das folgende Skript versuchen.

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

Dies hat bei mir funktioniert: 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

Nur ein kleiner Kommentar von meiner Seite, da der OBJECT_ID bei mir nicht funktioniert. Das gibt es immer wieder

`#tempTable existiert nicht

..auch obwohl es existiert. Ich habe gerade herausgefunden, dass es unter einem anderen Namen gespeichert ist (der durch _ unterstrichen wurde):

#tempTable________

Das funktioniert gut für mich:

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

pmac72 verwendet GO, um die Abfrage in Stapel aufzuteilen und ein ALTER zu verwenden.

Offenbar wird derselbe Stapel ausgeführt, nach dem Ändern wird er jedoch zweimal ausgeführt: DROP ... CREATE ... edit ... DROP ... CREATE ..

Hinterlasse vielleicht deinen genauen Code, damit wir sehen können, was los ist.

10
gbn

Dies könnte mit einer einzigen Codezeile erreicht werden:

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

Normalerweise ist dieser Fehler aufgetreten, wenn ich die temporäre Tabelle bereits erstellt habe. Der Code, der die SQL-Anweisung auf Fehler überprüft, erkennt die "alte" temporäre Tabelle und gibt eine falsche Anzahl von Spalten in späteren Anweisungen zurück, als ob die temporäre Tabelle niemals gelöscht worden wäre.

Löschen Sie die Tabelle, nachdem Sie die Anzahl der Spalten in einer temporären Tabelle geändert haben, nachdem Sie bereits eine Version mit weniger Spalten erstellt haben, und führen Sie dann Ihre Abfrage aus.

7
Jacob Griffin

Jetzt können Sie die folgende Syntax verwenden, wenn Sie eine der neuen Versionen von SQL Server (2016+) verwenden.

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

Ich habe kürzlich von einem DBA etwas Ähnliches gesehen:

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

Mein Code verwendet eine Source Tabelle, die sich ändert, und eine Destination Tabelle, die diesen Änderungen entsprechen muss.

-- 
-- 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

Ja, "ungültige Spalte", dieser Fehler wurde in der Zeile "select company, stepid, fieldid, NewColumn from #Results" ausgelöst.

Es gibt zwei Phasen, in denen t-sql ausgeführt wird:

zunächst prüft der SQL-Server beim Parsen in dieser Phase die Korrektur der von Ihnen übermittelten SQL-Zeichenfolge, einschließlich der Tabellenspalte, und optimiert Ihre Abfrage für den schnellsten Abruf.

zweitens: Ausführen und Abrufen der Daten.

Wenn die Tabelle #Results existiert, prüft der Parsing-Prozess, ob die von Ihnen angegebenen Spalten gültig sind oder nicht. Andernfalls (Tabelle existiert nicht) wird das Parsing anhand der von Ihnen angegebenen Prüfspalten durchgeführt.

0
pnbps