2016-05-23 15 views
1

Ich erstelle ein Webportal in ASP.NET, mit dem wir einige Sicherheitsereignisse in unserer Umgebung verfolgen können, die für unsere Plattform recht proprietär sind.Kann mehrere Abfragen in einer gespeicherten Prozedur ohne Fehler ausführen

Die Daten sind wirklich unkompliziert. Wir sammeln sie und melden Sie es in einem ziemlich einfachen Tisch:

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 
) 

Ich habe eine gespeicherte Prozedur, die mein Code ruft 24hr zu sammeln, 7 Tage und 1 Monat Statistiken. Abhängig davon, dass ich eine einzelne Variable, @Scoreboard, eingerichtet habe, über die ich eine Zeichenfolge übergeben kann, damit die gespeicherte Prozedur verschiedene Scoreboard-Statistiken generiert.
Das scheint alles ziemlich einfach.

Hier ist die gespeicherte Prozedur, wie es jetzt existiert:

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 

Allerdings habe ich gelernt, dass dies aus irgendeinem Grund nicht funktioniert. Diese sollten drei unabhängige Abfragen sein, die ihren eigenen Wert an die Ausgabevariablen zurückgeben.

ich diesen Fehler:

Msg 116, Level 16, State 1, Procedure sp_BuildScoreboard, Line 38
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

Msg 116, Level 16, State 1, Procedure sp_BuildScoreboard, Line 41
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

Msg 116, Level 16, State 1, Procedure sp_BuildScoreboard, Line 42
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

ich super schwach bin in T-SQL. Die Suche nach diesen Fehlern führt mich zu einigen anderen Problemen, die nicht vollständig mit meinen zusammenhängen. Was mache ich falsch?

Antwort

1

Erstens, gewöhnen Sie sich an, Semikolons am Ende jeder Anweisung zu setzen. Das ist nicht das Problem (in diesem Fall). Stattdessen schreiben syntaktisch korrekte Aussagen:

 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 
        ); 

Beachten Sie, dass die Unterabfrage a skalare Unterabfrage. Es kann nur eine Spalte und höchstens eine Zeile zurückgeben. Zwei Spalten sollten einen Fehler erzeugen.

+0

Vielen Dank für den Tipp zur Syntax. Und das Neuschreiben meiner Anfrage. Aktualisiert wie dein Beispiel, es funktioniert perfekt! –

0

Sie müssen bonkVictim, aus jeder select-Anweisung entfernen, damit die SELECT-Anweisungen nur eine Zeile und eine Spalte zurückgeben.

Verwandte Themen