条件“序列的下一个值”

时间:2013-09-08 11:55:09

标签: sql-server

情形:

Sql Server 2012表名为“Test”的表有两个字段。 “CounterNo”和“Value”都是整数。

定义了4个名为sq1,sq2,sq3,sq4

的序列对象

我想在插页上执行这些操作:

  • 如果CounterNo = 1 ,则值= sq1的下一个值
  • 如果CounterNo = 2 ,则值= sq2的下一个值
  • 如果CounterNo = 3 ,则值= sq3的下一个值

我认为,创建自定义函数会将其指定为Value字段的默认值。但是,当我尝试自定义函数不支持“序列对象的下一个值”

另一种方法是使用触发器。该表已经触发了。

使用存储过程进行插入是最好的方法。但是EntityFramework 5 Code-First不支持它。

你能告诉我一个实现这个目标的方法吗?

(如果你告诉我怎样才能使用自定义函数you can also post it here。这是我的另一个问题。)

更新 实际上,该表中有23个字段,并且还设置了主键,并且我在软件方面使用“计数器表”生成此计数器值。在客户端生成计数器值并不好。

我使用4个序列对象作为计数器,因为它们代表不同类型的记录。

如果我同时在同一记录上使用4个计数器,则所有计数器都会生成下一个值。我只想要相关的计数器生成它的下一个值而其他值保持不变。

3 个答案:

答案 0 :(得分:1)

如果我完全理解您的使用案例,我并不感到害羞,但以下示例可能会说明您的需求。

Create Table Vouchers (
    Id              uniqueidentifier    Not Null Default NewId()
    , Discriminator varchar(100)        Not Null
    , VoucherNumber int                 Null
    -- ...
    , MoreData      nvarchar(100)       Null
);
go
Create Sequence InvoiceSequence AS int Start With 1 Increment By 1;
Create Sequence OrderSequence AS int Start With 1 Increment By 1;
go
Create Trigger TR_Voucher_Insert_VoucherNumer On Vouchers After Insert As 
   If Exists (Select 1 From inserted Where Discriminator = 'Invoice')
     Update v
        Set VoucherNumber = Next Value For InvoiceSequence
        From Vouchers v Inner Join inserted i On (v.Id = i.Id)
        Where i.Discriminator = 'Invoice';
   If Exists (Select 1 From inserted Where Discriminator = 'Order')
     Update v
        Set VoucherNumber = Next Value For OrderSequence
        From Vouchers v Inner Join inserted i On (v.Id = i.Id)
        Where i.Discriminator = 'Order';
go

Insert Into Vouchers (Discriminator, MoreData) 
Values ('Invoice', 'Much')
    ,  ('Invoice', 'More')
    ,  ('Order', 'Data')
    ,  ('Invoice', 'And')
    ,  ('Order', 'Again')
;
go

Select * From Vouchers;

现在,Invoice-和Order-Numbers将独立递增。因为你可以在同一个表上有多个插入触发器,这应该不是问题。

答案 1 :(得分:0)

我认为你是以错误的方式思考这个问题。您有3个值,这些值由另一列确定。切换它,创建3列并删除Counter列。

如果您的表格包含value1value2value3,那么该值所在的列会隐含Counter值。在这三列上创建一个唯一索引,并为主键添加一个标识列,然后对其进行排序;您可以轻松地在存储过程中完成所有操作。

答案 2 :(得分:0)

如果您有四种不同类型的记录,请使用四个不同的表格,每个表格中都有一个单独的identity列。

如果您需要一起查看所有数据,请使用视图将它们组合在一起:

create v_AllTypes as
    select * from type1 union all
    select * from type2 union all
    select * from type3 union all
    select * from type4;

或者,在输出上计算序列号:

select t.*,
       row_number() over (partition by CounterNo order by t.id) as TypeSeqNum
from AllTypes t;

如果需要对四个标识列进行条件更新,那么您的数据模型似乎有些不妥。