提取嵌入在复合代码字符串

时间:2015-04-23 16:46:17

标签: sql sql-server sql-server-2008

我正在尝试在sql server 2008中创建一段代码,该代码将从dbo表中的每个不同字符串中获取特定值。最终目标是在Visual Studio内创建一个下拉框,以便可以从数据库中选择包含特定产品代码的所有行(请参阅下面的产品代码定义)。示例字符串:

in_0314_95pf_500_w_0315

in_0314_500_95pf_0315_w

我希望识别的这些字符串的一部分是在每个字符串中出现一次的3位数字代码(在本例中我们称之为产品代码)。大约有300种不同的产品代码。

问题是这些产品代码值不会出现在每个唯一字符串中的相同位置。因此,我很难确定产品代码,因为我不能使用子字符串,charindex等等。

有什么想法吗?任何帮助都非常感谢。

3 个答案:

答案 0 :(得分:1)

可以使用PATINDEX

完成此操作
DECLARE @s NVARCHAR(100) = 'in_0314_95pf_500_w_0315'
SELECT SUBSTRING(@s, PATINDEX('%[_][0-9][0-9][0-9][_]%', @s) + 1, 3)

输出:

500

如果没有下划线,那么:

SELECT SUBSTRING(@s, PATINDEX('%[^0-9][0-9][0-9][0-9][^0-9]%', @s) + 1, 3)

这意味着任何非数字符号之间的3位数。

修改

适用于表格:

SELECT SUBSTRING(ColumnName, PATINDEX('%[^0-9][0-9][0-9][0-9][^0-9]%', ColumnName) + 1, 3)
FROM TableName

答案 1 :(得分:0)

一种方法是使用字符串拆分表here,它将字符串分解为其组件。然后,您可以根据您的条件过滤组件:

DataGridViewRow

我稍微修改了这个函数,接受了分隔符作为参数。

SELECT Name
FROM dbo.splitstring('in_0314_95pf_500_w_0315', '_')
WHERE ISNUMERIC(Name) = 1 AND LEN(Name) = 3;

要将此应用于您的表格,请使用CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX), @delimiter VARCHAR(50)) RETURNS @returnList TABLE ([Name] [nvarchar] (500)) AS BEGIN DECLARE @name NVARCHAR(255) DECLARE @pos INT WHILE CHARINDEX(@delimiter, @stringToSplit) > 0 BEGIN SELECT @pos = CHARINDEX(@delimiter, @stringToSplit) SELECT @name = SUBSTRING(@stringToSplit, len(@delimiter), @pos-len(@delimiter)) INSERT INTO @returnList SELECT @name SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+LEN(@delimiter), LEN(@stringToSplit)-@pos) END INSERT INTO @returnList SELECT @stringToSplit RETURN END (单一分隔符):

CROSS APPLY

更新,多个分隔符

我想真正的根本问题是最终产品代码需要从复合密钥中规范化(例如,向同一个表添加一个不同的SELECT mt.Name, x.Name AS ProductCode FROM MyTable mt CROSS APPLY dbo.splitstring(mt.Name, '_') x WHERE ISNUMERIC(x.Name) = 1 AND LEN(x.Name) = 3 ProductId列),使用像这样查询,然后通过ProductCode存储回表中。从字符串中反向设计产品代码似乎是一个试错过程。

尽管如此,在应用最终的判别过滤器之前,您可以继续通过进一步的分割函数(每种类型的分隔符一个)继续传递分割字符串:

update

请注意,stringsplit函数再次被更改以适应多字符分隔符。

答案 2 :(得分:0)

如果您有产品代码的表格(或可以在内联视图中生成),您可以使用like子句将长字符串列表加入到产品代码中。

prodCode    longcode
100         abc_a_100_test
100         f_100_u
100         a_b__c_d_100_efg
111         asdf_111_bob
111         hihi_111_bye
123         in_0314_123_95pf
123         in_123_0314_95pf

他们与这样的产品代码保持一致:

like p.prodCode

编辑:看到其他答案的发展,你可以将like子句简化为

echo "testing";

只是处理一个事实,即你有一个复合字符串产生多个匹配的可能性更大。