17

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、条件付きブロックでステートメントを実行することもできますが、テーブルには多くの列が含まれるため、効率的にしようとしていました。それが唯一の選択肢ですか?または、これを機能させる方法はありますか?

ありがとう、マット

4

9 に答える 9

18

回答が8年遅れましたが、誰も考えていないことに驚いています。

select * into #MyTempTable from...
where 1=2

IF -- CONDITION HERE
insert into #MyTempTable select...
ELSE
insert into #MyTempTable select...

シンプル、迅速、そしてそれは動作します。動的SQLは必要ありません

于 2018-02-15T17:46:04.560 に答える
14

あなたが抱えている問題は、一時テーブルにデータを入力しているということではなく、テーブルを作成しようとしているということです。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

ただし、一時テーブルは動的セッションの間だけ存続します。したがって、残念ながら、最初にテーブルを宣言してから、データを入力する必要があるようです。おそらく、記述してサポートするのが面倒なコードですが、十分に効率的に実行されます。

于 2010-11-11T19:06:40.777 に答える
4

あなたが提供するシナリオでは、これを行うことができます

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
于 2010-11-11T15:27:34.440 に答える
2

これは、一時テーブルを事前に作成できず、動的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
于 2018-12-28T17:01:05.230 に答える
1

これは古い問題ですが、ここに来る他の人にとっては:

ユーザーPhilipKelleyによって与えられた動的SQL回答は、ローカル一時テーブル(#Mytemp)では機能しません。##MyTemp実行できるのは、動的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

DROP ##MyTestTable
于 2017-07-26T09:49:50.913 に答える
0

このコードはあなたを助けるかもしれません

--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で機能するかどうかはわかりません。

于 2018-01-08T11:58:18.473 に答える
0

私はこれを試しました:

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に列を追加する必要がある場合に適しています。そうしないと、スクリプトを再実行する前に列を物理的に削除する必要があり、テスト条件が煩雑になります。

于 2019-04-26T13:03:13.543 に答える
0

このコードを試すことができます。

IF (CONDITION HERE)
       begin
           select * into #MyTempTable from tablename ....
       end
       ELSE
           truncate table #MyTempTable 
           insert into #MyTempTable 
           select * from tablename ....
       end

ありがとう!!!

于 2021-03-18T04:42:10.157 に答える
-1

どちらの場合も、テーブルを選択する前にテーブルを削除できます。例:

DECLARE @Id int 
SET @Id = 1  

IF (@Id = 2) BEGIN  
    IF OBJECT_ID('tempdb..#MyTestTable') IS NOT NULL DROP TABLE #MyTestTable
    SELECT 'ABC' AS Letters 
    INTO #MyTestTable; 
END ELSE BEGIN 
    IF OBJECT_ID('tempdb..#MyTestTable') IS NOT NULL DROP TABLE #MyTestTable 
    SELECT 'XYZ' AS Letters 
    INTO #MyTestTable; 
END 

コメント後の更新:

うざい。

2つの別々の一時テーブルはどうですか?次に、If / Elseログイン後、それぞれの存在を確認し、存在する場合は、3番目の一時テーブルを選択しますか?それはうまく機能しないかもしれませんが、それが重要かどうかは、これが何のために必要かによって異なります。

于 2010-11-11T15:29:18.373 に答える