Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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_Sql Server_Stored Procedures - Fatal编程技术网

如何在SQL Server中解析复杂字符串

如何在SQL Server中解析复杂字符串,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,我试图找出解析SQL Server中以字符串形式存储的复杂JSON对象的最佳方法 我的表格包含以下信息: LogID | Content -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

我试图找出解析SQL Server中以字符串形式存储的复杂JSON对象的最佳方法

我的表格包含以下信息:

LogID      |    Content
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
55271413   |    {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218912","CarrierScac":"XYZ","Latitude":33.595555,"Longitude":-85.854722,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271414   |    {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218944","CarrierScac":"XYZ","Latitude":37.996666,"Longitude":-78.314444,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271415   |    {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219079","CarrierScac":"YZB","Latitude":34.027500,"Longitude":-117.522222,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271416   |    {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219020","CarrierScac":"XYZ","Latitude":37.754722,"Longitude":-121.144166,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271417   |    {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218911","CarrierScac":"XYZ","Latitude":40.585833,"Longitude":-91.425000,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271418   |    {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218785","CarrierScac":"XYZ","Latitude":30.747500,"Longitude":-85.270277,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
55271426   |    {"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219044","CarrierScac":"XYZ","Latitude":33.598333,"Longitude":-97.936388,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}
我试图解析每个字符串,并将其放入一个新列中,以JSON属性的名称作为列名,相应的值作为行值

例如,下面是我为每一行查找的结果:

LogID     |  LicensePlate  |  FreightHaulerProviderXId  |  FreightProviderReferenceNumber  |  CarrierScac  |  Latitude  |  Longitude  |  StreetAddress1  |  StreetAddress2  |  City  |  State  |  PostalCode  |  Country
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
55271413  |                |  ABC                       |  5218912                         |  XYZ          |  33.595555 |  -85.854722 |                  |                  |        |         |              |                 
我尝试过使用一些可能非常糟糕的SQL逻辑来解析它。实际上,我查找整个字符串,获取一个子字符串,然后手动指定一个列名。对于可伸缩性和性能而言,这不是一个很好的解决方案

SELECT DISTINCT
    SUBSTRING(lcon.Content, CHARINDEX('CarrierScac', lcon.Content)+14, CHARINDEX('City',lcon.Content) - CHARINDEX('CarrierScac', lcon.Content) + Len('City')-21) as 'CarrierScac',
    SUBSTRING(lcon.Content, CHARINDEX('Latitude', lcon.Content)+10, CHARINDEX('Longitude',lcon.Content) - CHARINDEX('Latitude', lcon.Content) + Len('Longitude')-21) as 'Latitude',
    SUBSTRING(lcon.Content, CHARINDEX('Longitude', lcon.Content)+11, CHARINDEX('PositionEventType',lcon.Content) - CHARINDEX('Longitude', lcon.Content) + Len('"PositionEventType')-31) as 'Longitude'
FROM
    acg.LogContext lcon
WHERE
    lcon.Content LIKE '%XYZ%'
任何帮助我都将不胜感激,因为即使在研究了半天的技术之后,我似乎完全被难倒了


谢谢

一个选项是升级到SQL Server 2016。否则,我会考虑使用NeXOLTFISH库和SQL CLR集成。
JSON。。。似乎CLR受到大多数人的青睐;但这里有一个有趣的TSQL方法

我知道仅仅在这里发布链接是不礼貌的,但这可能是TL;大多数人的DR;正如@Gordon Linoff提到的,2016年将有内置支持。总之,有人提出了一个解决方案:


在一个解析函数和两个交叉应用程序的帮助下

Declare @YourTable table (LogID int,Content varchar(max))
Insert Into @YourTable values
(55271413,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218912","CarrierScac":"XYZ","Latitude":33.595555,"Longitude":-85.854722,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271414,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218944","CarrierScac":"XYZ","Latitude":37.996666,"Longitude":-78.314444,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271415,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219079","CarrierScac":"YZB","Latitude":34.027500,"Longitude":-117.522222,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271416,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219020","CarrierScac":"XYZ","Latitude":37.754722,"Longitude":-121.144166,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271417,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218911","CarrierScac":"XYZ","Latitude":40.585833,"Longitude":-91.425000,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271418,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5218785","CarrierScac":"XYZ","Latitude":30.747500,"Longitude":-85.270277,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}'),
(55271426,'{"LicensePlate":"","FreightHaulerProviderXId":"ABC","FreightProviderReferenceNumber":"5219044","CarrierScac":"XYZ","Latitude":33.598333,"Longitude":-97.936388,"StreetAddress1":"","StreetAddress2":"","City":"","State":"","PostalCode":"","Country":""}')


Select LogID
      ,LicensePlate = max(case when Item='LicensePlate' then Value else null end)
      ,FreightHaulerProviderXId = max(case when Item='FreightHaulerProviderXId' then Value else null end)
      ,FreightProviderReferenceNumber = max(case when Item='FreightProviderReferenceNumber' then Value else null end)
      ,CarrierScac = max(case when Item='CarrierScac' then Value else null end) 
      ,Latitude = max(case when Item='Latitude' then Value else null end)
      ,Longitude = max(case when Item='Longitude' then Value else null end)
      ,StreetAddress1 = max(case when Item='StreetAddress1' then Value else null end)
      ,StreetAddress2 = max(case when Item='StreetAddress2' then Value else null end)
      ,City = max(case when Item='City' then Value else null end)
      ,State = max(case when Item='State' then Value else null end)
      ,PostalCode = max(case when Item='PostalCode' then Value else null end)
      ,Country = max(case when Item='Country' then Value else null end)
 From ( 
        Select LogID
              ,Item  = max(case when RetSeq=1 then RetVal else null end)
              ,Value = max(case when RetSeq=2 then RetVal else null end)
        From (
                Select A.LogID
                      ,Grp = B.RetSeq
                      ,C.*
                From  @YourTable A
                Cross Apply (Select RetSeq,RetVal=Replace(Replace(Replace(RetVal,'"',''),'{',''),'}','') From [dbo].[udf-Str-Parse](A.Content,',') ) B
                Cross Apply (Select * From [dbo].[udf-Str-Parse](B.RetVal,':') ) C
            ) N Group By LogID,Grp
      ) F
 Group By LogID
返回

如果需要的话,UDF

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = Row_Number() over (Order By (Select null))
          ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From (Select x = Cast('<x>'+ Replace(@String,@Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i)
);
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')

从SQL Server 2016开始,数据库中内置了JSON支持:。有大量源详细说明了SQL CLR的内存泄漏情况。这个问题解决了吗?不幸的是,我无法升级到2016年,也没有任何第三方集成到我们数据库的perms:你是个天才。非常感谢你!你到底是怎么学会如此惊人的SQL技能的?你有推荐书/网站/在线课程吗?@colonelsanders91 Genius。。。我妻子不会同意的。只能建议通过实践学习,并通过观察重量级击球手来学习。我每天都学到一些东西。这是有趣的部分。