当存储范围
当你想从一组可能重叠 范围删除范围,需要多个语句。
To be printed |-------|
Actually printed |---|
例如,当用户打印范围的“中间”块,留下 开始和结束区块未打印的,你不能更新与 一个SQL语句中的数据。您必须更新原始行,并且 会插入一个新行,或者您必须删除原始行并插入两行 行。
事实上,无法预测是否需要更新语句,多个更新语句或更新和插入语句的组合是红色标记。
在任何情况下,每个用户都必须在该表上选择,插入,更新和删除 特权。您是否可以忍受这是依赖于应用程序的 ,但这是另一个红旗。
这些红旗并不意味着“永远不要这样做”。他们做意思是停下来,坐在你的手上,并说,“等一下......”
当存储个别事实
这往往简单存储个别事实,而不是他们的 范围。有几种不同的方法:a)仅存储需要打印的 ; b)存储需要打印的内容和 已打印的内容。
如果您只存储需要打印的内容,记录什么有已被 打印只需要选择和删除权限。
如果使用两个表 - 存储在一个“要打印”,并在其他“已经 印” - 用户需要只选择特权“是 印有”(选择,如果插入特权用户可以添加要打印的东西 ),并在“已打印”上选择并插入权限。
例如,如果您只存储需要打印的内容,请使用此表启动 。
-- Does *not* assume that to_print is unique.
create table to_be_printed (
file_no varchar(10) not null,
to_print integer not null
check (to_print > 0),
primary key (file_no, to_print)
);
create index on to_be_printed (to_print);
insert into to_be_printed values
('Abc', 1), ('Abc', 2), ('Abc', 3), ('Abc', 4), ('Abc', 5),
('Abc', 6), ('Abc', 7), ('Abc', 8), ('Abc', 9), ('Abc', 10),
('Abc', 11), ('Abc', 12), ('Abc', 13), ('Abc', 14), ('Abc', 15),
('Abc', 16), ('Abc', 17), ('Abc', 18), ('Abc', 19), ('Abc', 20),
('Abc', 21), ('Abc', 22), ('Abc', 23), ('Abc', 24), ('Abc', 25),
('Abc', 26), ('Abc', 27), ('Abc', 28), ('Abc', 29), ('Abc', 30),
('Abc', 31), ('Abc', 32), ('Abc', 33), ('Abc', 34), ('Abc', 35),
('Abc', 36), ('Abc', 37), ('Abc', 38), ('Abc', 39), ('Abc', 40),
('Abc', 41), ('Abc', 42), ('Abc', 43), ('Abc', 44), ('Abc', 45),
('Abc', 46), ('Abc', 47), ('Abc', 48), ('Abc', 49), ('Abc', 50),
('DGM', 51), ('DGM', 52), ('DGM', 53), ('DGM', 54), ('DGM', 55),
('DGM', 56), ('DGM', 57), ('DGM', 58), ('DGM', 59), ('DGM', 60);
为了指示用户已经通过31 40印刷号码,从该表只是删除 那些行。
delete from to_be_printed
where to_print between 31 and 40;
友好的呈现
存储单个事实并不完全解决问题。您 可能仍然需要向用户提供数据作为每个 文件编号的范围。这类问题的搜索条件是“sql间隙和 岛屿”。
select file_no, min(to_print) as range_start, max(to_print) as range_end
from
(select file_no
, to_print
, to_print - row_number() over
(partition by file_no order by to_print) as grouping
from to_be_printed
) as d
group by file_no, grouping
order by file_no, range_start;
file_no range_start range_end
--
Abc 1 30
Abc 41 50
DGM 51 60
只要是明确的:如果用户输入A..B,并没有为范围X..Y的记录(用X <=A & Y> = B),要更换这个纪录一个用于范围X..A-1(如果X <= A-1)和B + 1..Y(如果Y> = B + 1)? – 2014-09-27 12:55:47
对不起!我已编辑输出 – 2014-09-27 12:59:40
您是否考虑存储用户已完成打印的范围? – 2014-09-27 13:23:07