将表参数传递给表值函数时出现 SQL 错误:“必须声明标量变量”。

3
以下是一个简单的SQL示例,它返回了一个错误。
这是一个传递给表值函数的表类型:
CREATE TYPE Ids
    AS TABLE
    (
        Id int NOT NULL,
        PRIMARY KEY( Id )
    );
GO

以下是失败的表值函数:

CREATE FUNCTION GetIds
(
    @ids -- or null
        Ids READONLY
)
RETURNS
    @result
        TABLE
        (
            EachId int
        )
AS
BEGIN
    IF @ids IS NOT NULL
        INSERT INTO @result
            SELECT Id
            FROM @ids;
    RETURN;
END;
GO

返回的错误是:

Msg 137,级别16,状态1,过程GetIds,行28
必须声明标量变量“@ids”。

我读到过一些帖子,说当SQL兼容性级别太低时会发生这种情况,但以下内容返回100:
SELECT compatibility_level 
FROM sys.databases 
WHERE name = 'TheDatabaseName';

任何建议都将不胜感激。

错误是因为您使用了未声明的变量。例如 declare @ids table(Ids int) - S.Visser
S.Visser:它被声明为Ids类型。这是如何将表作为参数传递的方法。 - uncaged
它是被创建的,而不是被声明的。如果你要引用它,你需要声明它。我认为这个MSDN文档会解释清楚:https://msdn.microsoft.com/zh-cn/library/bb510489.aspx - S.Visser
我认为你误读了那个例子。请注意@TVP作为参数传递,并且没有“声明”。 - uncaged
奇怪的是,如果删除“IF @ids IS NOT NULL”这行代码,错误就会消失。看来我需要检查一个空表格。 - uncaged
2个回答

1

让我告诉您,表格类型的参数就像一个数据表。

因此,如果您想在其上放置if条件,则:

只需将函数的if条件更改为如下内容即可:

IF (select count(*) from @ids) > 0

完整的函数代码如下:

CREATE FUNCTION GetIds
(
@ids Ids READONLY      
)
RETURNS @result TABLE(EachId int)
AS
BEGIN
IF (select count(*) from @ids) > 0
    INSERT INTO @result
    SELECT Id FROM @ids;            
RETURN;
END;

这几乎是我解决这个问题的方式,尽管我更喜欢能够传递NULL。顺便说一下,我认为IF EXISTS (SELECT * FROM @ids)可能比确定行数并将其与0进行比较要高效一点。 - uncaged

0

只需检查您的表中是否有任何记录

if(select count(1) from @ids)>0

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