我有MSSQL表有列,作为具有特定名称的用户的项目的存储。每个用户在表项中都有一个记录如下:
Name(string) 1(string) 2(string) 3(string) 4(string) 5(string)
插入数据时,我需要逐个使用列(“数据包”)。含义如果“1”包含数据,请使用“2”列。如果“1”为空,请使用“1”。如果只有“3”为空,请使用“3”/ 换句话说,我总是需要选择最低的空列来写入数据。如果这5个都不为空,那么根本不要写数据。 任何人都可以帮我解决这个问题吗?谢谢
答案 0 :(得分:1)
在SQL中对此进行建模的正确方法是:
CREATE TABLE Tab (
Name varchar(20) not null, --20? Who knows, not specced in question
Idx int not null,
Value varchar(20) not null, --20? Who knows, not specced in question
constraint PK_Tab PRIMARY KEY (Name,Idx),
constraint CK_Tab_Indexes CHECK (Idx between 1 and 5)
)
然后您可以将插入内容写为:
INSERT INTO Tab (Name,Idx,Value)
SELECT @Name,COALESCE((select MAX(Idx)+1 from Tab where Name=@Name),1),@Value
其中@Name
和@Value
是要插入的提供值。如果表中已有5个特定名称的项目,您将收到检查约束错误,插入将失败。
这也使得查询特定值成为可能,而不必搜索5个不同的列,这意味着将来更容易扩展到更多项目(仅通过更改检查约束)
我的印象是这只是插入。如果正在发生删除,并且您希望重用项目,则插入查询将为:
;WITH Nums(n) as (select 1 union all select 2 union all select 3 union all select 4 union all select 5)
INSERT INTO Tab (Name,Idx,Value)
SELECT @Name,(select MIN(n) from Nums where not exists (select * from Tab where Name=@Name and Idx = n)),@Value
一旦你在5个项目中获胜,它将因为非空约束而失败。如果您的数据库中已有数字表,可能会更简单,但我认为不在上面。