![]() |
1
50
SQL Server 2012已引入
创建它们很容易:
插入前使用它们的示例:
有关如何使用序列的详细信息,请参见我的博客: http://sqljunkieshare.com/2011/12/11/sequences-in-sql-server-2012-implementingmanaging-performance/ |
![]() |
2
14
作为
sqljunkieshare
正确地说,从sql server 2012开始,有一个内置的
原来的问题并不清楚,但我认为序列的要求是:
我想对原问题中的陈述进行评论:
好吧,我们在这里无能为力。DB是序号的提供者,DB处理所有这些无法处理的并发问题。我认为除了向数据库询问序列的下一个值之外别无选择。必须有一个 原子的 操作“给我序列的下一个值”,只有db可以提供 原子的 操作。没有客户端代码可以保证只有他在处理序列。
要回答标题“您将如何实现序列”中的问题,我们使用的是2008,它没有
对于我需要的每个序列,我创建一个单独的helper表,其中只有一个
可以指定起始值和增量。 然后创建一个存储过程,返回序列的下一个值。 过程将启动事务,将一行插入到帮助表中,记住生成的标识值并回滚事务。因此helper表始终为空。
关于程序的注释很少。
首先,如何将行插入到只有一个标识列的表中并不明显。答案是
然后,如果在另一个事务中调用了过程,我希望它能够正常工作。简单的
这就是我如何使用该过程(例如,在创建新合同的其他大型过程中):
如果你需要一次生成一个序列值,一切都很好。在合同的情况下,每个合同都是单独创建的,因此这种方法非常有效。我可以确定所有的合同都有唯一的合同号。
注:只是为了防止可能的问题。这些合同编号是对我的合同表所具有的代理标识密钥的补充。代理项密钥是用于引用完整性的内部密钥。生成的合同编号是打印在合同上的人性化编号。此外,同一个合同表包含最终合同和建议书,它们可以成为合同,也可以永远作为建议书保留。提案和合同都有非常相似的数据,这就是为什么它们被放在同一个表中的原因。只需在一行中更改标志,提案就可以成为合同。提案用一个单独的数字序列编号,我有第二张表
不过,最近我遇到了一个问题。 我需要批量生成序列值,而不是逐个生成。
我需要一个程序,将处理在一个给定的季度内一次性收到的所有付款。这种处理的结果可能是大约20000个事务,我想在
从本质上讲,我使用了相同的方法,但没有什么特殊之处。
首先,没有直接的方法在一个只有一行的表中插入多行
helper表如下所示:
程序是这样的:
这就是它的使用方式(在一些计算事务的大型存储过程中):
这里没有什么需要解释的。
我需要将给定的行数插入到
我必须将大容量插入的结果保存在某个地方,并以某种方式传递给调用方。在存储过程之外传递表的一种方法是使用临时表。我不能在这里使用表值参数,因为它是只读的,很不幸。此外,我不能直接将生成的序列值插入到临时表中。
所以,我使用表变量
而且,它可以使用
我犯了个错误
但是,我需要
在所有这些之后,切换到最新版本的sql server会有多好
|
![]() |
3
5
An Identity column 大致类似于一个序列。 |
![]() |
4
5
您可以使用普通的旧表并将它们用作序列。这意味着您的插入内容将始终是:
但不要这样做。锁会坏的… 我从SQL Server开始,对我来说,Oracle“序列”方案看起来像黑客攻击。我猜你是从另一个方向来的,对你来说,scope_identity()看起来像个黑客。 克服它。在罗马的时候,要像罗马人一样。 |
![]() |
5
4
我用来解决这个问题的方法是一个存储所有序列的表'sequences'和一个'nextval'存储过程。 SQL表:
这个 pk_序列 只是用来确保永远不会有同名的序列。 SQL存储过程:
插入一些序列:
最后得到序列的下一个值,
一些C代码从序列表中获取下一个值,
|
|
6
3
在SQL Server 2012中,您可以简单地使用
在2005年和2008年,您可以使用公共表表达式获得序列号的任意列表。 下面是一个例子(注意maxrecursion选项很重要):
|
![]() |
7
3
由Oracle实现的序列需要在插入之前调用数据库。 SQL Server实现的标识需要在插入之后调用数据库。 一个并不比另一个更老套。净效果是相同的-对数据存储区的依赖/依赖性,以提供唯一的人工密钥值,并且(在大多数情况下)两个调用到存储区。 我假设您的关系模型是基于人工键的,在这种情况下,我将提供以下观察: 我们永远不应该试图给人工密钥注入意义,它们的唯一目的应该是链接相关记录。 你对订购数据有什么要求?它是否可以在视图(演示文稿)中处理,或者是数据必须保留的真实属性吗? |
|
8
2
创建一个带有标识符的stage表。 在加载stage表之前,截断标识符并重新设置其种子,使其从1开始。 把你的桌子搬上。现在每一行都有一个从1到n的唯一值。 创建一个保存序列号的表。这可以是几行,每个序列都有一行。 从您创建的序列表中查找序列号。 通过将stage表中的行数添加到序列号来更新sequence号。 通过添加查找到的序列号来更新阶段表标识符。这是一个简单的单步过程。 或 加载目标表,在ETL中加载时将序列号添加到标识符。这可以利用大容量加载程序并允许其他转换。 |
![]() |
9
2
考虑下面的片段。
|
![]() |
10
2
作为 sqljunkiesshare states ,序列已添加到SQL Server 2012。下面是如何在gui中实现的。这相当于:
笔记:
|
![]() |
11
0
我完全同意,去年做了一个项目。 我刚刚创建了一个表,其中包含序列名称、当前值和增量金额。 然后我创建了两个过程来添加和删除它们。和两个函数获取下一个,获取当前值。 |
![]() |
12
0
如果要插入带有顺序键的数据,但不希望再次查询数据库以获取刚刚插入的键,我认为您只有两个选择:
如果我在做客户端密钥生成,我 爱 吉兹。我觉得他们很漂亮。
那条线应该在某个地方的跑车引擎盖上。 |
![]() |
13
0
如果使用的是SQL Server 2005,则可以选择使用行号 |
![]() |
14
0
标识列的另一个问题是,如果有多个表的序号需要唯一,则标识列不起作用。就像Corey Trager提到的,滚动自己的序列实现可能会带来一些锁定问题。 最直接的等价解决方案似乎是创建一个sql server表,其中包含一列标识,该标识代替了单独类型的“sequence”对象。例如,如果在Oracle中,一个序列中有两个表,例如dogs<--sequence object--gt;cats,则在SQL Server中,您将创建三个数据库对象,所有表都像dogs<--pets with identity column--gt;cats。您可以在pets表中插入一行,以获取通常使用nextval的序列号,然后在从用户那里获得实际类型的宠物后,按照通常的方式插入dogs或cats表。任何额外的公共列都可以从dogs/cats表移到pets supertype表中,结果是:1)每个序列号有一行;2)获取序列号时无法填充的任何列都需要有默认值;3)获取所有列都需要连接。 |
![]() |
15
0
通过sql可以使用这种策略;
并读取此sql的唯一下一个值
|
![]() |
16
0
交易安全! 对于2012之前的sqlserver版本…(谢谢马特G。) 讨论中缺少的一点是交易安全。如果你从一个序列中得到一个数字,那么这个数字必须是唯一的,并且没有其他应用程序或代码能够得到这个数字。在我的例子中,我们经常从序列中提取唯一的数字,但是实际的事务可能会占用相当长的时间,所以我们不希望任何其他人在提交事务之前得到相同的数字。 我们需要模拟Oracle序列的行为 ,其中一个号码在提取时被保留。 我的解决方案是使用xp_cmdshell在数据库上获取单独的会话/事务,以便我们可以立即更新整个数据库的序列,甚至在事务完成之前。
解决方案需要一个表来保存使用的序列值,并且需要一个过程 创建第二个自主事务 以确保并发会话不会陷入混乱。您可以拥有任意数量的唯一序列,它们是按名称引用的。修改下面的示例代码以省略序列历史表上的请求用户和日期戳(用于审核),但我认为对于该示例而言,不太复杂。
现在,为了让这个过程正常工作,你需要启用一个程序集,有很多关于如何做的好的描述,这里是我在尝试工作时所做的个人笔记。基本思想是,您需要在SQLServer Surt中打开XPyCMDHELL是一个配置,并且需要将用户帐户设置为XPyCMDS壳命令将运行的帐户,它将访问数据库插入序列号并提交它。
|
![]() |
Community wiki · SQL语法新手 1 年前 |
|
KateMak · 是否将多行中的多列与唯一id组合? 1 年前 |
![]() |
Karuna · SQL中列内的筛选器[重复] 1 年前 |
![]() |
Irvan Affandy · 为另一个选择选择声明的键 1 年前 |
![]() |
Community wiki · 这个MySQL语句出了什么问题? 1 年前 |
![]() |
Community wiki · 优化从同一表中提取的多列的查询 1 年前 |