如何在IF语句中以及BEGIN..END块中使用@@ ROWCOUNT?

Sim*_*ely 10 sql sql-server stored-procedures sql-server-2008

我的代码如下:

SET @var = (SELECT var FROM dbo.varDB WHERE varName = @varName)

IF (@@ROWCOUNT > 0)
    BEGIN
        //carry out insert
    END
Run Code Online (Sandbox Code Playgroud)

我是否正确地说这将始终为@@ ROWCOUNT返回1,因为它最后执行一项任务?

如果是这样,那么最优雅的解决方案是什么让我:

  • 使用存储在其中的查询结果创建变量
  • 测试查询是否返回任何结果

Aar*_*and 9

它返回一个的原因是因为你只分配了一个值(某个任意值).EXISTS无论如何,你应该使用而不是手动计数,正如@Sive建议的那样.原因是EXISTS的性能不会低于COUNT,并且在您描述的用例中,无论如何实际计数并不重要.您想知道计数是零还是大于零.

如果有多个行匹配会发生以你的方式将值赋给变量的问题?我们来试试吧:

DECLARE @foo TABLE([var] INT, varname SYSNAME);
INSERT @foo VALUES (1,N'bob'),(2,N'bob');
DECLARE @var INT;
SET @var = (SELECT [var] FROM @foo WHERE varname = N'bob
Run Code Online (Sandbox Code Playgroud)

结果:

消息512,级别16,状态1,行4
子查询返回的值超过1.当子查询跟随=,!=,<,<=,>,> =或子查询用作表达式时,不允许这样做.

现在,如果varname是唯一的,我会这样做:

SELECT @var = [var] FROM dbo.varDB WHERE varName = @varName;
IF @var IS NOT NULL
BEGIN
    // carry out insert
END
ELSE
BEGIN
    PRINT 'Already existed! ' + RTRIM(@var);
END
Run Code Online (Sandbox Code Playgroud)

如果varname唯一的,那么我不知道你要与一个值做什么.它拉了哪一个?想象一下这种情况:

DECLARE @foo TABLE([var] INT, varname SYSNAME);
INSERT @foo VALUES (3,N'bob'),(2,N'adam'),(1,N'bob');
DECLARE @var INT;
SELECT @var = [var] FROM @foo WHERE varname = N'bob';
PRINT @var;
Run Code Online (Sandbox Code Playgroud)

@var是1还是3?谁知道?如果您只捕获潜在的多个值之一,为什么它是重要的?你打算用那一行做些什么而不是其他的吗?

另外,如果你打算从这个表中插入数据,为什么不简单地抛弃前期检查,行数等,然后说:

INSERT dbo.SomeTable(column1 --,...other columns
  SELECT var --,...other columns
  FROM dbo.varDB
  WHERE varName = @varName;
Run Code Online (Sandbox Code Playgroud)

如果行不存在,则不会发生插入.


小智 5

你可以用这样的东西做EXISTS.这将检查@varName在执行BEGINEND之间的语句之前是否存在给定值的至少一条记录.

脚本:

 IF EXISTS (SELECT var FROM dbo.varDB WHERE varName = @varName)
    BEGIN
         //carry out insert
    END
Run Code Online (Sandbox Code Playgroud)

MSDN文档:EXISTS(Transact-SQL)

根据评论,更新#1:

我不明白了解价值的要求.我想你可能想要使用COUNT,如果你想要获取计数.

DECLARE @recordsCount
SELECT @recordsCount = COUNT(var) FROM dbo.varDB WHERE varName = @varName

IF recordsCount > 0 
BEGIN
  // your statements
END
Run Code Online (Sandbox Code Playgroud)

根据评论,更新#2:

如果您想在BEGIN和END中使用结果集本身,那么问题需要有关如何在语句中使用结果集的更多详细信息.根据进一步的输入,您可能甚至不需要IF声明.需要进一步的细节来为您的问题提供明确的解决方案.


Mik*_*son 5

您可以将变量设置为NULL(只是为了确定).

如果您的查询没有返回任何行,@ var仍然是NULL.
如果它返回一行,@var则会有一个值
如果它返回多行,则会出现异常.

SET @var = NULL

SET @var = (SELECT var FROM dbo.varDB WHERE varName = @varName)
IF @var IS NOT NULL
BEGIN
//carry out insert
END
Run Code Online (Sandbox Code Playgroud)

更新

如果你真的想要使用,@@ROWCOUNT你可以使用select而不是使用赋值set.

SELECT @var = var FROM dbo.varDB WHERE varName = @varName
IF (@@ROWCOUNT > 0)
BEGIN
//carry out insert
END
Run Code Online (Sandbox Code Playgroud)

  • 如果所选的`var`值恰好是'NULL'怎么办? (3认同)