我有一个用于重新排序列的系统。我有一个允许用户禁用列的功能。这会在数据库中将其列顺序设置为null并将其设置为禁用,但我需要能够更新ColumnOrder列以使用新订单更新剩余的已启用记录。
当我禁用“客户类型”时,我的表格就是这样的。你可以看到我现在剩下4条已启用的记录但是我需要给它们新的ColumnOrder数字1,2,3,4(不需要5):
ID ColumnID UserID Text ColumnOrder Enabled?
50 22 1 'id' 1 1
51 1 1 'Cust Types' NULL 0
52 2 1 'Description' 2 1
53 3 1 'Apply VAT' NULL 0
54 4 1 'Produce Invoices?' 4 1
55 5 1 'Purchase Sale' 5 1
56 6 1 'Terms Days' NULL 0
57 7 1 'Date Time Last Updated' NULL 0
以下是启用或禁用记录的过程:
IF EXISTS ( SELECT [Enabled?]
FROM dbo.CustomerLocalizationColumns CLC
INNER JOIN Portal.dbo.Columns C
ON CLC.ColumnID = C.ID
WHERE UserID = @UserID
AND ColumnID = @ColumnID
AND CLC.[Enabled?] = 0 )
BEGIN
UPDATE dbo.CustomerLocalizationColumns
SET [Enabled?] = 1
,ColumnOrder = (
SELECT COUNT(*) + 1
FROM dbo.CustomerLocalizationColumns
WHERE [Enabled?] = 1
)
WHERE (
SELECT [Enabled?]
FROM dbo.CustomerLocalizationColumns CLC
INNER JOIN Portal.dbo.Columns C
ON CLC.ColumnID = C.ID
WHERE UserID = @UserID
AND ColumnID = @ColumnID
) = 0
AND dbo.CustomerLocalizationColumns.UserID = @UserID
AND dbo.CustomerLocalizationColumns.ColumnID = @ColumnID
END
ELSE
BEGIN
UPDATE dbo.CustomerLocalizationColumns
SET [Enabled?] = 0
,ColumnOrder = NULL
WHERE (
SELECT [Enabled?]
FROM dbo.CustomerLocalizationColumns CLC
INNER JOIN Portal.dbo.Columns C
ON CLC.ColumnID = C.ID
WHERE UserID = @UserID
AND ColumnID = @ColumnID
) = 1
AND dbo.CustomerLocalizationColumns.UserID = @UserID
AND dbo.CustomerLocalizationColumns.ColumnID = @ColumnID
END
END
答案 0 :(得分:0)
试试这个..
我可以使用ROWNUMBER()
为您的非空列生成新列顺序,然后update
在同一传递中为您的表生成
WITH CTE
AS (
SELECT *
, ROW_NUMBER() OVER (
ORDER BY columnorder
) ROWNUM
FROM CustomerLocalizationColumns
WHERE columnorder IS NOT NULL
--Could also use Enabled=1
)
UPDATE A
SET columnorder = rownum
FROM CustomerLocalizationColumns A
INNER JOIN CTE
ON A.Columnid = CTE.Columnid
WHERE columnorder IS NOT NULL
--Could also use Enabled=1;
端到端样本:
DECLARE @tble TABLE (
Columnid VARCHAR(30)
, columnorder INT
)
insert into @tble
SELECT 'a', 1 UNION all
SELECT 'b', 2 UNION all
SELECT 'c', NULL UNION all
SELECT 'd', 6 UNION all
SELECT 'e', NULL UNION all
SELECT 'f', 8
--BEFORE UPDATE
SELECT *
FROM @tble;
--UPDATING
WITH CTE
AS (
SELECT *
, ROW_NUMBER() OVER (
ORDER BY columnorder
) ROWNUM
FROM @tble
WHERE columnorder IS NOT NULL
)
UPDATE A
SET columnorder = rownum
FROM @tble A
INNER JOIN CTE
ON A.Columnid = CTE.Columnid;
--AFTER UPDATE
SELECT *
FROM @tble;
答案 1 :(得分:0)
UPDATE CustomerLocalizationColumns
SET ColumnOrder = new_num
FROM CustomerLocalizationColumns
LEFT OUTER JOIN
(SELECT ID, ROW_NUMBER() OVER (ORDER BY ID) as new_num
FROM CustomerLocalizationColumns
WHERE [Enabled?]=1
) as enabledrows
ON CustomerLocalizationColumns.ID=enabledrows.ID
我用它来测试:
CREATE TABLE #CustomerLocalizationColumns
(ID INT, ColumnOrder INT, [Enabled?] INT);
With Data as
(SELECT 50 as ID, 1 as ColumnOrder, 1 as [Enabled?] UNION ALL
SELECT 51,0,0 UNION ALL
SELECT 52,2,1 UNION ALL
SELECT 53,0,0 UNION ALL
SELECT 54,4,1 UNION ALL
SELECT 55,5,1 UNION ALL
SELECT 56,0,0 UNION ALL
SELECT 57,0,0
)
INSERT INTO #CustomerLocalizationColumns
SELECT * FROM Data;
-- because I used 0 instead of NULLs in a hurry (and it lines up nicely!) :)
UPDATE #CustomerLocalizationColumns
SET ColumnOrder=NULL
WHERE [Enabled?] = 0
UPDATE #CustomerLocalizationColumns
SET ColumnOrder = test
FROM #CustomerLocalizationColumns
RIGHT OUTER JOIN (SELECT ID, ROW_NUMBER() OVER (ORDER BY ID) as test FROM #CustomerLocalizationColumns
WHERE [Enabled?]=1) as enabledrows ON #CustomerLocalizationColumns.ID=enabledrows.ID
SELECT * FROM #CustomerLocalizationColumns;
DROP TABLE #CustomerLocalizationColumns