SQL Server2008R2を使用してファイルを追跡するファイルシステムアプリがあります。ファイルを削除するときに、パス階層の親を更新して、新しいサイズを反映させたいと思います。現在のFILE_IDに@fid、FILE_SIZEに@ size、階層内の親のFILE_IDに@pidを使用しています。
これが私が使用しているループです:
SELECT @pid=PARENT_ID FROM FILES WHERE FILE_ID=@fid;
WHILE @pid<>0
BEGIN
UPDATE FILES
SET
FILE_SIZE =
-- Avoid potential situation where new file size might incorrectly drop below 0
CASE
WHEN FILE_SIZE-@size>=0 THEN FILE_SIZE-@size
ELSE 0
END
WHERE FILE_ID=@pid;
SET @fid=@pid;
SELECT @pid=PARENT_ID FROM FILES WHERE FILE_ID=@fid;
END
これを実行すると、サイズが更新されません。UPDATEをSELECTに置き換えると、正しく機能しているように見えます。何が起こっている? サイズが更新されないのはなぜですか?これを行うためのより良い方法はありますか?
コンテキストを追加するために、このスニップ-実際には別のループ内で実行されているため、複数のファイルをバッチで削除できます。このコンテキストでのコードは次のとおりです。
-- Declarations
DECLARE @fid int, @size int, @pid int;
DECLARE c CURSOR FOR
SELECT
FILE_ID, FILE_SIZE
FROM
FILES
OPEN c;
-- Initialize variables
FETCH NEXT FROM c
INTO @fid, @size;
-- Main loop
WHILE @@FETCH_STATUS = 0
BEGIN
-- Statements to delete the file --
-- Loop to update sizes --
SELECT @pid=PARENT_ID FROM FILES WHERE FILE_ID=@fid;
WHILE @pid<>0
BEGIN
UPDATE FILES
SET
FILE_SIZE =
CASE
WHEN FILE_SIZE-@size>=0 THEN FILE_SIZE-@size
ELSE 0
END
WHERE FILE_ID=@pid;
SET @fid=@pid;
SELECT @pid=PARENT_ID FROM FILES WHERE FILE_ID=@fid;
END
FETCH NEXT FROM c
INTO @fid, @size;
END
CLOSE c;
DEALLOCATE c;