SQL Server ВИБІРТЕ В @variable?


250

У мене є такий код в одній із моїх збережених програм Sql (2008), який виконує ідеально:

    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

Відповіді:


204

Ви не можете ВИБІРАТИ .. В ІНТИ .. СТОЛИ ЗМІННО. Найкраще ви можете створити його спочатку, а потім вставити в нього. Ваш другий фрагмент повинен бути

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

5
Слід зазначити, що це добре працює і в контексті CTE. Базінга!
Майкл Краукліс

4
У когось є відповідь, чому ви не можете вибрати в змінну таблиці, як ви можете, з фактичною тимчасовою таблицею?
KSwift87

504

Якщо ви хочете просто призначити деякі змінні для подальшого використання, ви можете зробити їх в один кадр із чимось у цих рядах:

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

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

Якщо це тип речі, яку ви хочете


1
Найкраще відповідь imho, але що станеться, якщо результатів більше, ніж одного?
capitano666

Якщо результатів більше, ніж один, ви отримаєте одне з доступних значень. Це могло скласти цікаву головоломку! Дивіться mssqltips.com/sqlservertip/1888/…
Смандолі

8
Щоб змусити запит повернути один рядок, використовуйте SELECT TOP 1
Adrian

1
@ Adrian Так, наведений вище запит передбачає, що ви вибрали один рядок. Ви також можете використовувати функції впорядкування та агрегування, якщо хочете більше фантазії.
dougajmcdonald

1
Якщо ви не використовуєте тип бази даних, який використовує ОП, не всі підтримують TOP 1, як згадував Адріан. SQL Server / MS Access використовують TOP, MySQL використовує LIMIT, а Oracle використовує ROWNUM. Додаткову інформацію див. У розділі w3schools.com/sql/sql_top.asp .
Тайлер

33

Ви можете це зробити:

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

то пізніше

SELECT CustomerId FROM #tempCustomer

вам не потрібно декларувати структуру #tempCustomer


3
@webturner Жодне з цих моментів не відповідає дійсності. Тимчасові таблиці не розміщуються за межами proc, а змінні таблиці більше не є "лише пам'яттю", ніж таблицями temp.
Мартін Сміт

7
Не забудьте додати те, DROP TABLE #tempCustomerколи #tempCustomerбільше не потрібно, інакше наступний вибір призведе до #tempCustomer already existsпомилки
ViRuSTriNiTy

15

Схоже, ваш синтаксис трохи вийшов. Це є кілька хороших прикладів

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
## temptable - поки власник (творець) не видалить його або не відключиться
RichardTheKiwi

4
Я не хочу тимчасових таблиць. Темп-таблиці - це дорого і повільно. Я просто хочу зберегти трохи даних для конкретного запису протягом невеликої кількості часу і зробити його доступним для декількох заяв sql, без подальших пошуків. Оскільки табличні змінні мають сферу застосування у збереженій програмі, в якій вони були визначені, вони є ідеальним рішенням для зберігання даних, зв'язаних у поєднанні, для цього одного виклику, що зберігається ...
bleepzter

3
Я також забув згадати, що БД проживає в Azure .... Я не хочу вводити безлад з управління тимчасовими таблицями.
bleepzter

Змінна таблиця - це шлях. оголосити @varTable Table (....)
ARLibertarian

1

Я знайшов ваше запитання, щоб шукати рішення тієї ж проблеми; а інші відповіді не вказують - це спосіб використовувати змінну для зміни назви таблиці для кожного виконання вашої процедури в постійній формі, а не тимчасовій.

Поки що я роблю, це об'єднати весь код SQL із змінними, які слід використовувати. Подобається це:

declare @table_name as varchar(30)
select @table_name = CONVERT(varchar(30), getdate(), 112)
set @table_name = 'DAILY_SNAPSHOT_' + @table_name

EXEC('
        SELECT var1, var2, var3
        INTO '+@table_name+'
        FROM my_view
        WHERE string = ''Strings must use double apostrophe''
    ');

Я сподіваюся, що це допомагає, але це може бути громіздко, якщо код занадто великий, тому, якщо ви знайшли кращий спосіб, будь ласка, поділіться!


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

Що означає створити нову @tempCustomerзмінну таблиці та вставити дані від Клієнта. Ви вже декларували це вище, тому не потрібно повторно заявляти. Краще поїхати

INSERT INTO @tempCustomer SELECT * FROM Customer

4
Це не працює. Ще потрібно заздалегідь оголосити змінну таблиці.
Йохан Буле
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.