SQL Server:在字符串中查找值

时间:2019-01-02 15:51:13

标签: sql-server

我正在使用:

  • Windows Server 2012 R2上的Microsoft SQL Server 2016(SP1)(X64)
  • Microsoft SQL Server Management Studio 14.0.17213.0

我在表中具有以下值:

table new_value from DB usm_system_change_detail

我需要一个查询,该查询在“ DNS_texto”列中找到txtf_dns_name=的值,并仅返回其结果。在该示例中,它只会是“ First_Domain”和“ Second_Domain”

使用同事的技巧后,我可以部分完成工作:

declare @var varchar(max) = (select new_value
                             from usm_system_change_detail AS uscd 
                             inner join usm_system_change AS usc on uscd.id = usc.id
                             inner join usm_request ON usc.object_id = usm_request.request_id
                             where object_id = '14170' 
                               and new_value like  '%silo01.mysql.bdh%'
                               and nsp_path= 'REQ_CREATE:ADDED')

select 
    substring(substring(@var, charindex('txtf_dns_nome', @var) + 14, 99), 1, charindex(',', substring(@var, charindex('txtf_dns_nome', @var) + 14, 99)) - 1)

这将返回:

silo01.mysql.bdh

但是如果删除where子句,我会得到:

  

Mensagem 245,Nível16,Estado 1,Linha 1
  将varchar值'f8543002'转换为数据类型int时,转换失败。

3 个答案:

答案 0 :(得分:0)

您可以使用嵌套的substring。如评论所述,txtf_dns_nome位于字符串中,而不是txtf_dns_name

declare @var varchar(max) = '**chb_cname=,chb_ipv4=value,chb_ipv6=value,lbl_dominio=,sel_dns_zona=dominio.com.br.,table_single_records-sel_rec_single_reverso--1=Não,table_single_records-txtf_rec_single_valor--1=1.1.1.1,txta_dns_motivo=teste,txtf_dns_nome=im_am_a_legend,txtf_contact_ext=1,txtf_contact_matricula=f123456,txtf_contact_name=john@email.com**'

select substring(substring(@var,charindex('txtf_dns_nome',@var) + 14, 99),1,charindex(',',substring(@var,charindex('txtf_dns_nome',@var) + 14, 99)) - 1)

这基本上是将substringtxtf_dns_nome到字符串的末尾,然后从该字符串中将substring到第一个逗号,这将使您拥有自己的价值。

答案 1 :(得分:0)

Declare @Pattern as NVARCHAR(100);
SET @Pattern = 'txtf_contact_name=';

select 
    SUBSTRING(MyValue, CHARINDEX(@Pattern, MyValue) + LEN(@Pattern), CHARINDEX('=', MyValue, CHARINDEX(@Pattern, MyValue))) as R
from 
    Table_2
where 
    MyValue like '%' + @Pattern + '%'

答案 2 :(得分:0)

这是使用REPLACESUBSTRINGLENCHARINDEX的可能解决方案:

--The test string
DECLARE @testString varchar(MAX) = '**chb_cname=,chb_ipv4=value,chb_ipv6=value,lbl_dominio=,sel_dns_zona=dominio.com.br.,table_single_records-sel_rec_single_reverso--1=Não,table_single_records-txtf_rec_single_valor--1=1.1.1.1,txta_dns_motivo=teste,txtf_dns_nome=im_am_a_legend,txtf_contact_ext=1,txtf_contact_matricula=f123456,txtf_contact_name=john@email.com**'
--Local string variable to hold the reduced string
--This gets the substring starting at the character index of the string you are
--looking for a value of (txtf_dns_nome)
--Then using REPLACE we get rid of the value txtf_dns_nome= which leaves a substring
--Holding the value you want or in case it is not the last key/value, the value
--Plus the remaining string
DECLARE @reducedString varchar(MAX) = REPLACE(SUBSTRING(@testString, CHARINDEX('txtf_dns_nome=', @testString), LEN(@testString) - CHARINDEX('txtf_dns_nome', @testString)), 'txtf_dns_nome=', '')
--Check to see if there is a comma, if so we want to grab the value up to the comma
--else the searched for string was the last key/value in the string so just get
--what is left
SELECT CASE WHEN CHARINDEX(',', @reducedString) = 0 THEN @reducedString ELSE SUBSTRING(@reducedString, 0, CHARINDEX(',', @reducedString, 0)) END

如果您需要将此作为表解决方案,只需执行以下操作,我将其拆分为上面的示例,以尝试解释发生的情况并为您提供测试示例。

TABLE解决方案:

SELECT CASE WHEN CHARINDEX(',', REPLACE(SUBSTRING([YourColumn], CHARINDEX('txtf_dns_nome=', [YourColumn]), LEN([YourColumn]) - CHARINDEX('txtf_dns_nome', [YourColumn])), 'txtf_dns_nome=', '')) = 0 THEN
REPLACE(SUBSTRING([YourColumn], CHARINDEX('txtf_dns_nome=', [YourColumn]), LEN([YourColumn]) - CHARINDEX('txtf_dns_nome', [YourColumn])), 'txtf_dns_nome=', '')  
ELSE SUBSTRING(REPLACE(SUBSTRING([YourColumn], CHARINDEX('txtf_dns_nome=', [YourColumn]), LEN([YourColumn]) - CHARINDEX('txtf_dns_nome', [YourColumn])), 'txtf_dns_nome=', ''), 0, CHARINDEX(',', REPLACE(SUBSTRING([YourColumn], CHARINDEX('txtf_dns_nome=', [YourColumn]), LEN([YourColumn]) - CHARINDEX('txtf_dns_nome', [YourColumn])), 'txtf_dns_nome=', ''), 0)) 
END
FROM [dbo].[YourTable]

可能更好的表解决方案,因为它没有使用太多的函数调用 并一次减少子查询中的字符串值:

SELECT CASE WHEN CHARINDEX(',', x.[YourColumn]) = 0 THEN x.[YourColumn] ELSE SUBSTRING(x.[YourColumn], 0, CHARINDEX(',', x.[YourColumn], 0)) END AS [YourColumn]
FROM 
(
   SELECT REPLACE(SUBSTRING([YourColumn], CHARINDEX('txtf_dns_nome=', [YourColumn]), LEN([YourColumn]) - CHARINDEX('txtf_dns_nome', [YourColumn])), 'txtf_dns_nome=', '') AS [YourColumn]
   FROM [dbo].[YourTable]
) AS x