Jump to content

generierendes SQL Statement absetzen


Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Empfohlene Beiträge

Hallo an alle aktuell beschäftige ich mich mit der Vereinfachung von SQL Statements zur besseren Wartung.

 

So habe ich zb. folgendes SQL Statement:


declare @i int=1;
declare @x int=1;
declare @zeile1 nvarchar(30);
declare @zeile2 nvarchar(300);

--Select

while(@x <=11)
	
	BEGIN
	while (@i <=16)
	   
		BEGIN					
		   SET @zeile1 = '[Zaehler_1K'+cast(@x as nvarchar(2))+'_'+cast(@i as nvarchar(2))+']';
		   SET @zeile2 = ',[Zaehler_1K'+cast(@x as nvarchar(2))+'_'+cast(@i as nvarchar(2))+']-(SELECT TOP 1 [Zaehler_1K'+cast(@x as nvarchar(2))+'_'+cast(@i as nvarchar(2))+'] FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS t2 WHERE (t2.[Zaehler_1K'+cast(@x as nvarchar(2))+'_'+cast(@i as nvarchar(2))+'] < t1.[Zaehler_1K'+cast(@x as nvarchar(2))+'_'+cast(@i as nvarchar(2))+']) OR((t2.[Zaehler_1K'+cast(@x as nvarchar(2))+'_'+cast(@i as nvarchar(2))+'] = t1.[Zaehler_1K'+cast(@x as nvarchar(2))+'_'+cast(@i as nvarchar(2))+']) AND (t1.[CounterID] > t2.[CounterID])) ORDER BY [Zaehler_1K'+cast(@x as nvarchar(2))+'_'+cast(@i as nvarchar(2))+'] DESC, [CounterID])  AS [Zaehler_1K'+cast(@x as nvarchar(2))+'_'+cast(@i as nvarchar(2))+'-Differenz]';
			print @zeile1;
	 		print @zeile2;
			SET @i = @i+1;
		END 
	SET @i=1;
	SET @x = @x+1;
END
GO

--from [SKEMS-HST-POWER].dbo.EnergieMonat

Ich Möchte die 2 while Schleifen nun mit einen Select from ... umschließen und ausführen lassen. Das Print (als Test) liefert schon mal die Grundlage dafür, aber wie kann ich nun das ganze absetzen?

 

kann mir bitte jemand helfen. Mir fehlt absolut der Ansatz nach was ich suchen kann.

Link zu diesem Kommentar

dann will ich mal weiter ausholen. wenn ich ein DTSX Paket schreiben will was verdammt viel SQL Syntax enthält bricht das Vorhaben (zb. Import) ab weil das SQL Statement zu lang ist. (meine Vermutung Begrenzung durch nvarchar ca 4000 Zeichen) Somit brauch ich eine Möglichkeit wie eine Abfrage durch eine gewisse Intelligenz mir nun das Ergebnis liefert. Soll heißen durch Schleifen und Co möchte ich wenig SQL Syntax (wegen der Begrenzung) aber eben das gleiche Ziel. :D

 

Die oben aufgeführte Syntax liefert (via print) den gewünschten SQL Aufbau (die eigentliche Syntax wird generiert), diesen Aufbau möchte ich dann nutzen für die eigentliche Abfrage.  

 

Ich weiß das es geht aber ich weiß noch nicht wie ich meine Print- Ausgabe nun zu einer SQL Syntax mache :D

 

@ sunny das mit case hatte ich auch schon im Kopf, aber eine while-Schleife und eine sich erhöhende Variable ist denke ich die bessere alternative

bearbeitet von tutter
Link zu diesem Kommentar

ich dachte das sei jetzt klar aber ok dann noch ein paar Details.

