函数在表变量中不起作用

时间:2014-11-26 06:00:24

标签: sql sql-server function tsql sql-server-2008-r2

我创建了一个返回varchar

的函数
CREATE FUNCTION dbo.Test
(
    @i INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
    DECLARE @it VARCHAR(MAX)
    SET @it = 'INSERT INTO @Test
                VALUES (1)
    '

    RETURN @it

END

我尝试在下面的查询中使用该函数但是出错了。

DECLARE @d VARCHAR(MAX)

DECLARE @Test TABLE
(
    i INT
)

SET @d = dbo.Test(1)

SELECT @d

EXEC (@d)

SELECT * FROM @Test

为什么函数在表变量中不起作用?

如何让它发挥作用?

4 个答案:

答案 0 :(得分:1)

试试这个: 如果我们尝试从声明范围之外的@test中使用Select,那么它将无效。因此,它已在@it。中设置。

CREATE FUNCTION [dbo].[Test]
(
    @i INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN

    DECLARE @it VARCHAR(MAX)
    SET @it = 'DECLARE @Test TABLE(i INT); INSERT INTO @Test VALUES (1); SELECT * FROM @Test'

    RETURN @it

END

DECLARE @Test TABLE
(
    i INT
)

DECLARE @d VARCHAR(MAX)

SET @d = dbo.Test(1)

SELECT @d

INSERT INTO @Test
EXEC (@d)

答案 1 :(得分:0)

尝试使用临时表而不是表变量这样做,因为表变量将无法被注释中的其他人指出。 [未经测试]

CREATE FUNCTION dbo.Test
(
    @i INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
    DECLARE @it VARCHAR(MAX)
    SET @it = 'CREATE TABLE #Test(i INT); INSERT INTO #Test
                VALUES (1)'

    RETURN @it

END 

然后调用你的函数

DECLARE @d VARCHAR(MAX)

SET @d = dbo.Test(1)

SELECT @d

EXEC (@d)

SELECT * FROM #Test

答案 2 :(得分:0)

动态SQL在单独的上下文中执行,其中您的变量(包括表格变量)不可用。

你要做的最接近的事情可能是:

insert into @Test
exec(@d);

而函数只返回select部分。

不要忘记,在Microsoft SQL Server中,您无法嵌套insert into ... exec语句。

答案 3 :(得分:0)

如果您的目标是创建一个函数来构建一个或多个插入语句,然后可以执行这些语句来填充表,那么使用表变量就无法工作,因为那些在其他范围内不可用(即子进程或父进程) - 进程范围)。做这样的事情的唯一方法是:

  1. 使用本地临时表(即#Temp
  2. 该函数可以返回一个字符串,该字符串包含插入本地临时表的插入语句。
  3. 需要在执行带有INSERT语句的字符串之前创建本地临时表。
  4. 然后你可以执行字符串。由于临时表已经存在,因此可以通过子流程(即EXEC)访问它。
  5. 示例:

    CREATE FUNCTION dbo.Test
    (
        @i INT
    )
    RETURNS VARCHAR(MAX)
    AS
    BEGIN
        DECLARE @it VARCHAR(MAX);
        SET @it = 'INSERT INTO #Test (Col1)
                    VALUES (' + CONVERT(VARCHAR(20), @i) + ');
        '
    
        RETURN @it;
    END;
    

    以这种方式使用:

    DECLARE @SQL VARCHAR(MAX);
    
    --DROP TABLE #Test;
    CREATE TABLE #Test
    (
        Col1 INT
    );
    
    SET @SQL = dbo.Test(1);
    SET @SQL += dbo.Test(55);
    
    SELECT @SQL;
    
    EXEC (@SQL);
    
    SELECT * FROM #Test;