插入DB时取得主键冲突问题
问题是这样的,我设置了一个数值型字段为主键,新记录主键是旧记录最大主键加1
SQL这么写会报错:
"insert into [log] (id,userId) values((select max(id)+1 from [log]), ' " + loginUser + " ') "
后来就改成先在C#中取得主键并加1,然后再插入数据库
执行 id = (select max(id)+1 from [log])
然后 "insert into [log] (id,userId) values( " + id + ", ' " + loginUser + " ') "
这样在多个页面同时打开时,可能造成主键重复
现在改写SQL为下面,正常了:
"insert into [log] (id,userId) select max(id)+1, ' " + loginUser + " ' from [log] "
请问除了上面的办法还有什么更好的办法没有?
不使用自动增长的字段。
------解决方案--------------------将表、表当前ID值放入一张表(比如A)中,再使用存储过程插入,插入之前先去查A表,插入成功后再把A表中“值”字段加1。
表的内容如下(示例):
表名 主键字段名 值
table1 table1_ID 1
table2 table2_ID 49
table3 table3_ID 0
------解决方案--------------------不过,使用事务是一种性能极其低下的做法。如果可能,不要将主键设计为流水号。反过来说,不要将流水号假想为数据库主键。
数据库主键应该使用一种与任何业务概念无关的方法来设计。例如GUID类型的值,在SQL Server中是uniqueidentifier。
而流水号有逻辑意义。其实流水号完全可以在记录已经产生之后再产生,也可以随时修改,例如前边某个流水号被删除的时候需要重新编排流水号。很多时候也不产生流水号,而是用排序字段和序号到记录集合里从往后遍历。
总之把流水当作数据库主键,是非技术人员制造的技术困难。