web-dev-qa-db-ja.com

一時表を作成する前に、一時表が存在するかどうかを確認し、存在する場合は削除します。

次のコードを使用して、一時テーブルが存在するかどうかを確認し、存在する場合は再度作成する前にそのテーブルを削除します。列を変更しない限り、うまくいきます。後で列を追加すると、「無効な列」というエラーが表示されます。何が悪いのか教えてください。

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

エラーを再現できません。

おそらく私はその問題を理解していません。

次のSQL Server 2005では、2番目の選択結果に余分な "foo"列が表示されますが、これは問題ありません。

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

文は次のようなものです。

  1. 表に対するステートメントの変更
  2. GO
  3. 選択ステートメント.

間に「GO」がないと、全体が1つのスクリプトと見なされ、selectステートメントが列を探すときには見つかりません。

'GO'を指定すると、スクリプトの 'GO'までの部分を1つの単一のバッチと見なし、 'GO'の後にクエリに入る前に実行されます。

68
SDS

droppingとtempテーブルを再作成する代わりに、truncateとそれを再利用することができます。

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

Sql Server 2016またはAzure Sql Databaseを使用している場合は、次の構文を使用して一時テーブルを削除して再作成してください。詳細情報はこちら _ msdn _

構文

DROP TABLE [IF EXISTS] [データベース名。 [schema_name]。 | schema_name。 ] table_name [、... n]

クエリ:

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

問題は、実行をバッチに分割するために、間にGOステートメントを追加する必要があることです。 2番目のドロップスクリプト、すなわちIF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Resultsは単一バッチの一部である一時テーブルをドロップしませんでした。下記のスクリプトを試してください。

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

これは私のために働いた: 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;
27
user219628

OBJECT_IDが私のために働かないので私の側からのほんの少しのコメント。それはいつもそれを返します

`#tempTableが存在しません

は存在しますが はありますが。私はちょうどそれが次のように別の名前で保存されているのを見つけました(_の下線が付いています)。

#tempTable________

これは私にはうまくいきます:

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

pmac72は、クエリをバッチに分割してALTERを使用するためにGOを使用しています。

同じバッチを実行しているように見えますが、変更後に2回実行しています。DROP ... CREATE ... edit ... DROP ... CREATE ..

おそらくあなたの exact コードをポストして、何が起こっているのかを見ることができます。

10
gbn

一時テーブルがすでに作成されていると、通常このエラーが発生します。 SQLステートメントのエラーをチェックするコードでは、「古い」一時テーブルが所定の位置にあることが確認され、一時テーブルが削除されなかった場合と同様に、後のステートメントの列数の誤カウントが返されます。

列数の少ないバージョンを作成した後に一時テーブルの列数を変更した後は、そのテーブルを削除してからクエリを実行してください。

6
Jacob Griffin

私は最近DBAがこれに似たことをするのを見ました:

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

SSMSの新しいバージョンを使用している場合は、次の構文を使用できます。

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

私のコードは変更するSourceテーブルとそれらの変更にマッチしなければならないDestinationテーブルを使います。

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

はい、「無効な列」このエラーは「select company、stepid、fieldid、#ResultsのNewColumn」の行から発生しました。

T-sqlを実行するには2つの段階があります。

まず、構文解析、このフェーズでは、SQL Serverはテーブルの列を含むSQL文字列をサブミットしたあなたの修正をチェックし、最速の検索のためにクエリを最適化しました。

次に、データを取得して実行します。

テーブル#Resultsが存在する場合、解析プロセスはあなたが指定したカラムが有効かどうかチェックします。そうでなければ(テーブルは存在しません)解析はあなたが指定したようにチェックカラムを通過します。

0
pnbps

これは1行のコードで実現できます。

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