【问题标题】:Create a unique identifier using SQL使用 SQL 创建唯一标识符
【发布时间】:2011-01-26 10:08:20
【问题描述】:

是否有一些 SQL 编码可以在单击获取默认按钮时生成唯一标识符?我正在寻找一种系统来在将物理纸质文件放入存储之前对其进行编号。问题是有 3 个办事处,每个办事处都需要一个序号系统(即 P001、P002、P003 和 C001、C002...)。

下面是我到目前为止生成唯一 ID 号前缀的代码。

SELECT CASE WHEN ptBranch=3 THEN 'P' WHEN ptBranch=4 THEN 'A' ELSE 'C' END + CONVERT(VARCHAR(2),GETDATE(),12) FROM LAMatter WHERE ptMatter = $Matter$

这个想法是代码可以生成整个文件编号,例如P110001、P110002(其中P、C或A表示文件所在的办公室,11表示文件入库的年份)

任何指针都非常感谢

【问题讨论】:

  • sequential 方面有多重要?插入失败会留下任何间隙吗?
  • 不幸的是真的很重要 - 因为它可以更容易地识别存储中丢失的文件(归档后它们一直被取入和取出) - 显然,如果它们是数字,你不会知道是文件丢失还是没有分配数字
  • 好吧,这完全排除了identity,因为这根本不能保证这一点(即使您有 3 个不同的表,您仍然可以从回滚事务中获得间隙)
  • 我刚刚注意到你说你想生成一个新的“点击获取默认按钮的唯一标识符” - 这是否意味着数字的生成发生在你有任何数据要插入之前(例如打印标签或其他东西)?如果是这样,如果生成了一个数字但从未使用过会发生什么?还会多人处理这些文件吗?
  • @martin 回顾您的row_number 想法,而不是order by id,您可以按字段本身订购吗?所以任何已分配编号的文件都会进入列表顶部,下次单击“获取默认值”时,您将获得下一个编号?不太确定这是否有意义,但我希望答案在于row_number 领域

标签: sql sql-server


【解决方案1】:

SQL Server 函数newid() 将生成一个GUID

您的 SQL 查询不会生成按钮或其他任何内容。 SQL 是一种用于查询数据库的语言,而不是用于编写软件接口的语言。

【讨论】:

  • 感谢 Dan,但我希望得到一个增量的 unquie 标识符(即 0001、0002、0003),这可能吗?
  • 是的,创建一个标识列,它会自动生成递增的标识符,而无需您编写任何代码。
  • 使用 Google 或本网站上的搜索框搜索会回答您的问题。这是 Microsoft SQL Server 文档:msdn.microsoft.com/en-us/library/bb545450.aspx
  • 最后一个问题 - 如果您为识别添加前缀(以表示文件所在的办公室),标识符属性是否会在一个办公室生成像 P001、P002、P003 和 C001、C002 在另一个办公室- 或者你会得到一些类似于 P001、C002、P003 的内容吗?假设我在问身份属性是否识别(或者可以识别)前缀?
  • 它不会为你这样做,你永远不应该这样做。每个列值都应该是原子的——它包含一个且只有一个信息。该文件属于哪个办公室是一条单独的信息,并在其自己的列中。如果你想在你的应用程序中显示“P0001”,你可以在你的应用程序中编写代码来组合办公栏和身份栏。您不会将这两个不同的数据存储为一个。
【解决方案2】:

我认为问题的最初措辞可能引起了误解。

我现在设想您需要一个流程,每个办公室都需要能够在每次处理文件时通过单击按钮生成一个新的保证序列号?

然后跟踪序列中的任何间隙以调查潜在的丢失文件。对吗?

如果是这样,您可以使用类似的方法来生成数字。

CREATE TABLE Sequences
(
OfficeCode char(1) primary key,
SequenceNumber int NOT NULL DEFAULT (0)
)

INSERT INTO Sequences(OfficeCode)
SELECT 'P' UNION ALL SELECT 'C' UNION ALL SELECT 'A'

GO

CREATE PROC dbo.GetSequence
@OfficeCode char(1),
@val AS int OUTPUT,
@n as int =1
AS
UPDATE dbo.Sequences 
SET @val = SequenceNumber = SequenceNumber + @n
WHERE OfficeCode = @OfficeCode;

SET @val = @val - @n + 1; 

GO


DECLARE @val  int

EXEC dbo.GetSequence 'C', @val output
select @val

【讨论】:

  • 首先,确认我需要什么(我想我们现在正在从同一张赞美诗表上签名)当一个文件需要进入存档时,每个办公室都会点击一个按钮并获得下一个存档编号随后(然后将其写入文件,并将其放置在存储中)...偶尔字段会从存储中返回,但我们保留它出来的间隙,因此我们知道它丢失了(如果其他人要求它).. 。 那有意义吗?我们同意了吗?至于代码,我不知道如何在我的系统中实现它,对不起,超出了我目前的理解
  • 我玩过,但遗憾的是,数据库不会让我看到它的自定义字段生成器更多。我可以在构建器中看到和更改的 SQL 级别与在初始问题中找到的相同。
【解决方案3】:

我会使用带有创建日期的 row_number 函数。如果您是批量插入,那么您还需要按 row_number 函数中的 id 列排序。

declare @records table (id int identity(1,1), CreationDate datetime, Name varchar(50), Section char(1), FileID varchar(10))

insert into @records (CreationDate, Name, Section)
select '2011-01-26 16:57:49', 'abc','p'

insert into @records (CreationDate, Name, Section)
select '2011-01-26 16:57:50', 'def','p'

insert into @records (CreationDate, Name, Section)
select '2011-01-26 16:58:00', 'ghi','c'

insert into @records (CreationDate, Name, Section)
select '2011-01-26 16:58:50', 'jkl','d'

insert into @records (CreationDate, Name, Section)
select '2011-01-26 16:58:51', 'mno','c'

insert into @records (CreationDate, Name, Section)
select '2011-01-26 16:58:52', 'pqr','p'

insert into @records (CreationDate, Name, Section)
select '2011-01-26 16:58:53', 'def','p'

update @records
set FileID=a.FileID
from 
(
    select id,
    Section + cast(row_number() over (partition by Section order by CreationDate, Section) as varchar(10)) as FileID
    from @records
) a
    inner join @records b
        on a.id=b.id

select * from @records

【讨论】:

    猜你喜欢
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    相关资源
    最近更新 更多