我有一张带有字段的表格。每个字段属于一个组,每个字段都有一个Field_order。 例如:
groupname | fieldname | fieldorder
-----------------------------------
group 1 | field1 | 1
group 1 | field2 | 2
group 1 | field3 | 3
group 2 | field4 | 1
group 3 | field5 | 1
group 3 | field6 | 2
如果我将field3
group 1
设置为fieldorder = 2
,则field2
需要自动设置为fieldorder = 3
。
如果我将field1
移至fieldorder 3
,field3
将fieldorder = 2
且field2
需要fieldorder = 1
,则同样如此。
我想用foreach循环来做这件事,但我似乎无法找到它。
答案 0 :(得分:0)
我会稍微改变一下,主要是因为我不喜欢触发器,并且使用存储过程。我假设(GroupName
,FieldName
)在您的表格中是唯一的,并且是主键,否则需要稍微调整以下内容。
所以你的第一个程序是创建新记录:
CREATE PROCEDURE dbo.InsertT
@GroupName VARCHAR(50),
@FieldName VARCHAR(50)
AS
BEGIN
INSERT dbo.T (GroupName, FieldName, FieldOrder)
SELECT @GroupName,
@Field,
ISNULL(MAX(FieldOrder), 0) + 1
FROM dbo.T
WHERE GroupName = @GroupName;
END
然后更新FieldOrder的过程:
CREATE PROCEDURE dbo.ChangeFieldOrder
@GroupName VARCHAR(50),
@FieldName VARCHAR(50),
@FieldOrder INT
AS
BEGIN
UPDATE T
SET FieldOrder = CASE WHEN t.FieldName = @FieldName THEN @FieldOrder
ELSE t.FieldOrder + c.Motion
END
FROM ( SELECT *,
Motion = SIGN(FieldOrder - @FieldOrder),
LowerVal = CASE WHEN @FieldOrder > FieldOrder THEN FieldOrder ELSE @FieldOrder END,
UpperVal = CASE WHEN @FieldOrder > FieldOrder THEN @FieldOrder ELSE FieldOrder END
FROM dbo.T
WHERE GroupName = @GroupName
AND FieldName = @FieldName
) AS c
INNER JOIN dbo.T AS T
ON T.GroupName = c.GroupName
WHERE Motion != 0
AND t.FieldOrder BETWEEN c.LowerVal AND c.UpperVal;
END
然后您可以按如下方式运行以下各项:
EXECUTE dbo.InsertT 'Group 1', 'Field1';
EXECUTE dbo.InsertT 'Group 1', 'Field2';
EXECUTE dbo.InsertT 'Group 1', 'Field3';
EXECUTE dbo.ChangeFieldOrder 'Group 1', 'Field3', 2;
更新的前提仅仅是受影响的行将是旧字段和新字段顺序之间的行。子查询c
具有以下表达式,基本上决定了更新:
Motion = SIGN(FieldOrder - @FieldOrder),
LowerVal = CASE WHEN @FieldOrder > FieldOrder THEN FieldOrder ELSE @FieldOrder END,
UpperVal = CASE WHEN @FieldOrder > FieldOrder THEN @FieldOrder ELSE FieldOrder END
LowerVal
和UpperVal
只是计算更新的上限和下限,以便在WHERE
子句中使用以下内容:
t.FieldOrder BETWEEN c.LowerVal AND c.UpperVal;
运动,只是计算出其他值需要移动的方式,即如果你减少一个值的顺序,那么它之间的所有旧值和它的新值都需要增加1在序列中创建空格,如果你增加一个记录的顺序,那么你需要将它上面的所有东西都移动,直到新的值减去一个为它腾出空间。
使用存储过程来管理这个问题的另一个原因是它强制更新是单独完成的,保持规则简单,即如果有人刚刚运行,你将如何管理触发器:
UPDATE dbo.T
SET fieldOrder = 1;
新订单会是什么?如果需要,此方法还允许使用唯一约束,以确保FieldOrder在每个组中都是唯一的:
ALTER TABLE dbo.T ADD CONSTRAINT UQ_T__GroupName_FieldOrder UNIQUE (GroupName, FieldOrder);
答案 1 :(得分:0)
将fieldorder更改为小数(9,1)
如果你想要它去最后一次 set fieldorder = 4 where fieldname ='field2'
如果你想要它先去 set fieldorder = 0 where fieldname ='field2'
如果你想要它第二个 set fieldorder = 1.5其中fieldname ='field3'
update table
set table.fieldorder = updateorder.newOrder
from table
join (select fieldname, row_number() over (order by fieldorder) as newOrder
from table
where groupname = 'group 1') as updateorder
on updateOrder.fieldname = table.fieldname
and table.fieldorder <> updateorder.newOrder
and table.groupname = 'group 1'
在评论OP发布时无法更改字段类型
你可以用整数
更新表设置fieldorder = fieldorder * 2
然后是上面发布的答案,但你使用的是奇数,而不是.5
你想把它全部包装在一个交易中
我知道不漂亮,但问题不是很好