2011-01-28 5 views
183

У меня есть следующий код в одном из моих Sql (2008) хранимыми Procs, который выполняет прекрасно:SQL Server SELECT INTO @variable?

CREATE PROCEDURE [dbo].[Item_AddItem] 
     @CustomerId uniqueidentifier, 
     @Description nvarchar(100), 
     @Type int, 
     @Username nvarchar(100), 
    AS 
    BEGIN 

     DECLARE @TopRelatedItemId uniqueidentifier; 
     SET @TopRelatedItemId = 
     (
      SELECT top(1) RelatedItemId 
      FROM RelatedItems 
      WHERE CustomerId = @CustomerId 
     ) 

     DECLARE @TempItem TABLE 
     (
      ItemId uniqueidentifier, 
      CustomerId uniqueidentifier, 
      Description nvarchar(100), 
      Type int, 
      Username nvarchar(100), 
      TimeStamp datetime 
     ); 

     INSERT INTO Item 
     OUTPUT INSERTED.* INTO @TempItem 
     SELECT NEWID(), @CustomerId, @Description, @Type, @Username, GETDATE() 

     SELECT 
      ItemId, 
      CustomerId, 
      @TopRelatedItemId, 
      Description, 
      Type, 
      Username, 
      TimeStamp 
     FROM 
      @TempItem 
END 
GO 

Так что вопрос для вас, ребята, это есть возможность сделать что-то вдоль линий:

DECLARE @TempCustomer TABLE 
(
    CustomerId uniqueidentifier, 
    FirstName nvarchar(100), 
    LastName nvarchar(100), 
    Email nvarchar(100) 
); 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
INTO 
    @TempCustomer 
FROM 
    Customer 
WHERE 
    CustomerId = @CustomerId 

Чтобы можно было повторно использовать эти данные из памяти в других следующих операциях? SQL Server бросает соответствие с вышеуказанным оператором, однако я не хочу создавать отдельные переменные и инициализировать каждую из них с помощью отдельного оператора SELECT в той же таблице .... UGH !!!

Любые предложения о том, как добиться чего-то вдоль линий без нескольких запросов к одной таблице?

+1

«создать отдельные переменные и инициализировать каждую из них с помощью отдельного оператора SELECT» - зачем вам это нужно? 'declare @t table' один раз, и если вам нужно его повторно использовать, запустите' DELETE @ TempCustomer', прежде чем вставлять в него снова. – RichardTheKiwi

ответ

165

Вы не можете выбрать .. В ... ТАБЛИЦУ ПЕРЕМЕННОГО. Лучшее, что вы можете сделать, это создать его сначала, а затем вставить в него. Ваш второй фрагмент должен быть

DECLARE @TempCustomer TABLE 
(
    CustomerId uniqueidentifier, 
    FirstName nvarchar(100), 
    LastName nvarchar(100), 
    Email nvarchar(100) 
); 
INSERT INTO 
    @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer 
WHERE 
    CustomerId = @CustomerId 
+4

Следует учитывать, что это прекрасно работает и в контексте CTE. Bazinga! –

+2

У каждого есть ответ на * почему * нельзя выбрать в таблицу переменную, как вы можете, с помощью временной таблицы? – KSwift87

13

Похоже, ваш синтаксис слегка вышел из строя. Это имеет некоторые good examples

DECLARE @TempCustomer TABLE 
(
    CustomerId uniqueidentifier, 
    FirstName nvarchar(100), 
    LastName nvarchar(100), 
    Email nvarchar(100) 
); 
INSERT @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer 
WHERE 
    CustomerId = @CustomerId 

Позже

SELECT CustomerId FROM @TempCustomer 
2

Похоже, вы хотите временные таблицы. http://www.sqlteam.com/article/temporary-tables

Обратите внимание, что #TempTable доступен на всей вашей SP.

Обратите внимание, что ## TempTable доступен для всех.

+2

## соблазнительно - пока владелец (создатель) не удалит его или не отключится – RichardTheKiwi

+3

Мне не нужны временные таблицы. Таблицы Temp являются дорогостоящими и медленными. Я просто хочу сохранить немного данных для определенной записи за небольшой промежуток времени и сделать ее доступной для нескольких операторов sql без последующего поиска. Поскольку переменные таблицы имеют область видимости в хранимой процедуре, в которой они были определены, они являются идеальным решением для хранения искаженных данных для одного сохраненного вызова proc ... – bleepzter

+3

Я также забыл упомянуть, что БД находится в Azure .... Я не знаю Не хотите вводить беспорядок из управления временными таблицами. – bleepzter

21

вы можете сделать это:

SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
INTO #tempCustomer 
FROM 
    Customer 
WHERE 
    CustomerId = @CustomerId 

потом

SELECT CustomerId FROM #tempCustomer 

вам не нужно объявить структуру #tempCustomer

+3

@webturner Ни одна из этих точек не верна. Таблицы Temp не ограничены пределами переменных proc и таблицы, а не являются «только памятью», чем временными таблицами. –

+0

@MartinSmith Я стою исправлен, комментарий удален. –

+3

Не забудьте добавить 'DROP TABLE # tempCustomer', когда' # tempCustomer' больше не нужен, иначе следующий выбор приведет к ошибке '#tempCustomer уже существует' – ViRuSTriNiTy

384

Если вы хотели просто присвоить некоторые переменные позже вы можете сделать их одним выстрелом с чем-то в этом направлении:

declare @var1 int,@var2 int,@var3 int; 

select 
    @var1 = field1, 
    @var2 = field2, 
    @var3 = field3 
from 
    table 
where 
    condition 

Если это тип вещи вы после

+1

Лучший ответ imho, но что произойдет, если результаты будут более чем один? – capitano666

+0

Если результаты более одного, вы получите одно из доступных значений. Это может сделать интересную головоломку! См. Https://www.mssqltips.com/sqlservertip/1888/when-to-use-set-vs-select-when-assigning-values-to-variables-in-sql-server – Smandoli

+5

Чтобы заставить запрос возвратить использование одной строки SELECT TOP 1 – Adrian

-1
"SELECT * 
    INTO 
    @TempCustomer 
FROM 
    Customer 
WHERE 
    CustomerId = @CustomerId" 

Что означает создание нового @tempCustomer tablevariable и вставки данных от клиента. Вы уже заявили об этом выше, поэтому не нужно снова объявлять. Лучше пойти с

INSERT INTO @tempCustomer SELECT * FROM Customer 
+1

Не работает. Вам все равно нужно заранее объявить переменную таблицы. –

Смежные вопросы