where condition 在错误的地方有一个声明的变量不知道它是否有效

where condition have a declared variable on a wrong place do not know if its valid

我的一个大存储过程中有如下这样的语句,我想知道这样写是否有效。

SELECT  @PVDate = pv.Date,
        @PVdMBeginDate = dbo.fPVoidDate(pv.myID)
FROM PVMeter pv (NOLOCK)
WHERE pv.PR_ID = @PR_ID
AND @VCommen BETWEEN pv.PVDMDate AND dbo.fPVoidDate(pv.myID)

现在,在这里,我的问题是,@VCommen 是一个声明的日期变量,上面设置了一个值。它根本不是PVMeter的一列,而PVDMDate是PVMeter和fpVoidDate中的一列returns datetime

当我调试 SP 时,我没有看到 @PVDate 和 @PVDMBeginDate 上的值

原始查询等同于:

SELECT  
    @PVDate = pv.Date,
    @PVdMBeginDate = dbo.fPVoidDate(pv.myID)
FROM PVMeter pv (NOLOCK)
WHERE 
    pv.PR_ID = @PR_ID
    AND pv.PVDMDate <= @VCommen
    AND @VCommen <= dbo.fPVoidDate(pv.myID)

这种风格大家应该比较熟悉吧。通常,您可以在 WHERE 子句中放置任何表达式,它可以由变量或常量构成,而根本不引用 table 列。

例子

经典示例:WHERE 1=1 ...动态生成查询文本时。可以很容易地添加任意数量的表达式,没有特定的顺序,并在所有表达式前加上 AND.

DECLARE @VarSQL nvarchar(max);

SET @VarSQL = 'SELECT ... FROM ... WHERE 1=1 ';

IF ... THEN SET @VarSQL = @VarSQL + ' AND expression1';
IF ... THEN SET @VarSQL = @VarSQL + ' AND expression2';
IF ... THEN SET @VarSQL = @VarSQL + ' AND expression3';

EXEC @VarSQL;

因此您不需要复杂的逻辑来确定是否需要在每个表达式前添加 AND

另一个例子。

您有一个带有参数 @ParamID int 的存储过程。

您在过程中有一个复杂的查询,通常 return 结果集的许多行和一列是唯一的 ID

SELECT ID, ...
FROM ...
WHERE
expression1
AND expression2
AND expression3
...

如果 @ParamIDNULL,您想要 return 所有行,如果 @ParamID 不是 [=21],则只有给定 ID 的一行=].我个人使用这种方法。当我第一次打开显示查询结果的屏幕时,我想向用户显示所有行,所以我将 NULL 作为参数传递。然后用户对选定的行进行更改,这是通过单独的 UPDATE 语句完成的。然后我想刷新用户在屏幕上看到的结果。我知道刚刚更改的行的 ID,所以我只需要重新查询这一行,所以我将这个 ID 传递给过程并再次获取一行而不是整个 table .

最终查询如下所示:

SELECT ID, ...
FROM ...
WHERE
(@ParamID IS NULL OR ID = @ParamID)
AND expression1
AND expression2
AND expression3
...
OPTION (RECOMPILE);

因此我不必重复查询的复杂代码两次。