NEWS
SQL Timeout von 15 sek erhöhen
-
Hallo Zusammen,
ich rufe mit SendTo eine SQL procedure auf, die leider länger als 15 sek benötigt (mehr optimieren kann ich sie auch leider nicht mehr).
Es sind einfach ca. 1 Mio Datensätze die recherchiert werden.
Nach 15 sek. wird SendTo aber abgebrochen mit einem TimeOut Fehler.Gibt es irgendeine Möglichkeit diese timeout Zeit zu erhöhen oder ist das im Adapter so definiert?
Die Fehlermeldung dazu ist:
javascript.0 (30008) script.js.SQL_Abfragen.SQL_DeltaAbfragen: RequestError: Timeout: Request failed to complete in 15000msDer Code im Script ist so:
function SQLquery() { var idQuery = myQueryDelta; if (logging>=2) log (xfunkName +'->'+arguments.callee.name+':'+'myQuery= '+idQuery,"info"); var xStart = new Date(); // Zeit messen sendTo('sql.0', 'query', idQuery, function (result) { var xTime = (new Date() - xStart)/1000; // Zeit s messen if (logging>=1) log (xfunkName +'->'+arguments.callee.name+':'+'myQuery= DAUER: '+xTime + " s / " + idQuery,"info"); setState(idTimeResult_Duration,xTime,true); if (result.error) { log(result.error); log (xfunkName +'->'+arguments.callee.name+':'+'myQuery= DAUER: '+xTime + " s / " + idQuery,"error"); } else { // show result if (logging>=1) log (xfunkName +'->'+arguments.callee.name+':'+'myQuery= DAUER: '+xTime + " s / " + idQuery,"info"); if (logging>=1) log (xfunkName +'->'+arguments.callee.name+':'+'myQueryresultJSON= '+JSON.stringify(result.result),"info"); setState(idResultJson,JSON.stringify(result.result),true); setState(idLastResult_CallWithoutError,formatDate(xStart, "TT.MM.JJJJ hh:mm:ss"),true); } }); }
Danke für jeden Tipp dazu.,
Gruss
Thomas -
@thomassch 1Million Datensätze ist ja nicht die Welt für ne DB, evtl. hat es dir die Indexe geschreddert. Bau die mal neu auf, wenn du magst kannst du auch mal die Procedure posten
-
Die Indizies sind neu erstellt, das bringt nicht so viel dass ich in unter die 15 sek komme.
Die Prozedure verdichtet Daten aus ts_number auf Stundenwerte und speichert diese dann in eine neue Tabelle, wobei ich hier immer nur die letzten 7 Tage anschaue, verdichte und kopiere, damit ich nicht immer 20 Mio Werte mit mehreren Jahren ständig berechnen muss.
Warum verdichte ich auf Stundenwerte m? Das ist eigentlich einfach, ich zeige Tabellen in der vis an in der ich über Jason eine Anzeige der Tages, Monats und Jahresverbräuche mache. Würde ich da ständig über alle Werte gehen in ts_number, würde es zu lange dauert.
Ich habe ganz bewusst keine Iobroker Datenpunkte erzeugt die auf Tage basieren, sondern wollte nachträglich meine alten absoluten Zählerstände verwenden können aus ts_number.
Ich denke das Problem ist dass ich mittlerweile 20 Mio Einträge in ts_number habe und 1 Mio in der Stundentabelle die ich erzeuge, die joins sind dann schon etwas aufwendiger.Die procedure kann ich gerne mal posten diese ist aber sehr lang und komplex, daher wollte ich erstmal versuchen die 15 Sekunden zu erhöhen.
Gruß
Thomas -
Für die die die procedure interessiert
USE [iobroker] GO /****** Object: StoredProcedure [dbo].[usp_CopyNewHoursValuesTable] Script Date: 22.06.2023 21:52:48 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Thomas Schatz -- Create date: 26.01.2023 -- Description: procedure für das Ermitteln der Differenzwerte pro Stunde -- ============================================= -- ein paar sammlungen von guten Abfragen -- --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy') as xYear, --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy-MM') as xMonth, --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy-MM-dd') as xDay, --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy-MM-dd HH') AS xLastDayHour, --FORMAT(dateadd(s,l.ts/1000,'19700101'),'yy-MM-dd HH:mm:ss') AS xTimeSec, -- ============================================= -- VERSION -- V5.0 ... inklusive löschen der Werte in IOBroker Werte die älter sind als 1 Tag -- ALTER PROCEDURE [dbo].[usp_CopyNewHoursValuesTable] -- Add the parameters for the stored procedure here @ClearAll INT = 0, -- 1 == löscht die letzten x-Tage, -1 läöscht dann alle Werte in der Tabell usr_IOBroker_Werte komplett @RunWithoutCopy INT = 1, -- 1== es wird nur angezeigt aber nichts kopiert @Debug int = 0, -- bei 1 werden alle Debugs angezeigt @DebugOnlyObject varchar(100) ='', @MaxDays INT = 1,-- maximale Anzahl der zu kopierenden Werte, damit die Abfragezeit nicht zu gross wird @StartDate datetime = '', @EndDate datetime = '' AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- sicherstellen das die Procedure nicht 2x läuft (1x IOBeroker Script und einmal hier im SQL Exec) BEGIN TRANSACTION -- Insert statements for procedure here DECLARE @xStartDate DATETIME, @xStartDateMin DATETIME, @xEndDate DATETIME, @xNewestDate DATETIME, @xNewest_IOWerte DATETIME, @xOldest_tsNumber DATETIME, @xOldest_IOWerte DATETIME; DECLARE @xTempDateTime DATETIME, @xTemp_Datetime DATETIME; DECLARE @xTempBigInt BIGINT; DECLARE @xStartDateUNIX BIGINT, @xEndDateUNIX BIGINT DECLARE @RunTime DATETIME; DECLARE @NewAnzahl as int, @NewAnzahl1 as int; DECLARE @myId as int; DECLARE @bNewest as bigint; DECLARE @OldValuesCount as bigint, @OldValuesCountBeforeDelete as bigint, @NewValuesCount as bigint; Declare @xOldest_ref as bigint; DECLARE @xNewest_IOWerte_AddDays as datetime; DECLARE @CountAnzahl as int, @runtimestart as datetime; DECLARE @CurrentTime as bigint; -- wurd ein Filterobject übergeben set @myId=0 if (@DebugOnlyObject<>'') BEGIN Select 'Es wurde ein FilterObject übergeben' select @DebugOnlyObject Select @myId = id from datapoints where name=@DebugOnlyObject END -- Tabelle erstellen, falls nicht extiert IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usr_IOBroker_Werte]') AND type in (N'U')) BEGIN CREATE TABLE dbo.usr_IOBroker_Werte ( id int not NULL, create_ts bigInt, UnixTime bigint, min_ts bigint, max_ts bigint, Zaehler real, [DateTime] datetime, Diff real, CONSTRAINT IOBroker_WerteIndex UNIQUE (id,min_ts) ) CREATE NONCLUSTERED INDEX [NonClusteredIndex-Test_UNIXtime_ID] ON [dbo].[usr_IOBroker_Werte] ( [id] ASC, [UnixTime] DESC, [DateTime] DESC ) select 'Tabelle mit Index erstellt' END DROP TABLE IF EXISTS #tempWERTE01 CREATE TABLE #tempWERTE01 ( xRowCount int NOT NULL, xId int NOT NULL, xUnixTime bigint NOT NULL, min_ts bigint NULL, max_ts bigint NULL, xZaehler real NULL, CONSTRAINT tempWERTE01_Index UNIQUE (xid,xUnixTime) ) CREATE NONCLUSTERED INDEX ix_tempWERTE01 ON #tempWERTE01 ([xId],[xUnixTime] DESC); DROP TABLE IF EXISTS #tempWERTE02 CREATE TABLE #tempWERTE02 ( xId int NOT NULL, xUnixTime bigint NOT NULL, min_ts bigint NULL, max_ts bigint NULL, xZaehler real NULL, xDiff real NULL, CONSTRAINT tempWERTE02_Index UNIQUE (xid,xUnixTime) ) CREATE NONCLUSTERED INDEX ix_tempWERTE02 ON #tempWERTE02 ([xId],[xUnixTime] DESC,[min_ts]); -- falls die Tabelle geloescht werden soll if (@ClearAll=-1) BEGIN if (EXISTS (select TOP 1 1 from usr_IOBroker_Werte)) BEGIN if @Debug>0 Select 'IOBroker Werte (Alle) werden alle gelöscht TRUNCATE' if @Debug>0 select count(*) as 'Anzahl Werte in IOBroker_Werte vor loeschen' from dbo.usr_IOBroker_Werte TRUNCATE TABLE dbo.usr_IOBroker_Werte if @Debug>0 select count(*) as 'Anzahl Werte in IOBroker_Werte nach loeschen' from dbo.usr_IOBroker_Werte END END -- falls xTage von Tabelle geloescht werden sollen if (@ClearAll>0) BEGIN if (EXISTS (select TOP 1 1 from usr_IOBroker_Werte)) BEGIN if @Debug>0 Select 'IOBroker Werte (x-Tage) werden alle gelöscht TRUNCATE' if @Debug>0 select count(*) as 'Anzahl Werte in IOBroker_Werte vor loeschen' from dbo.usr_IOBroker_Werte -- nun die x-Tage loeschen --select @xNewest_IOWerte=dateadd(SECOND,max(UnixTime)/1000, '01.01.1970 00:00:00.0') from usr_IOBroker_Werte select @xNewest_IOWerte=dateadd(SECOND,max(UnixTime)/1000, '01.01.1970 00:00:00.0') from usr_IOBroker_Werte select @xTemp_Datetime=Dateadd(day,-@ClearAll,DATETIMEFROMPARTS(YEAR(@xNewest_IOWerte),MONTH(@xNewest_IOWerte),DAY(@xNewest_IOWerte),0,0,0,0)) select @xTempBigInt=DATEDIFF(SECOND,'01.01.1970 00:00:00.0',@xTemp_Datetime) if @Debug>0 Select @xNewest_IOWerte as 'Neuste Werte in Tabelle @xNewest_IOWerte=:' if @Debug>0 Select @xTemp_Datetime as 'Loesche alles Älter als@xTemp_Datetime=:' if @Debug>0 Select @xTempBigInt as 'Sekunden für Delete Abfrage @xTempBigInt=:' if @RunWithoutCopy=0 BEGIN DELETE from usr_IOBroker_Werte where UnixTime/1000>=@xTempBigInt AND id = (CASE WHEN @myId=0 THEN id ELSE @myId END) END if @Debug>0 select count(*) as 'Anzahl Werte in IOBroker_Werte nach loeschen' from dbo.usr_IOBroker_Werte if @Debug>2 BEGIN select FORMAT(dbo.fn_Convert_UNIX_2_UTCDateTime(UnixTime),'yy-MM-dd HH:mm:ss') as ts_lesbar_UTC, * from usr_IOBroker_Werte where UnixTime/1000>=@xTempBigInt AND id = (CASE WHEN @myId=0 THEN id ELSE @myId END) END END END -- schauen wir mal ob IOBorker_Werte mnoch leer ist if (NOT EXISTS (select TOP 1 1 from usr_IOBroker_Werte)) BEGIN -- IOBroker leer if @Debug>0 select 'der Neueste Wert in der Tabelle usc_IOBroker_Werte ist NULL, daher jetzt mal den ältesten Wert in ts_number suchen' set @xOldest_tsNumber=(select dbo.fn_Convert_UNIX_2_DateTime(min(ts)) from ts_number); if @Debug>0 select @xOldest_tsNumber as 'Wir nehmen als Startwert den Wert von in ts_number:' SET @xStartDate= @xOldest_tsNumber -- als EndeDatum setzen wir Startdatum plus die Anzahl der Tage die kopiert werden dürfen laut Übergabe SET @xEndDate=dateadd(day,@MaxDays, @xStartDate) if @Debug>0 select (@MaxDays) as 'Anzahl der Tage die kopiert werden sollen:' END ELSE BEGIN -- Werte in IOBroker vorhanden if @Debug>0 select @MaxDays as 'MaxDays:' -- ermitteln wir wieviele Werte in der Tabelle stehen set @OldValuesCountBeforeDelete=(select count(*) from dbo.usr_IOBroker_Werte) -- wir leoschen mal den letzte Stunde in der IOBorkerWerte Tabelle, der sollte meist nur angefangen sein und keine volle Stunde beinhalten select @xNewest_IOWerte=dateadd(SECOND,max(UnixTime)/1000, '01.01.1970 00:00:00.0') from usr_IOBroker_Werte if @Debug>0 select @xNewest_IOWerte as '@xNewest_IOWerte=' if @Debug>0 select dateadd(hour, -1,GETUTCDATE()) as 'dateadd(hour, -1,GETUTCDATE())=' if @xNewest_IOWerte>=dateadd(hour, -1,GETUTCDATE()) begin if @Debug>0 BEGIN select 'wir loeschenletzte stunde, das wären dann:' SELECT dateadd(SECOND,UnixTime/1000, '01.01.1970 00:00:00.0'),* from usr_IOBroker_Werte where UnixTime/1000>DATEDIFF(SECOND,'01.01.1970 00:00:00.0',Dateadd(hour,-1,@xNewest_IOWerte)) AND id = (CASE WHEN @myId=0 THEN id ELSE @myId END) END DELETE from usr_IOBroker_Werte where UnixTime/1000>DATEDIFF(SECOND,'01.01.1970 00:00:00.0',Dateadd(hour,-1,@xNewest_IOWerte)) AND id = (CASE WHEN @myId=0 THEN id ELSE @myId END) END select @xNewest_IOWerte=dbo.fn_Convert_UNIX_2_DateTime(max(min_ts)) from usr_IOBroker_Werte if @Debug>0 select @xNewest_IOWerte as 'usr_IOBroker_Werte vorhanden, hier ist der neueste Wert min_ts:' set @xNewest_IOWerte_AddDays=dateadd(day,@MaxDays,@xNewest_IOWerte) if @Debug>0 select @xNewest_IOWerte_AddDays as 'neuester Wert von usr_IOBroker_Werte + MaxDays:' select @xOldest_ref=dbo.fn_Convert_DateTime_2_ts_sec(@xNewest_IOWerte_AddDays) if @Debug>0 select @xOldest_ref as '@xOldest_ref:' select @xOldest_tsNumber=ISNULL((select dbo.fn_Convert_UNIX_2_DateTime(min(ts)) from ts_number where ts/1000>@xOldest_ref),GETUTCDATE()) if @Debug>0 select @xOldest_tsNumber as 'Der älterste Wert von ts_number der größer ist als der neuste IOBroker_Wert Eintrag + MaxDays:' SET @xStartDate=dateadd(day,-1, @xNewest_IOWerte) SET @xEndDate=@xOldest_tsNumber END -- falls Start und Ende übergeben, dann machen wir nur das if @StartDate<>'' BEGIn if @Debug>0 select 'Start und Ende übergeben, Abfrage auf diese Werte begrenzen' SET @xStartDate=@StartDate SET @xEndDate=@EndDate END /* --- schauen wir mal welche number_ts das betrift if (@Debug>0) BEGIN select dbo.fn_Convert_ts_sec2DateTime(ts/1000), * from ts_number where (ts/1000) >= @xStartDateUNIX and (ts/1000) < @xEndDateUNIX and id = (CASE WHEN @myId=0 THEN id ELSE @myId END) order by ts DESC END -- Welches Messwwerte schauen wir an? if (@Debug>0) BEGIN select 'ts_number, diese Werte schauen wir an' select ts as xts, dbo.fn_Convert_UNIX_2_UTC(ts) as ts_in_UTC, FORMAT(dateadd(s,ts/1000,'19700101'),'yy-MM-dd HH:mm:ss') as ts_in_Format_ohne_UTC, @xStartDate as xStartFilter_ts, dbo.fn_ConvertUTC2Local(@xStartDate) as xStartFilter_UTC, @xEndDate as xEndeFilter_ts, dbo.fn_ConvertUTC2Local(@xEndDate) as x@xEndeFilter_UTC, * from ts_number where id = @myId AND ts >= dbo.fn_ConvertUTC2IOBrokerTS(@xStartDate) AND ts < dbo.fn_ConvertUTC2IOBrokerTS(@xEndDate) order by ts DESC; END */ set @runtimestart=getUTCdate() set @CountAnzahl=0 while (@CountAnzahl=0 and datediff(SECOND,@runtimestart,getUTCdate())<30) begin if @Debug>0 select 'while schleife startr' if @Debug>0 select datediff(SECOND,@runtimestart,getUTCdate()) as 'laufzeit' -- wir loeschen mal die temporären Tabellen TRUNCATE TABLE #tempWERTE01 TRUNCATE TABLE #tempWERTE02 -- berechnen wir enddatum if @xEndDate>GETUTCDATE() BEGIN if @Debug>0 select 'Endedatum ist größer als aktuelles Datum, daher mal begrenzen auf aktuelles Datum!' set @xEndDate=GETUTCDATE() END if @Debug>0 select @xStartDate as 'Filter Startzeit' if @Debug>0 select @xEndDate as 'Filter Endezeit'; -- un nun Start un Ende als UNIXWert d.h. ohne UTC Verschiebung SET @xStartDateUNIX=[dbo].[fn_Convert_DateTime_2_ts_sec](@xStartDate) SET @xEndDateUNIX=[dbo].[fn_Convert_DateTime_2_ts_sec](@xEndDate) --select dbo.fn_Convert_ts_sec2DateTime(@xStartDateUNIX) as 'Filter @xStartDateUNIX', @xStartDateUNIX as 'as ts' --select dbo.fn_Convert_ts_sec2DateTime(@xEndDateUNIX) as 'Filter @xEndDateUNIX', @xEndDateUNIX as 'as ts' -- und nun mal versuchen die neue Tabelle zu füllen --- wir ermitteln damit nicht ein einfaches MIN oder MAX, das würde mit GROUP schon gehen, sondern -- holen uns den letzten Wert des Tages aus ts_number und speichern diesen -- es wird hier mit xRC doppelte Einträge in ts_number gefiltert, das kann z.B. passieren, wenn zur gleichen Zeit ein Wert vom Adapter kommt und der SQL Server einen Wert schreibt wenn er aufzeichnen soll alle x-sekunden if @Debug>0 select 'Alle Objekte: ermitteln wir mal die Werte im Intervall 1 h und kopieren diese in #tempWERTE01' insert into #tempWERTE01 ( xRowCount, xId, min_ts,max_ts, xUnixTime, xZaehler ) select * from ( SELECT ROW_NUMBER() OVER(PARTITION BY l.id,l.ts ORDER BY l.ts DESC) xRC, l.id as xId, m.min_ts as min_ts, m.max_ts as max_ts, l.ts as xUnixTime, l.val AS xZaehler FROM ts_number l INNER JOIN ( SELECT MAX(x.id) as xid, x.ts/1000/(60*60) as d, MIN(x.ts) as min_ts, MAX(x.ts) as max_ts FROM ts_number x Where x.id = (CASE WHEN @myId=0 THEN x.id ELSE @myId END) AND (x.ts/1000) >= @xStartDateUNIX --AND (x.ts/1000) >= datediff(s, '1970.01.01', @xStartDateUNIX) AND (x.ts/1000) < @xEndDateUNIX GROUP BY x.id, x.ts/1000/(60*60) -- 1 h ) m ON ( l.id=m.xid AND l.ts = m.max_ts ) WHERE ---shere bezeiht sich auf den gesamten Join --xRC = 1 l.id = (CASE WHEN @myId=0 THEN l.id ELSE @myId END) And l.val IS NOT NULL And l.val>=0 And (l.ts/1000) >= @xStartDateUNIX and (l.ts/1000) < @xEndDateUNIX ) aa where aa.xRC=1 if (@Debug>0) BEGIN select 'temp01 Inhalt anzeigen' select xUnixTime as xxts, dbo.fn_Convert_UNIX_2_UTCDateTime(xUnixTime) as ts_in_UTC, FORMAT(dateadd(s,xUnixTime/1000,'19700101'),'yy-MM-dd HH:mm:ss') as ts_in_Format_ohne_UTC, @xStartDate as xStartFilter_ts, dbo.fn_Convert_UTCDateTime_2_ts_sec(@xStartDate) as xStartFilter_UTC, @xEndDate as xEndeFilter_ts, dbo.fn_Convert_UTCDateTime_2_ts_sec(@xEndDate) as xEndeFilter_UTC, * from #tempWERTE01 order by xId ASC, xUnixTime DESC; END /* if (@Debug>0) BEGIN select 'temp01 vor dem Löschen doppelter Werte' SELECT COUNT(*) from #tempWERTE01; END -- wir loeschen einfach die doppelten werte, falls IOBroker mal zu einem Zeitpunkt sowohl den Messwerte bekommt -- als auch den eingestellten Wert der Aufgezeichnet werden soll im Intervall -- damit verhindern wir beim Insert eine Schlüsselverletzung WITH cte AS ( SELECT xId, xUnixTime, ROW_NUMBER() OVER ( PARTITION BY xId, xUnixTime ORDER BY xId, xUnixTime ) row_num FROM #tempWERTE01 ) DELETE FROM cte WHERE row_num > 1; select 'temp01 NACH dem Löschen doppelter Werte' select * from #tempWERTE01; */ -- und nun mal mit der internen SQL Funktion lag - die Differenz zum vorherigen Wert ermitteln --select 'und nun die Differenz immer zum letzten Wert:' insert into #tempWERTE02 ( xId, min_ts,max_ts, xUnixTime, xZaehler,xDiff ) SELECT xId, min_ts,max_ts, xUnixTime, xZaehler, round((xZaehler-lag(xZaehler) over (partition by xid order by (xUnixTime/1000/(60*60)))),3) -- 1 h --(xZaehler-lag(xZaehler) over (partition by xid order by FORMAT(dbo.fn_Convert_UNIX_2_UTC(xUnixTime),'yy-MM-dd HH'))) FROM #tempWERTE01 ; -- Werte anzeigen if (@Debug>0) BEGIN select 'Inhalt #tempWerte02 anzeigen:'; --set rowcount @MaxCount; Select dbo.fn_Convert_UNIX_2_UTCDateTime(xUnixTime) as xUnixTimeUTC, * from #tempWERTE02 order by xId ASC, xUnixTime DESC END; -- unsinnige Werte anzeigen if (@Debug>0) BEGIN select 'Unsinnige Inhalt #tempWerte02 anzeigen:'; Select dbo.fn_Convert_UNIX_2_UTCDateTime(xUnixTime) as xUnixTimeUTC, * from #tempWERTE02 where xDiff<0 OR xDiff>(xzaehler*1.5) order by xId ASC, xUnixTime DESC END; -- Sprünge die keinen Sinn machen löschen delete from #tempWERTE02 where xDiff<0 OR xDiff>(xzaehler*1.5); /* -- versuchen wir mal einen totalen Zaehler zu bauen --select 'und nun ergänzen wir einen totalen neuen laufenden Zähler:' select *, sum(xDiff) over(order by xDay rows unbounded preceding) as xSumTotal, (select name from datapoints where id=rr.xid) as xObject FROM tempWERTE02 rr; */ -- wieviele Werte wären neu? with xAnzahl as ( SELECT DISTINCT s.xId, s.min_ts, s.max_ts, s.xUnixTime, s.xZaehler, s.xDiff from #tempWERTE02 s WHERE NOT EXISTS (SELECT * FROM dbo.usr_IOBroker_Werte t WHERE t.id = s.xId --AND t.UnixTime = s.xUnixTime and t.min_ts = s.min_ts --- hier mal schauen ob der Startwert schon vorhanden ist --and s.xUnixTime IS NOT NULL ) ) select @CountAnzahl=count(*) from xAnzahl --select @CountAnzahl=0 if @Debug>0 select @CountAnzahl as 'Anzahl der kopierenden werte' if (@CountAnzahl=0) begin set @xEndDate=dateadd(day,@MaxDays,@xEndDate); if @Debug>0 select @xEndDate as 'keine werte erkannt und kopiert, enddate erhöhen!' end else begin break end if @xEndDate>GETUTCDATE() BEGIN if @Debug>0 select 'Endedatum ist größer als aktuelles Datum, daher mal begrenzen auf aktuelles Datum!' break END if @EndDate<>'' begin if @xEndDate>@EndDate BEGIN if @Debug>0 select 'Endedatum ist größer als @EndDate, wir stoppen die Schleife!' break END END End; -- ####### WHILE set @OldValuesCount=(select count(*) from dbo.usr_IOBroker_Werte) if (@RunWithoutCopy=0) BEGIN if @Debug>0 select 'Funktion mit RunWithoutCopy=0 gestartet d.h. es werden neue Werte kopiert!' -- Werte in die echte neue Tabelle übernehmen --select 'und nun die Werte in die neue Tabelle kopieren:' set @CurrentTime = DATEDIFF(SECOND,'01.01.1970',getUTCDate()) if @Debug>0 select @CurrentTime as '@CurrentTime=' INSERT INTO dbo.usr_IOBroker_Werte ( id, create_ts, min_ts, max_ts, UnixTime, [DateTime], Zaehler, Diff ) SELECT DISTINCT s.xId, @CurrentTime, s.min_ts, s.max_ts, s.xUnixTime, dbo.fn_Convert_UNIX_2_UTCDateTime(s.xUnixTime), s.xZaehler, s.xDiff from #tempWERTE02 s WHERE NOT EXISTS (SELECT * FROM dbo.usr_IOBroker_Werte t WHERE t.id = s.xId AND ( t.UnixTime = s.xUnixTime or t.min_ts = s.min_ts ) --- hier mal schauen ob der Startwert schon vorhanden ist --and s.xUnixTime IS NOT NULL ); END ELSE BEGIN if @Debug>0 select 'Funktion mit RunWithoutCopy gestartet d.h. es werden keine neuen Werte kopiert' END set @NewValuesCount = (select count(*) from dbo.usr_IOBroker_Werte) select @xStartDate as 'Startzeit', @xEndDate as 'Endezeit', (@NewValuesCount-@OldValuesCount) as 'Created', (@NewValuesCount-@OldValuesCountBeforeDelete) as 'New', @NewValuesCount as 'WerteIOBrokerTable' if (@Debug>=2) BEGIN select 'alle werte in IOBroker_Werte anzeigen' SELECT TOP 1000 dbo.fn_Convert_ts_sec_2_UTCDateTime(create_ts) as create_ts_UTC, FORMAT(dbo.fn_Convert_UNIX_2_UTCDateTime(UnixTime),'yy-MM-dd HH:mm:ss') as ts_lesbar_UTC, FORMAT(dbo.fn_Convert_UNIX_2_UTCDateTime(max_ts),'yy-MM-dd HH:mm:ss') as xMax_UTC, FORMAT(dbo.fn_Convert_UNIX_2_UTCDateTime(min_ts),'yy-MM-dd HH:mm:ss') as xMin_UTC, * from usr_IOBroker_Werte where Id = (CASE WHEN @myId=0 THEN Id ELSE @myId END) -- DEBUG order by UnixTime desc --select count(*) as 'Anzahl Werte in IOBroker_Werte' from dbo.usr_IOBroker_Werte END; -- wir loeschen nun alles temporäre drop table #tempWERTE01 drop table #tempWERTE02 COMMIT TRANSACTION END