SELECT [CounterID]
      ,[Datum]
      ,cast(substring(CONVERT(varchar(10),[Datum],101),7,4) as numeric) as Jahr
      ,cast(substring(CONVERT(varchar(10),[Datum],101),4,2) as numeric) as Tag
      ,cast(substring(CONVERT(varchar(10),[Datum],101),1,2) as numeric) as Monat
      ,[Zaehler_1K1_1]
      ,[Zaehler_1K1_1]-(SELECT TOP 1 [Zaehler_1K1_1] FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS t2 WHERE (t2.[Zaehler_1K1_1] < t1.[Zaehler_1K1_1]) OR((t2.[Zaehler_1K1_1] = t1.[Zaehler_1K1_1]) AND (t1.[CounterID] > t2.[CounterID])) ORDER BY [Zaehler_1K1_1] DESC, [CounterID])  AS [Zaehler_1K1_1-Differenz]
      ,[Zaehler_1K1_2]
      ,[Zaehler_1K1_2]-(SELECT TOP 1 [Zaehler_1K1_2] FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS t2 WHERE (t2.[Zaehler_1K1_2] < t1.[Zaehler_1K1_2]) OR((t2.[Zaehler_1K1_2] = t1.[Zaehler_1K1_2]) AND (t1.[CounterID] > t2.[CounterID])) ORDER BY [Zaehler_1K1_2] DESC, [CounterID])  AS [Zaehler_1K1_2-Differenz]
      ,[Zaehler_1K1_3]
      ,[Zaehler_1K1_3]-(SELECT TOP 1 [Zaehler_1K1_3] FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS t2 WHERE (t2.[Zaehler_1K1_3] < t1.[Zaehler_1K1_3]) OR((t2.[Zaehler_1K1_3] = t1.[Zaehler_1K1_3]) AND (t1.[CounterID] > t2.[CounterID])) ORDER BY [Zaehler_1K1_3] DESC, [CounterID])  AS [Zaehler_1K1_3-Differenz]
      ,[Zaehler_1K1_4]
      ,[Zaehler_1K1_4]-(SELECT TOP 1 [Zaehler_1K1_4] FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS t2 WHERE (t2.[Zaehler_1K1_4] < t1.[Zaehler_1K1_4]) OR((t2.[Zaehler_1K1_4] = t1.[Zaehler_1K1_4]) AND (t1.[CounterID] > t2.[CounterID])) ORDER BY [Zaehler_1K1_4] DESC, [CounterID])  AS [Zaehler_1K1_4-Differenz]
      ,[Zaehler_1K1_5]
      ,[Zaehler_1K1_5]-(SELECT TOP 1 [Zaehler_1K1_5] FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS t2 WHERE (t2.[Zaehler_1K1_5] < t1.[Zaehler_1K1_5]) OR((t2.[Zaehler_1K1_5] = t1.[Zaehler_1K1_5]) AND (t1.[CounterID] > t2.[CounterID])) ORDER BY [Zaehler_1K1_5] DESC, [CounterID])  AS [Zaehler_1K1_5-Differenz]
      ,[Zaehler_1K1_6]
      ,[Zaehler_1K1_6]-(SELECT TOP 1 [Zaehler_1K1_6] FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS t2 WHERE (t2.[Zaehler_1K1_6] < t1.[Zaehler_1K1_6]) OR((t2.[Zaehler_1K1_6] = t1.[Zaehler_1K1_6]) AND (t1.[CounterID] > t2.[CounterID])) ORDER BY [Zaehler_1K1_6] DESC, [CounterID])  AS [Zaehler_1K1_6-Differenz]
      ,[Zaehler_1K1_7]
      ,[Zaehler_1K1_7]-(SELECT TOP 1 [Zaehler_1K1_7] FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS t2 WHERE (t2.[Zaehler_1K1_7] < t1.[Zaehler_1K1_7]) OR((t2.[Zaehler_1K1_7] = t1.[Zaehler_1K1_7]) AND (t1.[CounterID] > t2.[CounterID])) ORDER BY [Zaehler_1K1_7] DESC, [CounterID])  AS [Zaehler_1K1_7-Differenz]


-- hier fehlen noch ein "paar" Anweisungen aber eben stets vom gleichen Aufbau
      

FROM         dbo.EnergieMonat AS t1
WHERE     (Datum BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0) AND DATEADD(ms, - 3, DATEADD(mm, 0, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0))))



Nun soll / muss das ganze eben via Syntax "verkleinert" werden

Link zu diesem Kommentar

achso! jetzt sind wir beieinander Ziel ist stets die Differenz vom Vormonat zum aktuellen Monat auszurechnen. Dabei sind die Werte aus den jeweiligen Zählern(wie der Name schon sagt *G*) zu verwenden. Das klappt auch alles bestens. Jedoch ist eben das Skript zu lang um den Source in ein DTSX Paket zu packen. wie schon geschrieben gehe ich von einer Begrenzung an Zeichen aus. Somit entsteht für mich die Notwendigkeit diese Abfrage so zu gestalten das sie einfach stur kürzer ist. ;)

 

Ich wird mal meinen Abend opfern und mir Skalarwertfunktion anschauen. Jedoch wäre mir auch an einer Lösung gelegen die meinen jetzigen Stand bzw. Herangehensweise umsetzen könnte.

 

Muss doch machbar sein! die While-Schleife steht doch schon!

Link zu diesem Kommentar

Ich wird mal meinen Abend opfern und mir Skalarwertfunktion anschauen. Jedoch wäre mir auch an einer Lösung gelegen die meinen jetzigen Stand bzw. Herangehensweise umsetzen könnte.

