updateステートメントでユーザー定義関数を使用してテーブルを更新しようとすると、問題が発生しました。SQL Server - 更新ステートメントでユーザー定義関数を使用してテーブルを正しく更新する方法
私は既存のSQLを大幅に簡略化し、私が見ている問題を示すサンプルコードを提供しました。私は私が欲しいもの、同じタイムスタンプ
と100行の3セットにMyTestTableで300行のグループに必要な、私はすべて同じタイムスタンプ値
でテストテーブルに300行から始め
:Timestamp Count
2016-04-01 15:51:00 100
2016-04-01 15:52:00 100
2016-04-01 15:53:00 100
は、私が今見ていることは同じタイムスタンプで更新されたすべての300行である:表示するには、このようなものです
Timestamp Count
2016-04-01 15:51:00 300
このクエリを作成する最も良い方法は何ですか?以下は
問題
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]
実際にトランザクションは独自の変更を見ることができますが、問題は恐らくステートメントレベルのHaloween Protectionです。 –
はい、私はそうでなければならないと考えました。更新ステートメントが完了するまで、変更は表示されません。だから、どうやって私が探している結果を得るために別の方法でこのクエリを書くことができますか?私が提供した簡単な例では、300行を使用しましたが、実際のコードは毎分1000行ずつ更新されます。だから私はかなり効率的な何かを探しています。 –
カーソルを使って一度に1つの行をループすることで、これを動作させることができますが、これを達成するためのより効率的な方法が必要だと思いますか? @JackAllen。 –