mayrastevenson 0 Geschrieben 19. November 2014 Melden Teilen Geschrieben 19. November 2014 Hallo zusammen,suche Hilfe zur Lösung dieses Problems: "Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression".Hoffentlich kann mir jemand dabei helfen. Es geht um eine Stored Procedure, die nicht nur die Anzahl von Opportunities mit Status "Pending" oder "Accepted" sondern auch die Namen der Opportunities mit diesen Stati ausgeben sollte. Folgende Probleme:1. Der SELECT, der mir die Namen der Opportunities ausgibt, kann mir aber in manchen Faellen mehr als einen Wert ausgeben. Ich kann aber den SELECT nicht einer Variable zuweisen, z.B. mi SET, wie kann ich das in dem Code anders zuweisen oder wie kann man den Code abändern in dem Fall?2. Der Code müsste auch die Namen der Opportunities ausgeben, naemlich nach "Die Opportunities sind:" und diese dem Empfaenger einer Email zugeschickt werden. Wie kann ich aber das so darstellen, so dass diese Opportunities Zeile fuer Zeile ausgegeben werden und nicht alles in einer Zeile, damit diese Ergebnisse dann per Email zugeschickt werden können?Es wuerde mich sehr freuen, wenn mir ein Specialist in Stored Procedures mit SQL Server dabei hilft, da ich schon längst versuche, diese Probleme zu lösen. Folgendes ist der Code: CREATE PROCEDURE [dbo].[Pending_Opportunities] AS BEGIN declare @V_USER VARCHAR(20), @V_NAME VARCHAR(100), @V_OPP_NAME VARCHAR(100), @V_ANZAHL INT, @V_EMAIL VARCHAR(60), @V_BODY VARCHAR(MAX), @V_ANZAHL_AKTIV int DECLARE CUR CURSOR FOR SELECT USER, COMPLETEDNAME, EMAILDIRECTION FROM USER_SIEBEL WHERE STATE = 'G' OPEN CUR FETCH NEXT FROM CUR INTO @V_USER, @V_NAME, @V_EMAIL WHILE @@FETCH_STATUS = 0 BEGIN SET @V_OPP_NAME = ( SELECT T1.NAME FROM dbo.S_OPTY T1 INNER JOIN dbo.S_OPTY_POSTN T2 ON T1.PR_POSTN_ID = T2.POSITION_ID AND T1.ROW_ID = T2.OPTY_ID INNER JOIN dbo.S_OPTY_BU T3 ON T3.BU_ID = '1-O5H' AND T1.ROW_ID = T3.OPTY_ID INNER JOIN dbo.S_PARTY T4 ON T2.POSITION_ID = T4.ROW_ID INNER JOIN dbo.S_PARTY T5 ON T3.BU_ID = T5.ROW_ID LEFT OUTER JOIN dbo.S_USER T6 ON T1.CREATED_BY = T6.PAR_ROW_ID LEFT OUTER JOIN dbo.S_SYS_KEYMAP T7 ON T1.ROW_ID = T7.SIEBEL_SYS_KEY LEFT OUTER JOIN dbo.S_OPTY T8 ON T1.PAR_OPTY_ID = T8.ROW_ID LEFT OUTER JOIN dbo.S_ADDR_ORG T9 ON T1.PR_OU_ADDR_ID = T9.ROW_ID LEFT OUTER JOIN dbo.S_ORG_EXT T10 ON T1.PR_DEPT_OU_ID = T10.PAR_ROW_ID LEFT OUTER JOIN dbo.S_POSTN T11 ON T1.PR_POSTN_ID = T11.PAR_ROW_ID LEFT OUTER JOIN dbo.S_PRI_LST T12 ON T10.CURR_PRI_LST_ID = T12.ROW_ID LEFT OUTER JOIN dbo.S_USER T13 ON T11.PR_EMP_ID = T13.PAR_ROW_ID WHERE T1.STATUS_CD in ( 'Pending' , 'Accepted') --AND T13.LOGIN = @V_USER AND (T13.LOGIN in (@V_USER) ) --OR (T6.LOGIN in (@V_USER)) ) AND T1.SUM_EFFECTIVE_DT <= GETDATE() AND T1.SUM_EFFECTIVE_DT >= '20100601' ) SET @V_ANZAHL = 0 SET @V_ANZAHL_AKTIV = 0 SET @V_ANZAHL = ( SELECT COUNT(*) FROM dbo.S_OPTY T1 INNER JOIN dbo.S_OPTY_POSTN T2 ON T1.PR_POSTN_ID = T2.POSITION_ID AND T1.ROW_ID = T2.OPTY_ID INNER JOIN dbo.S_OPTY_BU T3 ON T3.BU_ID = '1-O7F' AND T1.ROW_ID = T3.OPTY_ID INNER JOIN dbo.S_PARTY T4 ON T2.POSITION_ID = T4.ROW_ID INNER JOIN dbo.S_PARTY T5 ON T3.BU_ID = T5.ROW_ID LEFT OUTER JOIN dbo.S_USER T6 ON T1.CREATED_BY = T6.PAR_ROW_ID LEFT OUTER JOIN dbo.S_SYS_KEYMAP T7 ON T1.ROW_ID = T7.SIEBEL_SYS_KEY LEFT OUTER JOIN dbo.S_OPTY T8 ON T1.PAR_OPTY_ID = T8.ROW_ID LEFT OUTER JOIN dbo.S_ADDR_ORG T9 ON T1.PR_OU_ADDR_ID = T9.ROW_ID LEFT OUTER JOIN dbo.S_ORG_EXT T10 ON T1.PR_DEPT_OU_ID = T10.PAR_ROW_ID LEFT OUTER JOIN dbo.S_POSTN T11 ON T1.PR_POSTN_ID = T11.PAR_ROW_ID LEFT OUTER JOIN dbo.S_PRI_LST T12 ON T10.CURR_PRI_LST_ID = T12.ROW_ID LEFT OUTER JOIN dbo.S_USER T13 ON T11.PR_EMP_ID = T13.PAR_ROW_ID WHERE T1.STATUS_CD in ( 'Pending' , 'Accepted') --AND T13.LOGIN = @V_USER AND (T13.LOGIN in (@V_USER) ) --OR (T6.LOGIN in (@V_USER)) ) AND T1.SUM_EFFECTIVE_DT <= GETDATE() AND T1.SUM_EFFECTIVE_DT >= '20100601' ) SET @V_ANZAHL_AKTIV = ( SELECT COUNT(*) FROM dbo.S_EVT_ACT T1 WHERE ( (T1.APPT_REPT_REPL_CD IS NULL) AND (T1.TEMPLATE_FLG != 'Y' AND T1.TEMPLATE_FLG != 'P' OR T1.TEMPLATE_FLG IS NULL) AND (T1.PRIV_FLG = 'N' OR T1.PRIV_FLG IS NULL OR T1.OWNER_PER_ID = '1-ONG') ) AND T1.TODO_PLAN_START_DT <= getdate() AND T1.TODO_PLAN_START_DT >= '20100601' AND T1.EVT_STAT_CD IN ('Pending','Programmed') AND T1.TODO_CD != 'Erinnerung' AND T1.TODO_CD != 'Task' AND T1.OPTY_ID is not null AND T1.NAME NOT LIKE '%hat Ihnen zu einer Opportunity eingeladen:%' AND T1.OWNER_LOGIN = @V_USER ) if @V_ANZAHL + @V_ANZAHL_AKTIV > 0 begin SET @V_BODY = '<BODY style="color:navy; font-size:10pt; font-family:verdana">' SET @V_BODY = @V_BODY + 'Sehr geehrte(r) ' + @V_USER + ',<br>' SET @V_BODY = @V_BODY + 'Sie haben ' IF @V_ANZAHL > 0 BEGIN SET @V_BODY = @V_BODY + cast(@V_ANZAHL as varchar) + ' Opportunities mit Status Pending' SET @V_BODY = @V_BODY + '<br>Die Opportunities sind:<br>' SET @V_BODY = @V_BODY + '<BR>' SET @V_BODY = @V_BODY + @V_OPP_NAME IF @V_ANZAHL_AKTIV > 0 SET @V_BODY = @V_BODY + ' und ' END IF @V_ANZAHL_AKTIV > 0 BEGIN SET @V_BODY = @V_BODY + cast(@V_ANZAHL_AKTIV as varchar) + ' Activities mit Status Pending/Programmed' END SET @V_BODY = @V_BODY + '<BR>' </BODY>' exec msdb..sp_send_dbmail @profile_name = 'Siebel Administrator', @recipients = @V_EMAIL, @subject = 'SIEBEL Email zur Verfolgung der Opportunities / Activities', @body = @V_BODY, @body_format = 'HTML', @exclude_query_output = 1 end FETCH NEXT FROM CUR INTO @V_USER, @V_NAME, @V_EMAIL END CLOSE CUR DEALLOCATE CUR END Zitieren Link zu diesem Kommentar
Pathomorph 1 Geschrieben 19. November 2014 Melden Teilen Geschrieben 19. November 2014 Hi 1. Wenn du schon ein Cursor benutzen willst, warum verknüpfst du nicht gleich die Tabelle "USER_SIEBEL" mit dbo.S_OPTY? Wenn du Datensätze zurück bekommst, musst du nicht noch die Anzahl abfragen... 2. Wieso verlinkst du so viele Tabelle, die du eigentlich nicht brauchst? So z.B. würde es auch tun?! Oder übersehe ich da etwas? ET @V_ANZAHL = ( SELECT COUNT(*) FROM dbo.S_OPTY T1 LEFT OUTER JOIN dbo.S_USER T13 ON T11.PR_EMP_ID = T13.PAR_ROW_ID WHERE T1.STATUS_CD in ( 'Pending' , 'Accepted') --AND T13.LOGIN = @V_USER AND (T13.LOGIN in (@V_USER) ) --OR (T6.LOGIN in (@V_USER)) ) AND T1.SUM_EFFECTIVE_DT <= GETDATE() AND T1.SUM_EFFECTIVE_DT >= '20100601' ) Zitieren Link zu diesem Kommentar
mayrastevenson 0 Geschrieben 19. November 2014 Autor Melden Teilen Geschrieben 19. November 2014 Danke fuer deine Antwort, aber darum geht es nicht, d.h. die Abfrage abzuaendern, da ist nichts zu aendern... Zitieren Link zu diesem Kommentar
Pathomorph 1 Geschrieben 19. November 2014 Melden Teilen Geschrieben 19. November 2014 Nein. Sicher. Das war nur eine Anmerkung.. Wichtiger ist der Punkt 1. Du willst in die Variable @V_OPP_NAME EINEN Wert speichert. Deine Abfrage liefert jedoch mehrere. Das geht also nicht... Daher die Anregung, das Konstrukt zu ändern, indem du die die Tabelle "USER_SIEBEL" mit dbo.S_OPTY verlinkst.. Zitieren Link zu diesem Kommentar
mayrastevenson 0 Geschrieben 20. November 2014 Autor Melden Teilen Geschrieben 20. November 2014 Ich habe einen Cursor benutzt, um die Ergebnisse dann durch PRINT bei der Ausfuehrung ueber den SQL Server auszugeben (ohne Header der Spalte NAME). Das einzige Problem, das ich noch loesen muss, ist die Konkatenierung mit dem Rest des @BODY. Folgendes Cursor habe ich noch in dem Code eingefuegt: DECLARE CUR_TEST CURSOR FOR SELECT T1.NAME FROM dbo.S_OPTY T1 INNER JOIN dbo.S_OPTY_POSTN T2 ON T1.PR_POSTN_ID = T2.POSITION_ID AND T1.ROW_ID = T2.OPTY_ID INNER JOIN dbo.S_OPTY_BU T3 ON T3.BU_ID = '1-O5H' AND T1.ROW_ID = T3.OPTY_ID INNER JOIN dbo.S_PARTY T4 ON T2.POSITION_ID = T4.ROW_ID INNER JOIN dbo.S_PARTY T5 ON T3.BU_ID = T5.ROW_ID LEFT OUTER JOIN dbo.S_USER T6 ON T1.CREATED_BY = T6.PAR_ROW_ID LEFT OUTER JOIN dbo.S_SYS_KEYMAP T7 ON T1.ROW_ID = T7.SIEBEL_SYS_KEY LEFT OUTER JOIN dbo.S_OPTY T8 ON T1.PAR_OPTY_ID = T8.ROW_ID LEFT OUTER JOIN dbo.S_ADDR_ORG T9 ON T1.PR_OU_ADDR_ID = T9.ROW_ID LEFT OUTER JOIN dbo.S_ORG_EXT T10 ON T1.PR_DEPT_OU_ID = T10.PAR_ROW_ID LEFT OUTER JOIN dbo.S_POSTN T11 ON T1.PR_POSTN_ID = T11.PAR_ROW_ID LEFT OUTER JOIN dbo.S_PRI_LST T12 ON T10.CURR_PRI_LST_ID = T12.ROW_ID LEFT OUTER JOIN dbo.S_USER T13 ON T11.PR_EMP_ID = T13.PAR_ROW_ID WHERE T1.STATUS_CD in ( 'Pending' , 'Accepted') --AND T13.LOGIN = @V_USER AND (T13.LOGIN in (@V_USER) ) --OR (T6.LOGIN in (@V_USER)) ) AND T1.SUM_EFFECTIVE_DT <= GETDATE() AND T1.SUM_EFFECTIVE_DT >= '20100601' ) OPEN CUR_TEST FETCH NEXT FROM CUR_TEST INTO @V_OP_NOMBRE WHILE (@@FETCH_STATUS = 0) BEGIN PRINT @V_OP_NOMBRE FETCH CUR_TEST INTO @V_OP_NOMBRE END CLOSE CUR_TEST DEALLOCATE CUR_TEST Aber, ich haenge noch in der Konkatenierung: SET @V_BODY = '<BODY style="color:navy; font-size:10pt; font-family:verdana">' SET @V_BODY = @V_BODY + 'Sehr geehrte(r) ' + @V_USER + ',<br>' SET @V_BODY = @V_BODY + 'Sie haben ' IF @V_ANZAHL > 0 BEGIN SET @V_BODY = @V_BODY + cast(@V_ANZAHL as varchar) + ' Opportunities mit Status Pending' SET @V_BODY = @V_BODY + '<br>Die Opportunities sind:<br>' SET @V_BODY = @V_BODY + '<BR>' SET @V_BODY = @V_BODY + @V_OP_NAME Wenn ich dies ausfuehre: exec msdb..sp_send_dbmail @profile_name = 'Siebel Administrator', @recipients = @V_EMAIL, @subject = 'SIEBEL Email zur Verfolgung der Opportunities / Activities', @body = @V_BODY, @body_format = 'HTML', @exclude_query_output = 1 end dieser gibt mir den Inhalt des @V_BODY, aber an der Stelle der Ausgabe der Namen der Opportunities, gibt der mir nur der letzte Row (Zeile) der Ergebnisse der SELECT in dem Cursor CUR_TEST...wie kann ich anstatt SET was Anderes benutzen, so dass mir alle Ergebnisse der SELECT ausgegeben werden? Zitieren Link zu diesem Kommentar
Empfohlene Beiträge
Schreibe einen Kommentar
Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.