2017-04-06 74 views
0

我在一个系统中遇到了一个相当独特的请求,我正在T-SQL数据库上运行这个请求。我有一个表,看起来像这样在其最基本的形式:VARCHAR字段中的下一个最大值或下一个唯一值

create table Merchants (
    ID   int not null identity(1,1) primary key, 
    PartnerID int, 
    ExternalRef varchar(10), 
    Name  varchar(MAX) 
) 

ExternalRef是一个varchar(10)领域中,我们通过开展一些外部当事人之一提供的参考数字。因此仅在PartnerID值定义的范围内才是唯一的。

我现在面临的问题是,一个合作伙伴没有价值,他们可以提供给我们,并希望我们为他们创造价值。这很简单,我可以使用递增的整数值并将它们转换为varchar。因此,在分配新值之前,我可以简单地执行select max(ExternalRef) where PartnerID = @PartnerID,转换为整数,将值加1并将其转换回varchar。事实上,DBMS将尽一切转换的含蓄和这样的事情应该很好地工作:

select @NewRef = max(ExternalRef)+1 
from Merchants 
where PartnerID = @PartnerID 

但我关心的是,如果该合作伙伴的价值之一就是字母数字值,并得到由返回打电话给select max(ExternalRef)?上述方法显然会以丑陋的方式失败,我不知道有什么方法可以“增加”字母数字字符串,无论这意味着什么。

所以我需要一种方法来创建表中不存在的唯一varchar(10)值。我可以生成一个随机值,检查它是否已经在表格中,如果是,我会重复,但我也不会为这种方法感到生气。如果我在where子句中可以使用某些东西来将结果限制为仅用于数字的值,那也可以起作用,但我想不出一种优雅的方式来做到这一点。喜欢的东西:

select @NewRef = coalesce(max(ExternalRef), 0)+1 
from Merchants 
where PartnerID = @PartnerID 
    and ExternRef is numeric 

会有人对我怎么能产生“下一个最大的” VARCHAR在现场或不会占用太多处理任何独特价值价值的建议?

回答

0

哦,我已经想通了。原来我想象中的“数字”条件并不是那么遥不可及。从SQL Server 2008起,有ISNUMERIC函数。因此,为了得到一个varchar领域未来最大整只值的VARCHAR表示,这里是我现在在做什么:

select @NewRef = coalesce(max(ExternalRef), 0)+1 
from Merchants 
where PartnerID = @PartnerID 
    and ISNUMERIC(ExternRef) = 1 
+0

'IsNumeric()'是使用技术术语[hinky](http://sqlinthewild.co.za/index.php/2011/07/26/goodbye-isnumeric-hell /)。您可能希望查看'Try_Parse()'或'Try_Convert()'。提示:使用合适的软件(MySQL,Oracle,DB2,...)和版本(例如, '的SQL服务器2014'。语法和功能的差异往往会影响答案。 – HABO

+0

谢谢@HABO,我添加了SQL Server标记。我不确定版本标签,因为这个问题不属于任何特定版本的SQL Server。当然,我们使用的版本会规定哪些答案是有用的,但我希望版本不可知的答案。 至于TRY_CONVERT(),它看起来不错,谢谢。不幸的是,它不适用于我们的服务器(2014年)。似乎是因为所讨论的数据库在兼容模式100下运行。我不知道为什么,但我不打算对其进行更改。不过,我会和我们的DBA一起提高它。 –

0
  1. 附加计算持续列或视图新列 - 使用ISNUMERIC确定性函数对新列CASECAST或使用标量函数与架构绑定

    alter table Merchants 
    add ExternRefNbr as (cast(case when isnumeric(ExternalRef) = 1 then ExternalRef end as int)) persisted 
    
  2. 创建索引

  3. 使用列
+0

这是为了使ISNUMERIC(ExternRef)= 1子句更有效吗? –