无法在存储过程中执行多个查询而不会出现错误

Posted

技术标签:

【中文标题】无法在存储过程中执行多个查询而不会出现错误【英文标题】:Cant perform multiple queries in a stored procedure without errors 【发布时间】:2016-05-23 23:34:50 【问题描述】:

我正在用 ASP.NET 构建一个 Web 门户,它允许我们跟踪在我们的环境中发生的一些安全事件,这些事件是我们平台相当专有的。

数据非常直接。我们收集它并将其记录在一个非常基本的表中:

CREATE TABLE [dbo].[tblBonks]
(
    [bonkID] [int] IDENTITY(1,1) NOT NULL,
    [bonkVictim] [nvarchar](50) NOT NULL,
    [bonkMachineID] [nvarchar](max) NULL,
    [bonkUser] [nvarchar](50) NOT NULL,
    [bonkTime] [datetime] NOT NULL,

    CONSTRAINT [PK_tblBonks] 
        PRIMARY KEY CLUSTERED 
)

我有一个存储过程,我的代码调用它来收集 24 小时、7 天和 1 个月的统计信息。根据我设置的单个变量@Scoreboard,我可以将字符串传递给该变量以使存储过程生成不同的记分牌统计信息。 这一切看起来都很简单。

这是现在存在的存储过程:

CREATE PROCEDURE sp_BuildScoreboard 
     @ScoreBoard nvarchar(25),
     @Day nvarchar(5) OUTPUT,
     @Week nvarchar(5) OUTPUT,
     @Month  nvarchar(5) OUTPUT
AS
BEGIN
    SET NOCOUNT ON;

    IF (@ScoreBoard = 'VICTIM')
    BEGIN
        set @Day = (select TOP(1) bonkVictim, count(bonkVictim) as bonknumber
                    from tblBonks
                    where bonkTime > DATEADD(DAY, -1, SYSDATETIME()) 
                      and bonkVictim != bonkUser
                    group by bonkVictim
                    order by bonknumber desc)

        /* 7 days */
        set @Week = (select TOP(1) bonkVictim, count(bonkVictim) as bonknumber
                     from tblBonks
                     where bonkTime > DATEADD(WEEK, -1, SYSDATETIME()) 
                       and bonkVictim != bonkUser
                     group by bonkVictim
                     order by bonknumber desc)

        /* 1 month */
        set @Month = (select TOP(1) bonkVictim, count(bonkVictim) as bonknumber
                      from tblBonks
                      where bonkTime > DATEADD(MONTH, -1, SYSDATETIME()) 
                        and bonkVictim != bonkUser
                      group by bonkVictim
                      order by bonknumber desc)
    END
    /*ELSE IF (@ScoreBoard = 'LEADER')
    BEGIN
    END
    ELSE IF (@ScoreBoard = 'MACHINE')
    BEGIN
    END*/
END
GO

但是我了解到,由于某种原因,这不起作用。这些应该是三个独立的查询,它们将自己的值返回给输出变量。

我收到此错误:

消息 116,级别 16,状态 1,过程 sp_BuildScoreboard,第 38 行 当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。

消息 116,级别 16,状态 1,过程 sp_BuildScoreboard,第 41 行 当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。

消息 116,级别 16,状态 1,过程 sp_BuildScoreboard,第 42 行 当子查询不使用 EXISTS 引入时,选择列表中只能指定一个表达式。

我在 T-SQL 方面非常薄弱。搜索这些错误往往会将我带入一些与我的不完全相关的其他问题。我做错了什么?

【问题讨论】:

【参考方案1】:

首先,养成在每条语句末尾添加分号的习惯。这不是问题(在这种情况下)。相反,编写语法正确的语句:

       set @Day = (select TOP(1) bonkVictim
                   from tblBonks
                   where bonkTime > DATEADD(DAY, -1, SYSDATETIME()) and
                          bonkVictim <> bonkUser
                    group by bonkVictim
                    ORDER BY count(bonkVictim) desc
                   );

请注意,子查询是一个标量子查询。它只能返回一列,最多返回一行。两列应该会产生错误。

【讨论】:

感谢您提供有关语法的提示。并重写我的查询。像你的例子一样更新它完美地工作!【参考方案2】:

您需要从每个select 语句中删除bonkVictim,,以便选择语句只返回一行和一列。

【讨论】:

以上是关于无法在存储过程中执行多个查询而不会出现错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在codeigniter中使用存储过程的结果集

oracle 执行存储过程 无法中断 但是是循环执行 怎么办

SQLSERVER创建该存储过程时不会出错,但是执行存储过程时报错

SQL Server 存储过程在查询分析器中执行,但在 C# 中无法正常运行

无法在 dbo 模式中执行存储过程

存储过程在数据库中的作用是啥