Database SQL:如何生成一个由FirstName#u LastName###字段组成的唯一ID表

Database SQL:如何生成一个由FirstName#u LastName###字段组成的唯一ID表,database,ms-access,Database,Ms Access,我有一个像“FIRST_LAST”格式的ID列表 我有一个“main”表,其中有一堆FIRST#u LAST##条目,其中##是一些数字。我正在尝试查找上次未使用的姓名和正在使用的号码 示例用法:我有约翰·史密斯,但我不知道主桌上有多少约翰·史密斯。主桌上有约翰·史密斯1号、约翰·史密斯2号等,但我想知道第一个可用的。所以我有John_Smith,我希望能够对照表扫描它,看到John_Smith 8是主表中第一个未使用的名称 如果我讲不通,请告诉我。我同意唐·乔治的观点。这里的设计是有缺陷的,你

我有一个像“FIRST_LAST”格式的ID列表

我有一个“main”表,其中有一堆FIRST#u LAST##条目,其中##是一些数字。我正在尝试查找上次未使用的姓名和正在使用的号码

示例用法:我有约翰·史密斯,但我不知道主桌上有多少约翰·史密斯。主桌上有约翰·史密斯1号、约翰·史密斯2号等,但我想知道第一个可用的。所以我有John_Smith,我希望能够对照表扫描它,看到John_Smith 8是主表中第一个未使用的名称


如果我讲不通,请告诉我。

我同意唐·乔治的观点。这里的设计是有缺陷的,你正试图做什么。如果可以,请返回并首先进入它自己的数据字段,然后作为它自己的字段进入最后一个字段。每个新条目都应该有一个唯一的自动递增ID,该ID应该是该记录的密钥。如果你想知道有多少“约翰·史密斯”,那么你只需做一个
COUNT()


如果无法做到这一点,那么性能非常差的尝试就是创建一个带有递增计数器的SQL循环:

DECLARE @counter int
SET @counter = 1

DECLARE @name nchar(100)
SET @name = 'john_smith' + CAST(@counter AS nchar(4))

WHILE (Exists(Select * From MainTable WHERE ID = @name ))
BEGIN
   SET @counter = @counter + 1
   SET @name = 'john_smith' + CAST(@counter AS nchar(4))
END

-- Now you have your @name to use...

从设计的角度来看,如果这是您唯一的选择,我将创建一个名为
GetUniqueID(FIRST,LAST)
的函数,该函数返回唯一的ID。它将执行上述函数


之后,您可以插入任何性能更好的SQL代码。

我同意Don George的观点。这里的设计是有缺陷的,你正试图做什么。如果可以,请返回并首先进入它自己的数据字段,然后作为它自己的字段进入最后一个字段。每个新条目都应该有一个唯一的自动递增ID,该ID应该是该记录的密钥。如果你想知道有多少“约翰·史密斯”,那么你只需做一个
COUNT()


如果无法做到这一点,那么性能非常差的尝试就是创建一个带有递增计数器的SQL循环:

DECLARE @counter int
SET @counter = 1

DECLARE @name nchar(100)
SET @name = 'john_smith' + CAST(@counter AS nchar(4))

WHILE (Exists(Select * From MainTable WHERE ID = @name ))
BEGIN
   SET @counter = @counter + 1
   SET @name = 'john_smith' + CAST(@counter AS nchar(4))
END

-- Now you have your @name to use...

从设计的角度来看,如果这是您唯一的选择,我将创建一个名为
GetUniqueID(FIRST,LAST)
的函数,该函数返回唯一的ID。它将执行上述函数


随后,您可以插入任何性能更好的SQL代码。

以下VBA函数可能会有帮助:

Public Function GetNextFirstLastID(first_last As String) As String
Dim cdb As DAO.Database, rst As DAO.Recordset, nextN As Long
Set cdb = CurrentDb
Set rst = cdb.OpenRecordset( _
        "SELECT Max(CLng(Mid(first_lastID, " & Len(first_last) + 1 & "))) " & _
        "FROM mainTable " & _
        "WHERE first_lastID LIKE """ & first_last & "#*""", _
        dbOpenSnapshot)
If IsNull(rst(0).Value) Then
    nextN = 1
Else
    nextN = rst(0).Value + 1
End If
rst.Close
Set rst = Nothing
Set cdb = Nothing
GetNextFirstLastID = first_last & nextN
End Function
对于这样的测试数据

first_lastID   
---------------
gord_thompson1 
gord_thompson11
gord_thompson2 
gord_thom1     
…函数返回

?GetNextFirstLastID("gord_thompson")
gord_thompson12
?GetNextFirstLastID("gord_thom")
gord_thom2
?GetNextFirstLastID("john_smith")
john_smith1

以下VBA函数可能会有帮助:

Public Function GetNextFirstLastID(first_last As String) As String
Dim cdb As DAO.Database, rst As DAO.Recordset, nextN As Long
Set cdb = CurrentDb
Set rst = cdb.OpenRecordset( _
        "SELECT Max(CLng(Mid(first_lastID, " & Len(first_last) + 1 & "))) " & _
        "FROM mainTable " & _
        "WHERE first_lastID LIKE """ & first_last & "#*""", _
        dbOpenSnapshot)
If IsNull(rst(0).Value) Then
    nextN = 1
Else
    nextN = rst(0).Value + 1
End If
rst.Close
Set rst = Nothing
Set cdb = Nothing
GetNextFirstLastID = first_last & nextN
End Function
对于这样的测试数据

first_lastID   
---------------
gord_thompson1 
gord_thompson11
gord_thompson2 
gord_thom1     
…函数返回

?GetNextFirstLastID("gord_thompson")
gord_thompson12
?GetNextFirstLastID("gord_thom")
gord_thom2
?GetNextFirstLastID("john_smith")
john_smith1

在您的设计过程中,创建这些单独的数据字段是否太晚?是的,主表或多或少都是在Stone中设置的。将表设计为具有名字、姓氏和代理自动生成的ID字段是否太晚?这将永远不会有效,运行时出现问题的可能性很高,并且在正确设计时不需要这样做。名字永远不会是唯一的,所以在名字中添加数字使其唯一只会使查询变得更加困难。使用代理键。这确实是一个不可行的设计。@HLGEM我对此没有任何影响。我必须用我所拥有的来工作。我不能去黑客,告诉他们,他们需要在这个时候彻底检查他们的整个系统。我下面的答案将生成一个唯一的ID。我还建议重命名这个问题。标题与您的要求不符。在您的设计过程中,创建这些单独的数据字段是否太晚?是的,主表或多或少都是在Stone中设置的。将表设计为具有名字、姓氏和代理自动生成的ID字段是否太晚?这将永远不会有效,运行时出现问题的可能性很高,并且在正确设计时不需要这样做。名字永远不会是唯一的,所以在名字中添加数字使其唯一只会使查询变得更加困难。使用代理键。这确实是一个不可行的设计。@HLGEM我对此没有任何影响。我必须用我所拥有的来工作。我不能去黑客,告诉他们,他们需要在这个时候彻底检查他们的整个系统。我下面的答案将生成一个唯一的ID。我还建议重命名这个问题。标题与你的要求不符。