我有一个表格,用于存储有关文件的数据;使用PreviousFileId和NextFileID字段链接文件,这是一个数据示例:
+--------+----------+-----------+----------------+------------+----------------+
| FileID | FileCode | FileOrder | PreviousFileID | NextFileID | ParentFileCode |
+--------+----------+-----------+----------------+------------+----------------+
| 1000 | FILE-A | 1 | NULL | 1001 | NULL |
| 1001 | FILE-B | 2 | 1000 | 1002 | NULL |
| 1002 | FILE-C | 3 | 1001 | NULL | NULL |
| 1003 | FILE-D | 1 | NULL | NULL | FILE-A |
| 1004 | FILE-E | 2 | NULL | NULL | FILE-B |
| 1005 | FILE-F | 3 | NULL | NULL | FILE-C |
+--------+----------+-----------+----------------+------------+----------------+
我想创建一个存储过程来更新文件1003,1004和1005之间的链接。该过程应该接受ParentFileCode作为参数,例如,如果我将'FILE-B'作为参数传递,数据应该看起来像这在执行存储过程之后:
+--------+----------+-----------+----------------+------------+----------------+
| FileID | FileCode | FileOrder | PreviousFileID | NextFileID | ParentFileCode |
+--------+----------+-----------+----------------+------------+----------------+
| 1000 | FILE-A | 1 | NULL | 1001 | NULL |
| 1001 | FILE-B | 2 | 1000 | 1002 | NULL |
| 1002 | FILE-C | 3 | 1001 | NULL | NULL |
| 1003 | FILE-D | 1 | NULL | 1004 | FILE-A |
| 1004 | FILE-E | 2 | 1003 | 1005 | FILE-B |
| 1005 | FILE-F | 3 | 1004 | NULL | FILE-C |
+--------+----------+-----------+----------------+------------+----------------+
这是表结构/插入数据代码:
CREATE TABLE Files
(
FileID INT NOT NULL,
FileCode VARCHAR(20) NOT NULL,
FileOrder INT NOT NULL,
PreviousFileID INT NULL,
NextFileID INT NULL,
ParentFileCode VARCHAR(20) NULL
)
INSERT INTO dbo.Files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode)
VALUES (1000, 'FILE-A', 1, NULL, 1001, NULL)
INSERT INTO dbo.Files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode)
VALUES (1001, 'FILE-B', 2, 1000, 1002, NULL)
INSERT INTO dbo.Files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode)
VALUES (1002, 'FILE-C', 3, 1001, NULL, NULL)
INSERT INTO dbo.Files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode)
VALUES (1003, 'FILE-D', 1, NULL, NULL, 'FILE-A')
INSERT INTO dbo.Files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode)
VALUES (1004, 'FILE-E', 2, NULL, NULL, 'FILE-B')
INSERT INTO dbo.Files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode)
VALUES (1005, 'FILE-F', 3, NULL, NULL, 'FILE-C')
关于如何实现这一点的任何想法?
答案 0 :(得分:0)
尝试这样的事情:
update table
set
previousfileid= lag(fileid, 1, 0) over(order by fileorder) ,
nextfileid= lead(fileid, 1, 0) over(order by fileorder)
from table_name
where parentfilecode is not null
答案 1 :(得分:0)
好的,我将您的示例数据放入临时表中,因为我发现这更容易使用:
IF OBJECT_ID('tempdb..#files') IS NOT NULL
DROP TABLE #files;
CREATE TABLE #files (
FileID INT NOT NULL,
FileCode VARCHAR(20) NOT NULL,
FileOrder INT NOT NULL,
PreviousFileID INT NULL,
NextFileID INT NULL,
ParentFileCode VARCHAR(20) NULL);
INSERT INTO #files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode) VALUES (1000, 'FILE-A', 1, NULL, 1001, NULL);
INSERT INTO #files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode) VALUES (1001, 'FILE-B', 2, 1000, 1002, NULL);
INSERT INTO #files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode) VALUES (1002, 'FILE-C', 3, 1001, NULL, NULL);
INSERT INTO #files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode) VALUES (1003, 'FILE-D', 1, NULL, NULL, 'FILE-A');
INSERT INTO #files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode) VALUES (1004, 'FILE-E', 2, NULL, NULL, 'FILE-B');
INSERT INTO #files (FileID, FileCode, FileOrder, PreviousFileID, NextFileID, ParentFileCode) VALUES (1005, 'FILE-F', 3, NULL, NULL, 'FILE-C');
方法1是做Daniel所说的,做了一些调整(将0变成NULL,因为你不能直接在{{1}中使用LEAD
/ LAG
}):
UPDATE
请注意,这并不是一个参数,只是更新整个表格。
这是一个使用三个UPDATE语句的方法,它有一个参数:
--Method #1
WITH x AS (
SELECT
FileId,
PreviousFileID = LAG(FileId, 1, NULL) OVER (ORDER BY FileOrder),
NextFileID = LEAD(FileId, 1, NULL) OVER (ORDER BY FileOrder)
FROM
#files f
WHERE
ParentFileCode IS NOT NULL)
UPDATE
f
SET
PreviousFileId = x.PreviousFileId,
NextFileId = x.NextFileId
FROM
#files f
INNER JOIN x ON x.FileId = f.FileId;
这两种方法都适用于这一小部分数据,因此我建议针对较大的数据集进行测试?然后,您需要将它们变为存储过程,这只是添加--Method #2
DECLARE @file VARCHAR(50) = 'FILE-B';
UPDATE
fx
SET
PreviousFileId = fxp.FileID,
NextFileID = fxn.FileId
FROM
#files f --Anchor
LEFT JOIN #files p ON p.FileID = f.PreviousFileID --previous file
LEFT JOIN #files n ON n.FileId = f.NextFileID --current file
INNER JOIN #files fx ON fx.ParentFileCode = 'FILE-B' --files to update
LEFT JOIN #files fxp ON fxp.ParentFileCode = p.FileCode
LEFT JOIN #files fxn ON fxn.ParentFileCode = n.FileCode
WHERE
f.FileCode = @file;
UPDATE
fxp
SET
NextFileID = fx.FileId
FROM
#files f --Anchor
LEFT JOIN #files p ON p.FileID = f.PreviousFileID --previous file
LEFT JOIN #files n ON n.FileId = f.NextFileID --current file
INNER JOIN #files fx ON fx.ParentFileCode = 'FILE-B' --files to update
INNER JOIN #files fxp ON fxp.ParentFileCode = p.FileCode
WHERE
f.FileCode = @file
UPDATE
fxn
SET
PreviousFileId = fx.FileID
FROM
#files f --Anchor
LEFT JOIN #files p ON p.FileID = f.PreviousFileID --previous file
LEFT JOIN #files n ON n.FileId = f.NextFileID --current file
INNER JOIN #files fx ON fx.ParentFileCode = 'FILE-B' --files to update
INNER JOIN #files fxn ON fxn.ParentFileCode = n.FileCode
WHERE
f.FileCode = @file;
...等的情况。