SQL Insert во временную таблицу в блоках If и Else

Я пытаюсь заполнить временную таблицу на основе результата условия в 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

я мог бы создать temp стол перед IF/ELSE заявление, а затем просто сделать INSERT SELECT операторы в условных блоках, но в таблице будет много столбцов, и я пытался быть эффективным в этом. Это единственный вариант? Или есть какой-то способ заставить это работать?

спасибо, Мэтт!--6-->

6 ответов


проблема заключается не в том, что вы заполняете временную таблицу, а в том, что вы пытаетесь создать столе. SQL анализирует ваш скрипт и обнаруживает, что вы пытаетесь создать его в двух разных местах, и поэтому вызывает ошибку. Недостаточно умен, чтобы понять, что "путь выполнения" не может поразить оба состояния create. Использование динамического 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

но временная таблица длится только до тех пор, пока динамическая сессия. Так что, увы, похоже, вам придется сначала объявить таблицу, а затем заполнить его. Неудобный код для написания и поддержки, возможно, но он будет работать достаточно эффективно.


в сценарии, который вы предоставляете, вы можете сделать это

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

отвечая 8 лет спустя, но я удивлен, что никто не подумал:

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

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

простой, быстрый, и он работает. Не требуется динамический sql


Это старый вопрос, но для всех, кто приходит сюда:

динамический ответ SQL, данный пользователем Philip Kelley, не работает для локальных временных таблиц (#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

этот код может помочь вам

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

этот код работает в sql server 2014 я не знаю, работает ли он в sql 2005 или нет


вы можете удалить таблицу, прежде чем выбрать ее в обоих случаях. например:

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 

Обновление После Комментария:

это раздражает.

Как насчет двух отдельных временных таблиц? Затем после входа в If/Else проверьте наличие каждого из них, и если он существует, выберите в третью временную таблицу? Это может быть не очень хорошо, но имеет ли это значение или нет, зависит от того, для чего вам это нужно.