12

我的代码如下:

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

IF (@@ROWCOUNT > 0)
    BEGIN
        //carry out insert
    END

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

如果是这样,让我能够做到的最优雅的解决方案是什么:

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

4 回答 4

10

它返回一个的原因是因为您已经分配了一个值(某个任意值)。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

结果:

消息 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

如果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;

@var是1还是3?谁知道?如果您只捕获可能的许多值中的一个,那为什么重要呢?你打算对那一行而不是其他行做些什么吗?

此外,如果您打算从该表中插入数据,为什么不简单地放弃预先检查、行数等,然后说:

INSERT dbo.SomeTable(column1 --,...other columns
  SELECT var --,...other columns
  FROM dbo.varDB
  WHERE varName = @varName;

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

于 2012-04-30T14:06:30.840 回答
6

您可以将变量设置为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

更新

如果你真的想使用而不是你可以使用而@@ROWCOUNT不是分配你的价值。selectset

SELECT @var = var FROM dbo.varDB WHERE varName = @varName
IF (@@ROWCOUNT > 0)
BEGIN
//carry out insert
END
于 2012-04-30T14:17:01.313 回答
5

您可以使用EXISTS. @varName这将在执行包含在BEGINEND之间的语句之前检查给定值是否存在至少一条记录。

脚本

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

MSDN 文档存在 (Transact-SQL)

根据评论,更新#1:

我不明白知道价值的要求。如果您要获取计数,我认为您可能想要使用 COUNT。

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

IF recordsCount > 0 
BEGIN
  // your statements
END

根据评论,更新#2:

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

于 2012-04-30T14:01:25.943 回答
4

您可以选择并测试返回的行数:

SELECT @var = var FROM dbo.varDB WHERE varName = @varName
IF (@@ROWCOUNT > 0)
BEGIN
   //carry out insert
END
于 2012-04-30T14:05:32.943 回答