Das ist IMHO recht simpel, so ähnlich wie eine SP, nur dass Du die Funktion auch in einem SELECT benutzen kannst.

 

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[SCF_RestInEuro]
(
	-- Add the parameters for the function here
	@Budget money,
	@Kosten money
)
RETURNS money
AS
BEGIN
	-- Declare the return variable here
	DECLARE @output money
	BEGIN
	-- Add the T-SQL statements to compute the return value here
	SET @output = ISNULL(@Budget - @Kosten, ISNULL(@Budget,0)) 
	END
	-- Return the result of the function
	RETURN @output

END
Im SELECT kann das dann so aussehen:

 

 

SELECT dbo.SCF_RestInEuro(dbo.View_SummeBudgetJahr.SummeBudget, dbo.View_SummeAuftraegeJahr.SummeAuftraege) AS RestEuro,
Natürlich kannst Du auch alles mögliche andere mit einbauen. bearbeitet von Sunny61
Link zu diesem Kommentar
  • 3 Wochen später...

Moin,

 

ich würde unter SQL immer versuchen _keine_ While-Schleifen oder sehr viele Subselects einzusetzen.

 

Zerlege das Problem in kleine Schritte und schau dir jeweils die Zwischenergebnisse an:

- Annahme: die Zählerstande sind aufsteigend, das Feld Datum enthält das Datum zum Messwert.

 

1 .View mit den Monatszählerständen (hier nur ein Zähler):

 

SELECT YEAR([Datum]) as Jahr, MONTH([Datum]) as Monat,
      MAX([Zaehler_1K1_1]) AS AktuellerMonat
FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS AktMonat
GROUP BY YEAR([Datum]), MONTH([Datum])
 

2. "Hilfs"-View mit den Vormonatswerten in der aktuellen Monatszeile.

Das DATEADD dient nur dazu, die Monat- / Jahresspalten anders darzustellen (Monat + 1):

 

SELECT YEAR(DATEADD(mm, 1, [Datum]) as Jahr, MONTH(DATEADD(mm, 1, [Datum]) as Monat,
      MAX([Zaehler_1K1_1])
FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS VorMonat
GROUP BY YEAR(DATEADD(mm, 1, [Datum]), MONTH(DATEADD(mm, 1, [Datum])
 

3. Hinzufügen zweier Hilfsspalten:

 

SELECT YEAR([Datum]) as Jahr, MONTH([Datum]) as Monat,
      MAX([Zaehler_1K1_1]) AS AktuellerMonat, 0 AS Vormonat
FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS AktMonat
GROUP BY YEAR([Datum]), MONTH([Datum])
 

SELECT YEAR(DATEADD(mm, 1, [Datum]) as Jahr, MONTH(DATEADD(mm, 1, [Datum]) as Monat,
      0, MAX([Zaehler_1K1_1])
FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS VorMonat
GROUP BY YEAR(DATEADD(mm, 1, [Datum]), MONTH(DATEADD(mm, 1, [Datum])
 

Beide Tabelle haben nun das gleiche Format:

Jahr, Monat, AktuellerMonat, Vormonat

Mittels UNION ALL beide Views zusammenfügen und per erneutem GROUP BY

gruppieren. So würde dann der fertige View aussehen:

 

SELECT Jahr, Monat, SUM(AktuellerMonat), SUM(Vormonat), SUM(AktuellerMonat) - SUM(Vormonat) AS Differenz
FROM (
SELECT YEAR([Datum]) as Jahr, MONTH([Datum]) as Monat,
      MAX([Zaehler_1K1_1]) AS AktuellerMonat, 0 AS Vormonat
FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS AktMonat
GROUP BY YEAR([Datum]), MONTH([Datum])
UNION ALL



SELECT YEAR(DATEADD(mm, 1, [Datum]) as Jahr, MONTH(DATEADD(mm, 1, [Datum]) as Monat,
      0, MAX([Zaehler_1K1_1])
FROM [SKEMS-HST-POWER].[dbo].[EnergieMonat] AS VorMonat
GROUP BY YEAR(DATEADD(mm, 1, [Datum]), MONTH(DATEADD(mm, 1, [Datum])
) a 
GROUP BY Jahr, Monat
 
Für weitere Zähler die Zeilen "MAX([Zaehler_1K1_1]) AS AktuellerMonat, 0 AS Vormonat" und

"0, MAX([Zaehler_1K1_1])" kopieren und die Aliasnamen anpassen.

 

 

Gruß Kai

Link zu diesem Kommentar
Der letzte Beitrag zu diesem Thema ist mehr als 180 Tage alt. Bitte erstelle einen neuen Beitrag zu Deiner Anfrage!

Schreibe einen Kommentar

Du kannst jetzt antworten und Dich später registrieren. Falls Du bereits ein Mitglied bist, logge Dich jetzt ein.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor-Fenster leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...