sql server:根据计数器和另一个列值生成主键
|
我正在创建一个客户表,其父表是公司的.
varchar(9)主键的其余部分应为零填充计数器,通过该公司内的客户数量递增. 例如. company = MSFT,这是MSFT记录的第一个插入:PK应为MSFT00001 我开始使用一个而不是触发器和一个我从其他stackoverflow响应创建的udf. ALTER FUNCTION [dbo].[GetNextID]
(
@in varchar(9)
)
RETURNS varchar(9) AS
BEGIN
DECLARE @prefix varchar(9);
DECLARE @res varchar(9);
DECLARE @pad varchar(9);
DECLARE @num int;
DECLARE @start int;
if LEN(@in)<9
begin
set @in = Left(@in + replicate('0',9),9)
end
SET @start = PATINDEX('%[0-9]%',@in);
SET @prefix = LEFT(@in,@start - 1 );
declare @tmp int;
set @tmp = len(@in)
declare @tmpvarchar varchar(9);
set @tmpvarchar = RIGHT( @in,LEN(@in) - @start + 1 )
SET @num = CAST( RIGHT( @in,LEN(@in) - @start + 1 ) AS int ) + 1
SET @pad = REPLICATE( '0',9 - LEN(@prefix) - CEILING(LOG(@num)/LOG(10)) );
SET @res = @prefix + @pad + CAST( @num AS varchar);
RETURN @res
END
如何编写my而不是触发器来插入值并增加此主键.或者我应该放弃它并开始一个割草业务? 抱歉,没有它,tmpvarchar变量SQL服务器给了我奇怪的结果. 解决方法虽然我同意反对者的观点,但“接受不能改变的原则”倾向于降低整体压力水平,恕我直言.尝试以下方法.缺点 >仅限单排插入.您不会对新客户表进行任何批量插入,因为每次要插入行时都需要执行存储过程. 但是,从好的方面来说,这种方法并没有任何与之相关的竞争条件,并且真正冒犯我的感情并不是太严重的黑客攻击.所以… 首先,从密钥生成表开始.它将包含每个公司的1行,包含您的公司标识符和每次执行插入时我们将要碰撞的整数计数器. create table dbo.CustomerNumberGenerator ( company varchar(8) not null,curr_value int not null default(1),constraint CustomerNumberGenerator_PK primary key clustered ( company ),) 其次,你需要一个像这样的存储过程(事实上,你可能希望将这个逻辑集成到负责插入客户记录的存储过程中.稍后详细介绍).该存储过程接受公司标识符(例如“MSFT”)作为其唯一参数.此存储过程执行以下操作: >将公司ID放入规范形式(例如,大写和修剪前导/尾随空格). 干得好: create procedure dbo.GetNewCustomerNumber
@company varchar(8)
as
set nocount on
set ansi_nulls on
set concat_null_yields_null on
set xact_abort on
declare
@customer_number varchar(32)
--
-- put the supplied key in canonical form
--
set @company = ltrim(rtrim(upper(@company)))
--
-- if the name isn't already defined in the table,define it.
--
insert dbo.CustomerNumberGenerator ( company )
select id = @company
where not exists ( select *
from dbo.CustomerNumberGenerator
where company = @company
)
--
-- now,an interlocked update to get the current value and increment the table
--
update CustomerNumberGenerator
set @customer_number = company + right( '00000000' + convert(varchar,curr_value),8 ),curr_value = curr_value + 1
where company = @company
--
-- return the new unique value to the caller
--
select customer_number = @customer_number
return 0
go
您可能希望将其集成到将行插入customer表的存储过程中的原因是它将它们全部组合到一个事务中;如果没有这个,当插入失败时,您的客户编号可能会/将会出现间隙. (编辑:清远站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

