从定界字符串中提取文本到另一个定界字符串TSQL中

时间:2019-04-11 12:47:09

标签: sql-server tsql

我有这个字符串,例如when((DataSource) ctx.lookup("Database name")).thenReturn(dataSource);

我希望能够从此public void getdetails() { MainclassObj mainclassObj=new MainclassObj(); InitialContext ctx = Mockito.mock(InitialContext.class); when((DataSource) ctx.lookup("Database name")).thenReturn(dataSource); //This is the manin class where DB call is made. mainclassObj.getRequiredData(String value); when(response.getStaus).thenReturn(200); }

中获取以下字符串

我尝试了多种解决方案,但它们往往迎合字符串的一个“部分”。如果无法做到这一点,那么我可以在c#端对其进行格式化,但是能够在存储过程中做到这一点是很好的。

谢谢

编辑:不幸的是,这是第三方数据集,所以我已经使用C#格式化了该数据。从下面的答案中,我同意SQL并非旨在提取和解析我所需要的内容,而这本来就更易于维护。

3 个答案:

答案 0 :(得分:1)

我假设需要在服务器上解析数据的原因是在更大的查询中使用它。否则,没有理由在服务器上进行解析。在C#中这样做会容易得多,例如使用正则表达式。

在不知道是哪个SQL Server的情况下,我假设它是2016年或以后,因为这允许我们通过将\替换为":"和{{ 1}}和;。在较早的版本中可以使用类似的技术将字符串转换为XML。

假设这个简单的表:

","

我们可以使用declare @table table (id int identity primary key,col varchar(max)) insert into @table (col) values ('Green/1051;Brown/1258;Red/1110;Yellow /1024;Red/1147;') 删除结尾的分号。此查询:

STUFF(col,len(col),1,'')

给予

select stuff(col,len(col),1,'')
from @table

代替Green/1051;Brown/1258;Red/1110;Yellow /1024;Red/1147 /
;

送礼:

select replace(replace(stuff(col,len(col),1,''),'/','":"'),';','","')
from @table

我们现在只需要通过用Green":"1051","Brown":"1258","Red":"1110","Yellow ":"1024","Red":"1147 {"包围此值来完成JSON字符串即可。

完成此操作后,我们可以使用OPENJSON:

"}

这将从源表返回select * from @table cross apply openjson('{"' + replace(replace(stuff(col,len(col),1,''),'/','":"'),';','","') + '"}') id列,并从OPENJSON返回colkeyvalue列:

type

会返回:

select id,[key],value
from @table 
    cross apply openjson('{"' + 
replace(replace(stuff(col,len(col),1,''),'/','":"'),';','","') + '"}') x

我们可以将这些结果与另一个表合并。假设这些数字是商品ID,我们有一个库存表,其中每个库存的数量:

id  key     value
1   Green   1051
1   Brown   1258
1   Red     1110
1   Yellow  1024
1   Red     1147

哪些项目的数量超过20?

declare @inventory table (colorid int,amount int)

insert into @inventory (colorid,amount)
values
(1051,5),
(1258,10),
(1110,24),
(1024,2),
(1147,22)

结果是:

select id, [key],colorid,amount
from @table 
    cross apply openjson('{"' + replace(replace(stuff(col,len(col),1,''),'/','":"'),';','","') + '"}') x
inner join @inventory i on i.colorid=x.value
where amount>20

答案 1 :(得分:0)

搜索DelimitedSplit8K。 这将使您可以将字符串转换为多个行;在;

然后您可以使用STUFF..FOR XML来重建字符串

或者,如果您知道您将始终想要所有可以使用的数字和分号,无“字母和空格”

REPLACE(REPLACE(instring,[A-Z],''),' ','')

答案 2 :(得分:0)

如果有STRING_AGG可用,可以将其与STRING_SPLIT一起使用:

DECLARE @str VARCHAR(100) = 'Green/1051;Brown/1258;Red/1110;Yellow /1024;Red/1147;';

SELECT STRING_AGG(STUFF(value, 1, CHARINDEX('/', value), ''), ';')
FROM STRING_SPLIT(@str, ';')
WHERE value IS NOT NULL

结果中的数字顺序可能与原始顺序不匹配。