Fehler beim Versuch, eine Tabelle mithilfe einer benutzerdefinierten Funktion in der Update-Anweisung zu aktualisieren.SQL Server - Wie Aktualisieren der Tabelle mit benutzerdefinierter Funktion in Update-Anweisung?
Ich habe mein vorhandenes SQL stark vereinfacht und einen Beispielcode zur Verfügung gestellt, um das Problem zu zeigen, das ich sehe.
Ich beginne mit 300 Zeilen in einer Testtabelle alle mit dem gleichen Zeitstempel Wert
ich zu einer Gruppe muß die 300 Zeilen in MyTestTable in 3 Sätze von 100 Zeilen mit demselben Zeitstempel aus
Was ich will, so etwas zu sehen ist:
Timestamp Count
2016-04-01 15:51:00 100
2016-04-01 15:52:00 100
2016-04-01 15:53:00 100
Was ich jetzt sehen, ist alle 300 Zeilen mit dem gleichen Zeitstempel aktualisiert:
Timestamp Count
2016-04-01 15:51:00 300
Was ist der beste Weg, um diese Abfrage zu formulieren?
Nachfolgend finden Sie einige vereinfachte Beispielcode, der das Problem für einen Kommentar
CREATE TABLE [MyTestTable]
(
[ID] [int],
[Timestamp] [smalldatetime]
) ON [PRIMARY]
GO
CREATE FUNCTION [dbo].[fn_MyTestFunction]
(@StartTime smalldatetime,
@EndTime smalldatetime,
@RandomNumberOfSeconds int)
RETURNS smalldatetime
AS
BEGIN
DECLARE @Timestamp SMALLDATETIME
-- Find an existing Timestamp between @StartTime and @EndTime in the MyTestTable
-- with less than 100 rows with that timestamp
SET @Timestamp = (SELECT TOP 1 [Timestamp]
FROM MyTestTable
WHERE [Timestamp] BETWEEN @StartTime AND @EndTime
GROUP BY [Timestamp]
HAVING COUNT(*) < 100)
-- If no row found with timestamp between @StartTime and @EndTime
-- or no timestamp found which has less than 100 rows with that timestamp
-- Create a timestamp with a time somewhere between @StartTime and @EndTime
if (@Timestamp is null)
begin
set @Timestamp = dateadd(ss, @RandomNumberOfSeconds, @StartTime)
end
return @Timestamp
END
GO
declare @Counter int
set @Counter = 0
-- Populate the test table with 300 rows, all initially with the same timestamp value
while @Counter < 300
begin
insert MyTestTable (ID, [Timestamp]) values (@Counter, 'April 1, 2016')
set @Counter = @Counter + 1
end
declare @StartTime smalldatetime
declare @EndTime smalldatetime
declare @RandomNumberOfSeconds float
set @RandomNumberOfSeconds = 60
set @StartTime = current_timestamp
set @EndTime = dateadd(minute, 30, @StartTime)
update MyTestTable
set [Timestamp] = dbo.fn_MyTestFunction(@StartTime, @EndTime, @RandomNumberOfSeconds)
select [Timestamp], count(*) as "Count"
from MyTestTable
group by [Timestamp]
Tatsächlich kann eine Transaktion ihre eigenen Änderungen sehen, das Problem ist vermutlich Anweisung Haloween Protection. –
Ja, ich dachte, dass das der Fall sein muss, dass Änderungen nicht sichtbar sind, bis die Update-Anweisung abgeschlossen ist. Wie könnte ich diese Abfrage anders schreiben, um die gewünschten Ergebnisse zu erhalten? In dem einfachen Beispiel, das ich zur Verfügung gestellt habe, habe ich 300 Zeilen verwendet, aber der echte Code aktualisiert jede Minute 1000 Zeilen. Ich suche also etwas ziemlich Effektives. –
Ich kann dies mit einem Cursor und der Schleife durch eine Zeile zu arbeiten, aber ich denke, es muss einen effizienteren schnelleren Weg, dies zu erreichen? –