Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在SQL Server表中匹配前导零个数可变的字段_Sql Server_Database_Tsql - Fatal编程技术网

Sql server 在SQL Server表中匹配前导零个数可变的字段

Sql server 在SQL Server表中匹配前导零个数可变的字段,sql-server,database,tsql,Sql Server,Database,Tsql,我有一种情况,我有一个传入的数据值,可能有也可能没有前导零。我需要将其与SQL Server表中的字段/行相匹配。SQL Server数据库中的字段值也可能有前导零,也可能没有前导零 因此,我可能会: 传入=50428000138 以db为单位的值可以是5042800138800504280001380005042800013800050428000138中的任意一个 或者传入的可能是0050428000138 以db为单位的值可以是504280013880050428000138000504

我有一种情况,我有一个传入的数据值,可能有也可能没有前导零。我需要将其与SQL Server表中的字段/行相匹配。SQL Server数据库中的字段值也可能有前导零,也可能没有前导零

因此,我可能会:

  • 传入=50428000138
    以db为单位的值可以是5042800138800504280001380005042800013800050428000138中的任意一个

  • 或者传入的可能是0050428000138
    以db为单位的值可以是5042800138800504280001380005042800013800050428000138中的任意一个

我提出的解决方案是去掉传入数据的前导零(始终),并使用SQL,如以下示例所示:

-- this simulates the incoming value to check
-- i strip out the leading zeroes.
declare @tryUPC as varchar(40)
set @tryUPC = '5042800138'

-- try to find it in the database and ignore leading zeroes
select prod_uid, prod_partno, prod_upc
from products as p
where (prod_upc = @tryUPC) or 
   (
   len(prod_upc) > len(@tryUPC)
   and right(prod_upc, len(@tryUPC)) = @tryUPC
   and stuff(prod_upc, 1, len(prod_upc) - len(@tryUPC), '0') = prod_upc
   )
这似乎奏效了。我的问题是,我是否遗漏了什么?SQL Server是否有更好的方法来处理此问题?我正在使用SQLServer2005

蒂亚

不要更新所有现有数据,使其不包含任何前导零,可能使用BIGINT数据类型
2) 在保存和搜索之前,始终从输入中去掉前导零
3) 不要再担心前导零了,实际上你可以使用索引

编辑 在OP的评论之后:


这不是很好,但这不是现实。我想我应该提到这是一个遗留应用程序。upc代码可以在不同的地方输入。更改数据类型将需要大量的折射。此外,有时需要零-数据库保持现状是有充分理由的唐迪金森

您可以使用一个持久的计算列,在其中反转()该列,然后对其进行索引。然后,您可以查询:

WHERE Column1Reverse Like REVERSE('1234567')+'%' --can use the persistent computed column's index
要添加持久化计算列(反转字符串)并在其上建立索引,请使用以下代码:

ALTER TABLE YourTable添加反向YourString作为反向(YourString)保留

CREATE NONCLUSTERED INDEX IX_YourTable_ReversedYourString 
ON YourTable (ReversedYourString) 

如果无法更改现有数据以去除前导零/转换为INT,则只需执行以下操作可能会更快:

WHERE prod_upc IN (@tryUPC, '0' + @tryUPC, '00' + @tryUPC, '000' + @tryUPC [...])
这和我的脚一样优雅,但它会更静态、更清晰,并且(可能)更容易得到任何相关的索引

这是假设你的前导零的数量是有限的,注意。将数据转换为INT(或添加一个新的INT列并在插入时进行计算)可能是解决此问题的最佳方法。

只需另一个倾斜(更正数据最好,但公认的答案也是一个不错的解决方法):添加一个持久化的索引计算列“actualUPC”,这是一种字符类型,使用正确数量的前导零进行计算。例如:

如果“实”代码应该是12位数字,则将计算列设置为

 right( '000000000000' + originalColumn, 12 )
这样,输入数据实际上被更正,然后被正确地索引,并且可以使用索引进行搜索

在查询时,还要将要匹配的输入作为常量填充到查询中

不过,在过于疯狂之前,请检查对索引计算列的限制


像这样的BTW代码(邮政编码、序列号、ssn等)应该始终以文本数据的形式存储,并带有前导零,而不是整数或数字类型。从一个在邮政编码01033的地方长大的人那里拿出来。

+1-比我快。我想提出的所有建议都与将数据转换为理想/最佳格式有关querying@AdaTheDev忘了一个:…将数据转换成理想/最佳/一致的格式…@KM-啊,是的!一致性是冠军的特质:)这不是很好,但不是现实。我想我应该提到这是一个遗留应用程序。upc代码可以在不同的地方输入。更改数据类型将需要大量的折射。此外,有时还需要零——数据库之所以如此是有很好的理由的。我喜欢你第一个想法的(相反):用正确数量的前导零填充所有原始数据,并将数据存储为文本。永远不要为代码引入可变长度(这是一个代码,而不是一个数字),问题也会消失,索引工作,等等。邮政编码、ssn、序列号等也是如此。我想这样可能更好。我必须看看允许的前导零的数量。用我的方法让它处理这么多的零可能是没有必要的。谢谢,只要数据不是分段的,我肯定会推荐这个(分段的意思。或者)。或者,您可以将所有字符填充到特定数量的零(123->001230123->0012300123->00123等)。。。如前所述,关键是要比较的两个索引之间的一致性。请参阅我的编辑,它显示了如何使用索引