【问题标题】:Must declare the scalar variable when referencing a table valued parameter引用表值参数时必须声明标量变量
【发布时间】:2017-08-21 20:44:39
【问题描述】:

这个问题来自this one

以下 SQL 有效:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[Update_Repair_Details]
    @RepairID BIGINT,
    @NewDetails NewDetails READONLY
AS
BEGIN
    SET NOCOUNT ON;

    DELETE FROM Repair_Details
    WHERE RepairID = @RepairID

    INSERT INTO Repair_Details
        SELECT *, GETDATE()
        FROM @NewDetails
END

但是由于RepairID是用户自定义表类型中的第一列,所以没有理由将其作为附加参数传递。

我是这样写的:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[Update_Repair_Details]
    @NewDetails NewDetails READONLY
AS
BEGIN
    SET NOCOUNT ON;

    DELETE FROM Repair_Details
    WHERE RepairID = @NewDetails.RepairID

    INSERT INTO Repair_Details
        SELECT *, GETDATE()
        FROM @NewDetails
END    

导致错误:

必须声明标量变量“@NewDetails”

为什么这个有错误,而以前的版本没有?

【问题讨论】:

    标签: sql-server table-variable


    【解决方案1】:

    在这种情况下,@NewDetails 是一个表;因此,你不能只做WHERE RepairID = @NewDetails.RepairID。您可以使用INEXISTSJOIN

    ALTER PROCEDURE [dbo].[Update_Repair_Details]
    @NewDetails NewDetails READONLY
    AS
    BEGIN
        SET NOCOUNT ON;
        DELETE A
        FROM Repair_Details A
        INNER JOIN @NewDetails B
            ON A.RepairID = B.RepairID;
    
    INSERT INTO Repair_Details
    SELECT *, GETDATE()
    FROM @NewDetails;
    END
    

    【讨论】:

    • 我想更好地理解这个答案(我对 SQL 很陌生)。 A 是 Repair_Details 的同义词,B 是 @NewDetails 的同义词吗?但是如果我进行替换,我会得到与 OP 中相同的错误。请解释 A 和 B 扮演的角色。
    • 我刚刚读到“当您在 FROM 子句中使用带有 JOIN 的表值参数时,您还必须给它起别名,...”所以 A 和 B 充当别名的角色,这出于某种原因需要。
    • @SezMe 是的,这些是表别名。你得到同样的错误吗?,这似乎很奇怪。请贴出NewDetails类型的定义
    • 不,您的更正是正确的。现在一切正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 2017-05-21
    • 2011-11-03
    相关资源
    最近更新 更多