SQL - 循环遍历列,一旦找到空,更新它
我启动了类似的线程,但由于问题更困难,我想从头开始。
想象一下,有10个库存插槽(在DB中它们是用户行中的列)。当用户选择一个项目时,它应该被放置到第一个空列(它被更新)。但是如果我想要仍然灵活的设计,如何在查询中循环查找(除了IF EXISTS)? 由于项目的顺序很重要(每个项目属于特定的槽),所以不能很好地解决问题。如果用户有第一个和第三个插槽已满,下一个挑选的项目应该进入第二个。 现在希望它更清楚,谢谢!SQL - 循环遍历列,一旦找到空,更新它
为什么不只是有另一个表的库存项目?所以你有一个库存表和inventory_item表,就像这样:
----------
inventory
----------
id int
description varchar(100)
---------------
inventory_item
---------------
id int
inventory_id int (foreign key to inventory table)
sequence_num int (indicates which "slot" the data represents)
所以,现在,你可以在库存有行,然后你可以插入行到inventory_item当你的价值观。因此,如果您有3个值,则只需将3行插入inventory_item。至于什么“插槽”他们进去,sequence_num字段会告诉你。
编辑
要查询现有inventory_items找出下一个可用的插槽数,你可以这样做:
SELECT coalesce(MAX(sequence_num),0) + 1 next_sequence_num
FROM inventory_item
WHERE inventory_id = xxx
如果没有inventory_items存在,这将返回1.如果现有的项目都存在,它会给你下一个“插槽编号”使用(我称之为sequence_number,但同样的事情)。
你用这种方式破坏1NF,这就是你遇到这个问题的原因。
我认为它可以通过在行中的项目来解决。您可以将每一行放入另一个表中,并使用该表中的另一列指定顺序。
我不确定Inventoryslot在你的例子中涉及什么,但是表格应该看起来与此类似。
InventorySlots(InventorySlotId, RelatedFieldID, OrderNumber, ItemID)
你可以把RelatedFieldID和订单号码具有唯一索引,以防止在同一位置上有两个项目。
我会说你可能仍然使用行。只需添加一列“SlotOrder”或其他。然后,你的查询会是这样(警告:伪码 - 没有测试所有):
declare @Slot int
set @Slot = 1
if @Slot <= (Select Max(SlotOrder) from Inventory)
select @Slot = (Select Max(SlotOrder) + 1 from Inventory)
if @Slot >= 10
Insert Into Inventory(Item, SlotOrder)
Values(@Item, @Slot)
Else -- Tell the user the inventory is full
在一个表中的项目有没有特定的顺序,那么孤单顺序不能用来区分不同的插槽。
但是,这可能并不重要,因为您想查找第一个空插槽。没有任何对插槽的排序,这相当于找到任何空插槽。如果添加slotNr
领域的插槽表(从1开始编号用户的插槽
update slots s
set slotValue=newValue
WHERE s.userID = <UserID> AND slotValue IS NULL AND NOT EXISTS
(SELECT 1 FROM slots s2 WHERE s2.userid=s.userid AND s2.slotValue IS NULL AND s2.slotID<s.slotID)
..:
这是这样做10),那么查询将如下所示:
update slots s
set slotValue=newValue
WHERE s.userID = <UserID> AND slotValue IS NULL AND NOT EXISTS
(SELECT 1 FROM slots s2 WHERE s2.userid=s.userid AND s2.slotValue IS NULL AND s2.slotNr<s.slotNr)
当您执行查询时,数据库将返回受影响的行数。如果所有插槽都在使用中,则返回值将为0,否则为1,如果插槽已更新。
你可以找到多少空闲插槽有写
select count(*) FROM slots
WHERE slots.userID=<userID> AND slots.slotValue IS NULL
虽然即使这个返回空闲插槽,也不能保证,当你真正到了改变的空插槽值,即有任何空闲插槽 - 为该用户添加插槽值的其他操作可能会占用最后一个可用插槽。因此,最好使用ROW_COUNT变量来确定插槽是否被修改。
如果顺序很重要,请将“插槽”列添加到行中以表示其顺序。 – 2010-07-26 14:11:34
听听@dcp和@Chris在下面说什么。您的模式已经融合,您应该在继续之前解决这个问题。 – 2010-07-26 14:17:21