如何在TSQL中定义临时表(或表变量)而不定义模式?

41
有没有一种方法可以在不预先定义其模式的情况下定义临时表?
3个回答

42

实际上,使用一个表变量,即内存中的表,是最优方式。#table会在temp db中创建一个表,而##table是全局的——两者都需要磁盘操作。考虑到事务数量所带来的减速和负担。

CREATE PROCEDURE [dbo].[GetAccounts] 
    @AccountID BIGINT,
    @Result INT OUT,
    @ErrorMessage VARCHAR(255) OUT
AS
BEGIN
    SET NOCOUNT ON;
    SET @Result = 0
    SET @ErrorMessage = ''

    DECLARE @tmp_Accounts TABLE (
                                                AccountId BIGINT,
AccountName VARCHAR(50),
...
)

INSERT INTO @tmp_Accounts ([AccountId], [AccountName]...
)
SELECT AccountID, AccountName
FROM Accounts
WHERE  ...


    IF @@Rowcount = 0
        BEGIN
            SET @ErrorMessage = 'No accounts found.'
            SET @Result = 0

            RETURN @Result
        END
    ELSE
        BEGIN
            SET @Result = 1

            SELECT *
            FROM @tmp_Accounts
        END 

注意你向临时表中插入数据的方式。

这种方法的缺点是可能需要较长时间来编写,因为你必须定义你的表变量。

我也推荐RedGate的SQL Prompt用于查询分析器。


1
然而,表变量必须在编译时而不是运行时定义,对吗?为此,我需要一个动态生成的表。 - Jeff
2
唉,但这太啰嗦了,尤其是因为 TSQL 没有“插入或更新”语句... - BlueRaja - Danny Pflughoeft
8
表变量之所以更快,因为它们只存在于内存中的想法似乎是不正确的。根据微软的这个常见问题解答,表变量可能存储在tempdb中,因为它们可能比内存能够容纳的更大。这是该FAQ中的第4个问题/答案。 - Trajanus
5
不仅没有回答问题,而且在使用表变量的时间和原因方面也是错误的。在速度方面,“它取决于”您将如何查询它以及它有多大。没有统计数据。您无法创建二级索引,也无法更改它。还没有回滚功能。范围非常有限。这也导致了一些优点。 - Gerard ONeill
表变量是未记录的。这就是为什么对于小数据量来说它肯定更快的原因。 - iDevlop
显示剩余2条评论

30

你不需要使用 OPENQUERY。只需在任何查询的 SELECT 列表和 FROM 之间加入 "INTO #AnyTableName" 即可...

SELECT *
    INTO #Temp1
    FROM table1
    WHERE x=y

将table1中的所有列插入到#Temp1中,但不插入任何行。 - Chris Burgess
5
如果你使用这种方法,请不要忘记在过程的结尾处执行 drop table #Temp1 - Matthieu

11

是的,您可以使用

SELECT INTO ...

假设

SELECT * INTO #t
FROM OPENQUERY( 'server',
'exec database.dbo.proc_name value1, value2, ... ' )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接