SQL 2005の条件の結果に基づいて一時テーブルにデータを入力しようとしています。一時テーブルはどちらの方法でも同じ構造になりますが、条件に応じて異なるクエリを使用してデータが入力されます。以下の簡略化されたサンプルスクリプトは、ELSE
ブロックINSERT INTO
の構文チェックに失敗し、次のエラーが発生します。
データベースには「#MyTestTable」という名前のオブジェクトがすでに存在します。
DECLARE @Id int
SET @Id = 1
IF OBJECT_ID('tempdb..#MyTestTable') IS NOT NULL DROP TABLE #MyTestTable
IF (@Id = 2) BEGIN
SELECT 'ABC' AS Letters
INTO #MyTestTable;
END ELSE BEGIN
SELECT 'XYZ' AS Letters
INTO #MyTestTable;
END
IF/ELSE
ステートメントの前に一時テーブルを作成してから、条件付きブロックでINSERT SELECT
ステートメントを実行することもできますが、テーブルには多くの列があり、効率的にしようとしていました。それが唯一の選択肢ですか?または、これを機能させる方法はありますか?
ありがとう、マット
あなたが抱えている問題は、一時テーブルにデータを入力しているということではなく、createテーブルを作成しようとしているということです。 SQLはスクリプトを解析し、2つの異なる場所でスクリプトを作成しようとしていることを検出したため、エラーが発生します。 「実行パス」が両方の作成ステートメントにヒットする可能性がないことを理解するのは賢明ではありません。動的SQLの使用は機能しません。私は試した
DECLARE @Command varchar(500)
DECLARE @Id int
SET @Id = 2
IF OBJECT_ID('tempdb..#MyTestTable') IS NOT NULL DROP TABLE #MyTestTable
IF (@Id = 2) BEGIN
SET @Command = 'SELECT ''ABC'' AS Letters INTO #MyTestTable'
END ELSE BEGIN
SET @Command = 'SELECT ''XYZ'' AS Letters INTO #MyTestTable'
END
EXECUTE (@Command)
select * from #MyTestTable
ただし、一時テーブルは動的セッションの間だけ存続します。したがって、残念ながら、最初にテーブルを宣言してから、データを入力する必要があるようです。おそらく、記述してサポートするのが面倒なコードですが、十分に効率的に実行されます。
8年遅れて答えましたが、誰も考えなかったことに驚いています。
select * into #MyTempTable from...
where 1=2
IF -- CONDITION HERE
insert into #MyTempTable select...
ELSE
insert into #MyTempTable select...
シンプル、迅速、そしてそれは機能します。動的SQLは必要ありません
あなたが提供するシナリオでは、これを行うことができます
DECLARE @Id int
SET @Id = 1
IF OBJECT_ID('tempdb..#MyTestTable') IS NOT NULL DROP TABLE #MyTestTable
SELECT
CASE WHEN (@Id = 2)
THEN 'ABC'
ELSE 'XYZ'
END AS Letters
INTO #MyTestTable;
ただし、それ以外の場合は、このようにif statement
の前にテーブルを作成する必要があります
Create Table #MyTestTable (
MyValue varchar(3)
)
IF (@Id = 2) BEGIN
Insert Into (MyValue)
SELECT 'ABC' AS Letters;
END ELSE BEGIN
Insert Into (MyValue)
SELECT 'XYZ' AS Letters;
END
これは、一時テーブルを事前に作成できず、動的SQLにコアロジックを配置したくない場合に使用するソリューションです。
IF 1 = 1 -- Replace with actual condition
BEGIN
SELECT * INTO #tmp1 FROM dbo.Table1
END
ELSE
BEGIN
SELECT * INTO #tmp2 FROM dbo.Table2
END
-- Inserting data into global temp table so sql server can't complain on not recognizing in a context
DECLARE @Command VARCHAR(MAX)
IF OBJECT_ID('tempdb..#tmp1') IS NOT NULL
BEGIN
SET @Command = 'SELECT * INTO ##tmp FROM #tmp1'
END
ELSE
BEGIN
SET @Command = 'SELECT * INTO ##tmp FROM #tmp2'
END
EXECUTE(@Command)
SELECT * INTO #tmpFinal FROM ##tmp -- Again passing data back to local temp table from global temp table to avoid seeing red mark
IF OBJECT_ID('tempdb..##tmp') IS NOT NULL DROP TABLE ##tmp
IF OBJECT_ID('tempdb..#tmp1') IS NOT NULL DROP TABLE #tmp1
IF OBJECT_ID('tempdb..#tmp2') IS NOT NULL DROP TABLE #tmp2
SELECT * FROM #tmpFinal
IF OBJECT_ID('tempdb..#tmpFinal') IS NOT NULL DROP TABLE #tmpFinal
このコードはあなたを助けるかもしれません
--creating temptable using columns of two existing tables
--you can create your temp table Using other methods
select top 0 VI.*,VU.FullName
into #mytemptable
from dbo.Items VI inner join
dbo.Users as VU
on VU.Id=VI.Id
--insert your data base on your condition
if(i<2) --First Condition
begin
INSERT INTO #mytemptable
SELECT VI.*,VU.FullName
from dbo.Items VI inner join
dbo.Users as VU
on VU.Id=VI.Id
end
Else if(2<i) --Second Condition
begin
INSERT INTO #mytemptable
SELECT VI.*,VU.FullName
from dbo.Items VI inner join
dbo.Users as VU
on VU.Id=VI.Id
end
select * from #mytemptable --show result
drop table #mytemptable --drop table if its needed
このコードはSQLServer2014で機能します。SQL2005で機能するかどうかはわかりません。
私はこれを試しました:
SELECT S1.* INTO #MytestTable
FROM
( SELECT 'ABC' AS Letters WHERE 1 = CASE @Id=2 THEN 1 ELSE 2 END
UNION
SELECT 'XYZ' AS Letters WHERE 1 = CASE @Id=1 THEN 1 ELSE 2 END
) AS S1
このソリューションは、後で#MyTestTableに列を追加する必要がある場合に適しています。そうしないと、スクリプトを再実行する前に列を物理的に削除する必要があり、テスト条件が煩わしくなります。
これは古い問題ですが、ここに来る他の人にとっては:
ユーザーPhilipKelleyによって与えられた動的SQLの回答は、ローカル一時テーブルでは機能しません(#Mytemp
)。できることは、動的SQLを作成して、それをグローバル一時テーブル(##MyTemp
)後で削除できます。
DECLARE @Command varchar(500)
DECLARE @Id int
SET @Id = 2
IF OBJECT_ID('tempdb..#MyTestTable') IS NOT NULL DROP TABLE ##MyTestTable
IF (@Id = 2) BEGIN
SET @Command = 'SELECT ''ABC'' AS Letters INTO ##MyTestTable'
END ELSE BEGIN
SET @Command = 'SELECT ''XYZ'' AS Letters INTO ##MyTestTable'
END
EXECUTE (@Command)
select * from ##MyTestTable
DROP ##MyTestTable