Excel - SQL查询 - ## Temp Table

时间:2017-11-07 15:23:16

标签: sql-server excel

我正在尝试使用一个查询的结果创建一个全局临时表,然后可以将其作为一个表选择并进一步操作几次,而不必反复重新处理数据。

这在SQL管理工作室中完美地运行,但是当我尝试通过Excel查询添加表时,该表可以在那时被引用,但它不是在tempdb数据库的临时表中创建的。

我把它分解为一个简单的例子。

如果我在SQL管理工作室中运行它,则按预期返回1的结果,并在临时表中创建表## testtable1

set nocount on;

select 1 as 'Val1', 2 as 'Val2' into ##testtable1
select Val1 from ##testtable1

然后我可以在这张桌子上运行另一个选项,即使在不同的会话中也是如此,正如您所期望的那样。 E.g。

Select Val2 from ##testtable1

如果我不删除## testtable1,则在Excel中的查询中运行以下内容会返回您期望的结果2。

Select Val2 from ##testtable1

但是,如果我直接在Excel中运行相同的Select ...到## testtable1查询,则会正确返回结果1,但不会创建temptable。

如果我然后尝试运行

Select Val2 from ##testtable1

作为单独的查询,它错误地说"无效的对象名称' ## testtable1'

该表未在SQL管理工作室的临时表中列出。

就好像它在查询完成执行后在表上执行了一次删除,即使我没有调用drop。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

阅读全球临时表(GTT)。只要存在引用它的会话,它们就会持续存在。在SSMS中,如果在另一个会话中使用GTT之前关闭创建GTT的会话,则GTT将被丢弃。这就是Excel中发生的事情。 Excel创建连接,执行和断开连接。由于Excel断开连接时没有使用GTT的会话,GTT将被丢弃。

我强烈建议你创建一个普通的表而不是使用GTT。由于它们的临时性质和对活动会话的依赖性,使用GTT时可能会得到不一致的结果。如果您改为创建普通表,则可以确定在以后尝试使用它时它仍然存在。

创建/清理表格的代码非常简单。

IF OBJECT_ID('db.schema.tablename') IS NOT NULL
    TRUNCATE TABLE [tablename]
ELSE
    CREATE [tablename]...
GO

您可以将截断更改为删除以清理特定数据集,并将其放在每个查询的开头。

答案 1 :(得分:0)

你可以使用视图吗?假设您要连接到同一服务器上的5个DB,您可以在视图中将数据合并在一起:

    CREATE VIEW [dbo].[testView]
    AS
    SELECT        *
    FROM            database1.dbo.myTable
    UNION
    SELECT        *
    FROM            database2.dbo.myTable

然后在excel中:

数据与GT;新查询>来自数据库>从SQL Server数据库

输入数据库服务器

从相应的数据库中选择视图 - 完成:)

或者调用视图然而你正在这样做(例如vba等)

同样你可以使用存储过程并从VBA调用它。基本上任何将复杂性转移到服务器端的东西都会让你的生活更轻松:D

答案 2 :(得分:0)

您绝对可以这样做。请注意,我是如何从SQL创建一个名为“ TmpSql”的临时表的...这可以是您想要的任何查询。然后,将其设置为记录集1。然后,创建另一个记录集2,然后去获取临时表数据。

想象一下,如果您正在循环更改TmpSql所在的第一个cn.Execute。这使您可以构建来自许多源或更改变量的临时表。这是一个强大的解决方案。

cn.open "Provider= ..."

sql = "Select t.* Into #TTable From (" & TmpSql & ") t "
Set rs1 = cn.Execute(sql)

GetTmp = "Select * From #TTable"
rs2.Open GetTmp, cn, adOpenDynamic, adLockBatchOptimistic
If Not rs2.EOF Then Call Sheets("Data").Range("A2").CopyFromRecordset(rs2)

rs2.Close
rs1.Close

cn.Close