这可能是1x中的2x问题。抱歉,但是去了:
问题
每次用户将一些数据上传到SQL Server时,我都会创建一个唯一的批处理ID。目前,我是通过查看“身份规范”的最后一个值并为其添加+1来实现的。
出现问题,就像您可能已经猜到的那样,如果多个用户同时输入数据,他们俩将获得相同的批次ID ...
可能的解决方案
为了减轻这个问题,我想出了这种方法来生成3个字母+随机数;和(最后一个ID值+ 1):
DECLARE @tmp CHAR(3) = CHAR(CAST(RAND()*26 AS int)+65) + CHAR(CAST(RAND()*26 AS int)+65) + CHAR(CAST(RAND()*26 AS int)+65);
SELECT @tmp;
select cast(RAND()*9999 as int)
(1)我不确定如何将其连接为一行字符串。
(2)另一个问题是,有没有办法100%保证每个用户每次提交请求时都获得唯一的批次ID,而不论有多少人同时执行请求? / p>
非常感谢您对此的投入。
答案 0 :(得分:2)
您需要一个带有Bigint Identity列的“上传”表作为BatchID,然后为每次用户上传添加新行。
服务器将保持正确的值并防止冲突。
答案 1 :(得分:2)
我将为此使用内置函数:
select newid()
> 240CA878-135E-4176-AE57-0FA83FF74037
答案 2 :(得分:1)
对于第一个问题,您可以为随机数创建一个变量,将其作为char(4)并将其简单地连接为2,或者将其创建为int,然后在连接时将其转换为VARCHAR。 所有串联在一起的字符串都必须是字符串。
DECLARE @tmp CHAR(3) = CHAR(CAST(RAND()*26 AS int)+65) + CHAR(CAST(RAND()*26 AS int)+65) + CHAR(CAST(RAND()*26 AS int)+65);
SELECT @tmp;
DECLARE @randNum VARCHAR(4) = CAST(RAND()*9999 AS INT)
-- OR DECLARE @randNum INT = CAST(Rand()*9999) AS INT)
SELECT @randNum
DECLARE @batchID VARCHAR(MAX) = @tmp + @randNum
-- OR DECLARE @batchID VARCHAR(MAX) = @tmp + CAST(@randNum AS VARCHAR)
SELECT @batchID
答案 3 :(得分:1)
尝试以下操作:
1)
DECLARE @tmp CHAR(7) = CHAR(CAST(RAND()*26 AS int)+65) + CHAR(CAST(RAND()*26 AS int)+65) + CHAR(CAST(RAND()*26 AS int)+65) + cast(cast(RAND()*9999 as int) as varchar(4));
SELECT @tmp;
2)是的,我是这样。
答案 4 :(得分:1)
1-串联部分非常简单,您可以执行以下操作:
DECLARE @tmp VARCHAR(10);
SET @tmp = CHAR(CAST(RAND()*26 AS int)+65)
+ CHAR(CAST(RAND()*26 AS int)+65)
+ CHAR(CAST(RAND()*26 AS int)+65)
+ CAST(cast(RAND()*9999 as int) AS VARCHAR(4));
SELECT @tmp;
2-我建议您在表中填充要发布给用户的随机值,然后从中进行选择,以避免出现竞争情况。
用两个列BatchNumbers
和BatchNumber
创建一个名为Used
的表。
填充批次号表,并将0作为“已用列”的默认值。
然后,每次需要批号时,请执行以下操作。
CREATE PROC dbo.usp_Get_BatchNumber
@BatchNumber VARCHAR(10) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
Declare @t TABLE (BN VARCHAR(10));
UPDATE TOP (1) BatchNumbers
SET Used = 1
OUTPUT inserted.BatchNumber INTO @t (BN )
WHERE Used = 0;
SELECT @BatchNumber = BN FROM @t;
END
答案 5 :(得分:1)
我赞成特里·卡门(Terry Carmen)的回答,但从他的评论看来,他的建议与我最初的想法有所出入,因此这里有一个完整的例子。我认为您想要一个表,该表具有一个用IDENTITY
属性定义的键,该键将告诉SQL Server您想要该列中的唯一顺序值,并且希望数据库担心保证它的详细信息。这样。
create table dbo.Import
(
-- identity(1, 1) means that SQL Server will automatically assign values for
-- this column when you insert a record, with 1 being the first value
-- assigned and each subsequent value incrementing by 1.
Identifier bigint not null identity(1, 1),
-- This column for illustration only; replace it with whatever data you need
-- to store.
YourStuffHere varchar(max)
);
-- Now simply use any INSERT or MERGE command against dbo.Import, and omit the
-- Identifier column from the list of columns whose values the command supplies.
-- Then you can use the SCOPE_IDENTITY() function or an OUTPUT clause to capture
-- the Identifier value that SQL Server has inserted.
-- Example 1: INSERT with explicit values and OUTPUT.
insert dbo.Import
(YourStuffHere)
output
inserted.Identifier
values
('Example 1');
-- Example 2: INSERT/SELECT with OUTPUT.
insert dbo.Import
(YourStuffHere)
output
inserted.Identifier
select
'Example 2';
-- Example 3: INSERT with SCOPE_IDENTITY().
insert dbo.Import
(YourStuffHere)
values
('Example 3');
select Identifier = convert(bigint, scope_identity());
-- Show table contents.
select * from dbo.Import;
上面的第一条INSERT
语句产生以下结果:
Identifier
1
第二个:
Identifier
2
第三个SELECT
之后的INPUT
给出:
Identifier
3
最后的SELECT
向您显示表的内容:
Identifier YourStuffHere
1 Example 1
2 Example 2
3 Example 3
这是解决此问题的最简单方法,因为它允许SQL Server为您完成所有实际工作。如果我误解了您的要求,请告诉我。