代码之家  ›  专栏  ›  技术社区  ›  Joe R.

类似于序列的int列

  •  1
  • Joe R.  · 技术社区  · 14 年前

    我有一个应用程序,根据添加或更新的交易类型,票据编号可能会增加,也可能不会增加。我不能对票据编号使用串行数据类型,因为不管交易类型如何,它都会递增,所以我将票据编号定义为in t。因此,在多用户环境中,如果用户A正在添加或更新交易,而用户B也在这样做,我将测试tran类型,如果需要下一个票据编号,那么

    LET ticket = (SELECT MAX(ticket) [WITH ADDLOCK or UPDLOCK?] FROM transactions) + 1
    

    但是,这必须在执行行或开始麻烦时进行。您能想出一个更好的方法来实现这一点吗:Informix、Oracle、MySQL、SQL Server、4JS/Genero或其他RDBMS?这是一个主要因素,它将决定我要在哪个RDBMS中重新编写我的应用程序。

    3 回复  |  直到 9 年前
        1
  •  2
  •   Jonathan Leffler    14 年前

    使用Informix DBMS,串行列在插入后不会更改;实际上,您根本无法更新串行值。您可以插入一个值为0的新值(在这种情况下会生成一个新值),也可以插入其他值。如果另一个值已经存在,并且有一个唯一约束,那么它将失败;如果它不存在,或者序列列上没有唯一约束,那么它将成功。如果插入的值大于先前插入的最大值,则要插入的下一个数字将再次变大。如果插入的数字较小或为负数,则对下一个数字没有影响。

    所以,您可以在不更改值的情况下进行更新—没问题。如果需要更改数字,则必须进行删除和插入(或插入和删除),其中插入的数字为零。如果您喜欢一致性,并且使用事务,则可以始终删除,然后(重新)插入具有相同数字或零的行以触发新的数字。这假设您有一种运行SQL的编程语言;我认为您不能调整ISQL并自动执行它。

    所以,在这一点上,我看不到Informix的问题。

    使用适当版本的ID(支持的任何内容),您也可以使用sequence来控制插入的值。这是基于Oracle语法和概念的;DB2也支持这一点。其他DBMS有其他同等(但不同)的机制来处理自动生成的数字。

        2
  •  1
  •   GSerg    14 年前

    从你的标签上很难看出你在使用什么数据库。

    对于SQL Server(因为它已列出),我建议

    ticket_num = (SELECT MAX(ticket_number) FROM transactions with (updlock)) + 1
    
        3
  •  1
  •   a_horse_with_no_name    9 年前

    这就是为大多数数据库创建的序列和支持的序列(MySQL是唯一一个没有序列的数据库-但是对于Informix不完全确定)

    任何依赖于 选择最大值(ID) 反模式要么在多用户环境中非常缓慢,要么在多用户环境中无法正常工作。

    如果您也需要支持MySQL,我建议在每个数据库中使用“本机”“自动增量”类型(postgresql为serial,mysql为auto-increment,sql server为identity,oracle为sequence+trigger等),让驱动程序返回生成的i d值。

    在JDBC中有一个getGeneratedKeys()方法,我确信其他接口也有类似的东西。