如何在SQL Server中递归选择拆分为多行的二进制数据

时间:2018-12-06 15:54:23

标签: sql-server tsql sitecore

在这里已经阅读了许多类似的问题,请允许我先说一下,我没有选择拆分数据(Sitecore做了),我想要做的就是重新组合它,以便我可以从中提取二进制文件。 Blob表。因此,答案告诉我,我不应该像这样拆分表中的数据,不太可能被视为明智的回答;-)

表数据的图片(显然数据未显示,我这样做是为了提高速度) enter image description here

某些项目仅分为1到3个条目。有些多达178个条目!

目前,我有一个可以正常工作的手动过程,但是我必须做很多条件语句重复才能使其适用于较大的文件。我希望有一种更聪明的方法来执行子查询,联合或联接,从而可以对1到178行的任何文件进行处理。

SELECT it.name,sf.itemID, it.templateId,
CASE WHEN EXISTS(select 1 from Sitecore2018.dbo.Blobs bl where bl.[Index] = 2 and bl.BlobId = sf.value)
        THEN
            (select cast(bl.Data as Varbinary(max)) from Sitecore2018.dbo.Blobs bl where bl.[Index] = 0 and bl.BlobId = sf.value) +
            (select cast(bl.Data as Varbinary(max)) from Sitecore2018.dbo.Blobs bl where bl.[Index] = 1 and bl.BlobId = sf.value) +
            (select cast(bl.Data as Varbinary(max)) from Sitecore2018.dbo.Blobs bl where bl.[Index] = 2 and bl.BlobId = sf.value) 
        ELSE 
            CASE WHEN EXISTS(select 1 from Sitecore2018.dbo.Blobs bl where bl.[Index] = 1 and bl.BlobId = sf.value)
            THEN
                (select cast(bl.Data as Varbinary(max)) from Sitecore2018.dbo.Blobs bl where bl.[Index] = 0 and bl.BlobId = sf.value) +
                (select cast(bl.Data as Varbinary(max)) from Sitecore2018.dbo.Blobs bl where bl.[Index] = 1 and bl.BlobId = sf.value) 
            ELSE 
            (select bl.Data from Sitecore2018.dbo.Blobs bl where bl.[Index] = 0 and bl.BlobId = sf.value ) 
            END
        END  as BData    
  FROM [Sitecore2018].[dbo].[Items] it
  inner join Sitecore2018.dbo.SharedFields sf on sf.ItemId = it.id
  where 
  it.TemplateID='0603F166-35B8-469F-8123-E8D87BEDC171' 
  and 
  sf.FieldId='40E50ED9-BA07-4702-992E-A912738D32DC' 
  and (sf.value is not null and sf.Value != '')
  order by it.name asc

1 个答案:

答案 0 :(得分:1)

这有点棘手,但您可以尝试以下方法:

我使用一个模型表模拟您的问题。为了显示原理,我插入了NVARCHAR值。

DECLARE @mockup TABLE(ID INT IDENTITY, GroupID INT, GroupIndex INT,SomeVal NVARCHAR(100),TheValAsBin VARBINARY(MAX));
INSERT INTO @mockup(GroupId,GroupIndex,SomeVal) VALUES(1,1,N'blah'),(1,2,N'buh'),(1,3,N'oh yeah!')
                                                     ,(2,1,N'&<>§!€'),(2,2,N' 汉语;'),(2,3,N'русский язык'),(2,4,''),(2,5,N'शान्तिः');

-现在我更新表以设置相应的VARBINARY

UPDATE @mockup SET TheValAsBin=CAST(SomeVal AS VARBINARY(MAX));

-递归CTE会将所有这些VARBINARY值伪装成一个long值。
-您可以通过将累积的VARBINARY转换回NVARCHAR(MAX)来检查结果。

WITH RecursiveCTE AS
(
    SELECT GroupId,GroupIndex,TheValAsBin,TheValAsBin AS GrowingValue FROM @mockup WHERE GroupIndex=1 

    UNION ALL

    SELECT m.GroupID,m.GroupIndex,m.TheValAsBin
          ,rc.GrowingValue + ISNULL(m.TheValAsBin, CAST('' AS VARBINARY(MAX))) 
    FROM @mockup m
    INNER JOIN RecursiveCTE rc ON m.GroupID=rc.GroupID AND m.GroupIndex=rc.GroupIndex+1
)
SELECT * 
      ,CAST(GrowingValue AS NVARCHAR(MAX)) AS CheckTheResult
FROM RecursiveCTE
ORDER BY GroupID,GroupIndex;

最后,您必须选择GroupIndexGroupId最高的行。

将最后一个SELECT更改为此

SELECT TOP 1 WITH TIES GroupId
                      ,CAST(GrowingValue AS NVARCHAR(MAX)) AS CheckTheResult
FROM RecursiveCTE
ORDER BY ROW_NUMBER() OVER(PARTITION BY GroupID ORDER BY GroupIndex DESC) 

为了得到这个:

GroupId CheckTheResult
2       &<>§!€ 汉语;русский языкशान्तिः
1       blahbuhoh yeah!