无法从函数内访问临时表

问题描述 投票:0回答:5

我想获取具体记录的数量。所以我的查询将如下所示...

SELECT
    ID, 
    NAME,
    (SELECT...) AS UserCount // Stmt1
FROM MyTable

问题是,'Stmt1'是一个复杂的语句,它不能写成innerquery。 好吧,我可以使用函数,但该语句包含“CREATE TABLE”,所以我收到以下错误消息

Cannot access temporary tables from within a function.

完成任务的最佳方式是什么?

sql-server-2008 function
5个回答
35
投票

您可以使用用户定义的表类型来解决您的问题。

您只需创建一个表变量,例如

CREATE TYPE [dbo].[yourTypeName] AS TABLE(
    [columeName1] [int] NULL,
    [columeName2] [varchar](500) NULL,
    [columeName3] [varchar](1000) NULL
)
GO

您可以在函数中声明此表变量,例如

    CREATE FUNCTION [dbo].[yourFunctionName] 
( 
    @fnVariable1 INT ,
    @yourTypeNameVariable yourTypeName READONLY
) 
RETURNS VARCHAR(8000) 
AS 
BEGIN 

    SELECT .................
        FROM @yourTypeNameVariable 
        WHERE ........
    RETURN @r 
END 

在您的程序中,您可以声明您的表类型,例如

DECLARE @yourTypeNamevaribale AS yourTypeName 

您可以将值插入到该表中,例如

insert into @yourTypeNamevaribale (col,col,..)values(val,val,..)

将其传递给您的函数,例如

dbo.yourFunctionName(fnVariable1 ,@yourTypeNamevaribale )

4
投票

是的,你不能使用#temp 表。

当您使用SQL Server 2008时,为什么不使用表变量而不是#temp表? 尝试一下吧。


1
投票

当我开始使用表变量并出于性能原因切换到临时表时,我发现了这篇文章,却发现临时表无法在函数中使用。

我会犹豫是否使用表变量,特别是如果您正在处理大型结果集,因为这些结果集保存在内存中。看这篇文章...

http://totogamboa.com/2010/12/03/speed-matters-subquery-vs-table-variable-vs-temporary-table/

其他替代方案是..

  1. 将临时表结果提取到另一个表函数中。
  2. 将代码转换为使用子查询

0
投票

在 99,99% 的情况下,不需要任何临时表或子查询的技巧,而是使用聚合函数,如

COUNT
SUM
AVG
OVER
子句
和(通常)结合使用
PARTITION BY

我不确定 OP 试图实现什么目标,但我假设 UserCount 在某种程度上与

MyTable
中的值相关。因此,必须有一种方法将
MyTable
连接到生成
UserCount
的任何表。

最简单的例子就是显示所有用户以及用户总数

SELECT id
    , name
    , user_count = COUNT(*) OVER()
FROM MyUsers

0
投票

您不能像在常规查询中那样在函数中使用临时表,但是您可以在声明表变量后使用它们来创建“临时表”。

临时表在表值函数中不起作用,因为它们 涉及磁盘 I/O 并引入与 函数的期望(应该是确定性的并且 轻的)。表变量位于内存中并且作用域在 函数,本质上更简单并且可以在函数中使用,因为 他们符合这些限制。

declare @TempTableName table(
       variable1 int,
       variable2 varchar(10),
       variable3 decimal(4,3)
 )

稍后在您的函数中,您只需将表引用为@TempTableName。

© www.soinside.com 2019 - 2024. All rights reserved.