Sql server 如何以特定格式创建唯一的序列号字符串?

Sql server 如何以特定格式创建唯一的序列号字符串?,sql-server,coldfusion,guid,uuid,Sql Server,Coldfusion,Guid,Uuid,我想用一些序列号填充我的SQL Server表,以便提供给其他人。实际上,它们只是与人们的电子邮件地址相关的UUID 我可以看到ColdFusion提供了CreateUUID函数,但它生成的ID格式如下: xxxxxxxx-xxxx-xxxx-XXXXXXXXXXXXXX 这是一个8-4-4-16结构。我只想要一些简单的东西,比如3-3-3格式,它对于表中的每一行(即每个客户)都是唯一的 解决这个问题的最好办法是什么?我不介意在SQL或ColdFusion中这样做,但我不知道如何让它们中的任何一

我想用一些序列号填充我的SQL Server表,以便提供给其他人。实际上,它们只是与人们的电子邮件地址相关的UUID

我可以看到ColdFusion提供了
CreateUUID
函数,但它生成的ID格式如下:

xxxxxxxx-xxxx-xxxx-XXXXXXXXXXXXXX

这是一个8-4-4-16结构。我只想要一些简单的东西,比如3-3-3格式,它对于表中的每一行(即每个客户)都是唯一的

解决这个问题的最好办法是什么?我不介意在SQL或ColdFusion中这样做,但我不知道如何让它们中的任何一个自动为我生成这样的字符串。SQL Server具有
NEWID()
函数,但它生成的大字符串格式不是我想要的格式


有没有办法强制SQL的
NewID()
或CF的
CreateUUID
创建一个具有3-3-3格式的唯一序列?

您可以使用类似的方法,它将生成您要查找的格式:

DECLARE @Value VARCHAR(100)
SELECT @Value = NEWID()
SELECT @Value
SELECT SUBSTRING(@Value,1,3) + '-' + SUBSTRING(@Value,10,3) + '-' + SUBSTRING(@Value,30,3)

序列号应该是唯一的。确保电子邮件地址具有唯一序列号的一种方法是设置标识列的格式。如果您的电子邮件表还没有标识列,请添加一个标识列。假设它名为Email_ID,那么下面的表达式将为您提供一个XXX-XXX-XXX形式的字符串,该字符串保证对电子邮件表是唯一的

SELECT
  STUFF(STUFF(RIGHT('000000000' + CAST(Email_ID AS VARCHAR(9)), 9), 4, 0, '-'), 8, 0, '-')
FROM
  EmailTable

您可以创建一个随机的9个字符的字符串,然后检查它在customer/people表中是否唯一。如果不是->创建一个新的随机字符串并再次检查。(循环直到它是唯一的)

我为此创建了两个函数,一个生成9个字符的随机字符串,另一个使用第一个函数创建一个字符串,然后检查一个表以查看该字符串是否存在于特定列中

随机字符串函数:

<cffunction name="makeRandomString" returnType="string" output="false">
    <cfargument name="codeLength" type="numeric" required="no" default="9">

   <cfset var chars = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ">
   <cfset var length = codeLength>
   <cfset var result = "">
   <cfset var i = "">
   <cfset var char = "">

   <cfscript>
   for(i=1; i <= length; i++) {
      char = mid(chars, randRange(1, len(chars)),1);
      result&=char;
   }
   </cfscript>

   <cfreturn result>
</cffunction>


对于(i=1;i)格式是肯定的,但它保证是唯一的吗?我怀疑不是。@Leigh,你是正确的,不保证这会产生唯一的序列号。你可以尝试使用newsequentialid()代替唯一值(编辑)不确定你是指总共九(9)位还是相同长度的uuid,只是格式化为三(3)位组,而不是四个或五个。如果是后者,我认为您可以生成uuid并调整连字符。但我不是100%确定。否则,现有格式是否存在特定的问题或问题?虽然您当然可以DIY,但需要确保生成的值确实是唯一的,而不仅仅是随机的。这似乎有点奇怪ike重新发明轮子…它们将被用作凭证代码,因此不会太长。类似于“XSY-20B-P7O”比一个庞大的默认UUID更适合我的需要。除非生成数百万个ID,否则即使是截断的UUID也不太可能发生冲突。原因是时间戳/时钟在第一组中是如何考虑的。只需去掉
-
并使用前9个字符。如果值不需要全局唯一,则使用9个字符c包含足够的组合,这可能会起作用。只是不要指望它不太可能。如果非唯一值会破坏代码,请确保向表中添加
unique
约束(然后重试代码)。抱歉,我看不出该代码中的列名
Email\u ID
在哪里?@volume\u one.oops,现在已修复。这与我的想法不完全一致。我确实需要一些更随机的东西,如“SYO-001-AXR”。虽然它没有多大用途,但我也不希望人们事后猜测这种组合可能是什么。请记住,web应用程序是多线程的。在繁忙的应用程序中,由于竞争条件,仍然可能出现重复。更可靠的方法是在db表上创建一个
唯一的
约束。然后再试一次/捕获约束异常并将其用作重试的触发器。另外a)不要忘记var/local scope所有函数局部变量b)使用cfqueryparam和c)小心使用表/列的变量,因为根据值的来源,它可能会带来SQL注入风险。我为此创建了两个函数,在发布时,请务必引用来源,这既是出于对作者的礼貌,也不被视为剽窃。没问题。好像我已经用了好几年了,忘了那个零件是从哪里来的。我的回答并不意味着因为写了一些代码而得到“认可”,只是为了帮助其他程序员。我会尽力记住在将来给予表扬。
<cffunction name="createUniqueCode" returnType="string" output="false">

    <cfargument name="tableName" type="string" required="yes">
    <cfargument name="columnName" type="string" required="yes">
    <cfargument name="codeLength" type="numeric" required="no" default="9">

    <cfset ordercode = 0>
    <cfset ordercodecheck = 0>
    <cfloop condition="ordercodecheck eq 0">
        <cfset ordercode = #makeRandomString('#codeLength#')#>
        <cfquery name="findCode" datasource="#application.datasource#">
        select #kolomNaam# from #tableName# where #columnName# = '#ordercode#'
        </cfquery>
        <cfif findCode.recordcount eq 0>
            <cfset ordercodecheck = 1>
        </cfif>
    </cfloop>

    <cfreturn ordercode>

</cffunction>
<cfloop from="1" to="100" index="i">
    <cfset newCode = createUniqueCode(tableName='myTableName',columnName='myColumnName')>

    <!--- insert what to do with new code here (f.e. an insert query) the "newCode" variable holds the new unique code. --->
</cfloop>