SQL Server SELECT INTO @变量?


249

我的Sql(2008)Stored Procs之一具有以下代码,该代码执行得很好:

    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语句来初始化每个变量。

关于如何在不对同一张表进行多次查询的情况下实现某些目标的任何建议?


1
“创建单独的变量并通过单独的SELECT语句初始化每个变量”-为什么需要这样做?declare @t table一次,如果您需要重复使用它,DELETE @TempCustomer请先发射a,然后再重新插入其中
RichardTheKiwi 2011年

Answers:


204

您不能选择.. INTO ..表变量。最好的办法是首先创建它,然后将其插入。您的第二个片段必须是

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上下文中也很好。巴津加!
Michael Krauklis 2011年

4
任何人都有一个答案,为什么不能像实际的临时表那样选择表变量?
KSwift87 '16

503

如果您只想分配一些变量以备后用,则可以按照以下步骤一口气完成它们:

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

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

如果那是你所追求的事情


1
最好的答案,恕我直言,但是如果结果不止一个会怎样?
capitano666 '16

如果结果不止一个,则将获得可用值之一。这可能会引起一个有趣的难题!参见 mssqltips.com/sqlservertip/1888/…– Smandoli
'16

8
要强制查询返回单行,请使用SELECT TOP 1
Adrian

1
@Adrian是的,以上查询假设您选择了一行。如果您想要更多的精美逻辑,也可以使用排序和聚合函数。
dougajmcdonald

1
如果您不使用OP所使用的数据库类型,那么正如Adrian所说的那样,并非所有人都支持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之外,并且表变量比临时表不再“仅是内存”。
马丁·史密斯

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-直到所有者(创建者)将其删除或断开连接
为止

4
我不要临时表。临时表既昂贵又缓慢。我只想为特定记录保留少量数据一段时间,并使其可用于多个sql语句,而无需后续查找。由于表变量在定义它们的存储过程中具有作用域,因此它们是用于存储该存储过程调用的重复数据的理想解决方案...
bleepzter 2011年

3
我也忘记提及数据库驻留在Azure中。...我不想在管理临时表时引入混乱。
bleepzter 2011年

可变表是要走的路。声明@varTable表(....)
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
没用 您仍然需要事先声明表变量。
JohanBoulé16年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.