在用户定义的函数中创建,删除和插入临时表

Sof*_*ner 7 sql-server function

我正在尝试按照我的要求创建一个函数.

但是,当我创建或删除时#tempTable,它会给出一个错误:

在函数内无效使用副作用运算符'drop object'

我的理解是,我们不能有create,dropinsert在操作#temptable中的功能.

那是对的吗?

我的SQL:

CREATE FUNCTION [dbo].[RT_ResultFunction]
(
    Id VARCHAR(4000)
)
RETURNS @RT_ResultFunction TABLE 
(   
    Id VARCHAR(20)
    , Name varchar(20)
    ,Balance Int
)
AS
BEGIN
    IF OBJECT_ID('tempdb..#tempTable') IS NOT NULL  
       DROP TABLE #tempTable

    SELECT Id, COUNT(Balance) 
    INTO  #tempTable
    'Balance' FROM Table1

    INSERT  @RT_ResultFunction 
        SELECT T1.ID,T1,NAME,T2,Balance 
        FROM    Table2 T1, 
                #tempTable T2
        WHERE T1.ID = T2.ID

    RETURN
END
Run Code Online (Sandbox Code Playgroud)

Jon*_*ton 20

这是正确的 - 你不能有副作用声明:

从这里:http://msdn.microsoft.com/en-us/library/aa175085(v = sql.80).aspx

BEGIN ... END块中的语句不会产生任何副作用.功能副作用是对具有函数外部作用域的资源状态的任何永久性更改,例如对数据库表的修改.函数中的语句可以进行的唯一更改是对函数本地对象的更改,例如本地游标或变量.对数据库表的修改,对函数不是本地的游标的操作,发送电子邮件,尝试修改目录以及生成返回给用户的结果集都是无法在函数中执行的操作的示例.

即使没有您的DROP陈述,您会发现,任何访问临时表的尝试都会给您消息(例如a SELECT ... INTO #TMP):

无法从函数中访问临时表

正如@Dems指出的那样,您可以使用表变量.因为这些是变量,所以它们在函数范围内,因此不会产生副作用.

您的函数可能运行如下:

...

BEGIN
    DECLARE @tempTable table (id varchar(20), rows int)

    insert @tempTable
    SELECT Id, COUNT(Balance) 
    FROM Table1

    INSERT  @RT_ResultFunction 
        SELECT T1.ID,T1,NAME,T2,Balance 
        FROM    Table2 T1, 
                @tempTable T2
        WHERE T1.ID = T2.ID

    RETURN END
Run Code Online (Sandbox Code Playgroud)

没有测试或任何东西,但你得到了要点.

  • 但是你可以使用表变量.哪一个是有用的事实,可以添加到你的答案中,帮助OP解决他的问题*(而不仅仅是知道为什么这是一个问题)*;) (4认同)
  • @LukeMarlin您无法从UDF调用存储过程,因为存储过程会导致副作用,并且不允许使用函数. (2认同)