我需要一个SQL查询来获取text
列中两个已知字符串之间的值。
列名称为 d_info ,表格名称为详细信息。
文本是XML
片段,但存储为text
值。
我需要的是获取书挡<nettoeinkommen>
和</nettoeinkommen>
之间的值,在此示例中为718
。
我还需要将输出保存在名为income
的新列中,数据类型为float(8)
。
land>DE</land></wohnanschrift><taetigkeit>rentner</taetigkeit><dkbkundenstatus><bestandskunde>false</bestandskunde></dkbkundenstatus><haushaltsangaben><einnahmen><einkommen><nettoeinkommen>718</nettoeinkommen></einkommen><kindergeld>0</kindergeld><vermietungverpachtungnetto>0</vermietungverpachtungnetto><elterngeld>0</elterngeld><rentenunbefristet>0</rentenunbefristet><unselbststaendigetaetigkeit>740</unselbststaendigetaetigkeit><geringfuegigebeschaeftigung>0</geringfuegigebeschaeftigung></einnahmen><ausgaben><warmmiete>550</warmmiete><ratenimmobilienfinanzierung>0</ratenimmobilienfinanzierung>
我试过这段代码:
SELECT cast(SUBSTRING(d_info, CHARINDEX('<nettoeinkommen>', d_info)
, CHARINDEX('</nettoeinkommen>', d_info) - CHARINDEX('<nettoeinkommen>', d_info)) as float(8)) as income
from dbo.Details
但它正在返回Error converting data type varchar to real.
当我删除cast
函数时,脚本可以正常工作,但它返回的是<nettoeinkommen>718
而不是718
。
感谢。
答案 0 :(得分:2)
它从标签的开头而不是它的结尾开始。
SELECT cast(
SUBSTRING(
d_info,
CHARINDEX('<nettoeinkommen>', d_info) + len('<nettoeinkommen>'),
CHARINDEX('</nettoeinkommen>', d_info) - (CHARINDEX('<nettoeinkommen>', d_info) + len('<nettoeinkommen>'))
) as float(8)) as income
from dbo.Details
你甚至可能在变量中定义了这些:
SELECT cast(
SUBSTRING(
d_info,
CHARINDEX(@startTag, d_info) + len(@startTag),
CHARINDEX(@endTag, d_info) - (CHARINDEX(@startTag,d_info)+ len(@startTag))
) as float(8)) as income
from dbo.Details
我认为使用变量更容易理解代码。
答案 1 :(得分:1)
您需要从起始索引添加开始标记的长度,并从子字符串语句的长度中减去:
SUBSTRING(d_info, CHARINDEX('<nettoeinkommen>', d_info)+16,
CHARINDEX('</nettoeinkommen>', d_info) - CHARINDEX('<nettoeinkommen>', d_info)-16)
答案 2 :(得分:1)
看起来,你正在查询普通的xml数据,为此目的,sql-server提供了xquery功能:
SELECT CAST(r.d_info AS XML).value('(/haushaltsangaben/einnahmen/einkommen/nettoeinkommen)[1]', 'decimal(19,2)')
FROM
(
SELECT '<taetigkeit>rentner</taetigkeit>
<dkbkundenstatus>
<bestandskunde>false</bestandskunde>
</dkbkundenstatus>
<haushaltsangaben>
<einnahmen>
<einkommen>
<nettoeinkommen>718</nettoeinkommen>
</einkommen>
</einnahmen>
</haushaltsangaben>' AS d_info
) AS r
如果您打算从源查询更多信息,最终会得到一堆堆叠子字符串,patindex函数甚至您自己定义的函数。这应该更具可读性和可持续性。
使用XQuery:https://docs.microsoft.com/en-us/sql/t-sql/xml/query-method-xml-data-type
关于您的初始问题SQL中的SUBSTRING
函数返回从给定索引开始的特定长度的字符串的子集。例如SELECT SUBSTRING('whatever',5,4)
返回&#39;永远&#39;。
在CHARINDEX
的情况下,它给出了字符串中给定模式的第一个匹配的索引。示例SELECT CHARINDEX('ever','whatever')
应返回5,因为&#39;永远&#39;无论是什么&#39;都从第五个位置开始。
现在,在您的情况下,您需要将'<nettoeinkommen>'
的长度添加到起始charindex并从子字符串的长度中减去'</nettoeinkommen>'
的长度:
如果需要精确计算,还可以考虑使用十进制或数字类型而不是浮点数:https://technet.microsoft.com/en-us/library/ms187912(v=sql.105).aspx