如何递归 select 二进制数据拆分成 SQL 服务器中的多行
How to recursively select binary data split over multiple rows in SQL Server
在这里阅读了很多类似的问题,请让我先说一下,我没有选择拆分数据(Sitecore 做了),我想做的就是重新组合它,这样我就可以提取二进制文件来自 blob table。因此,告诉我不应该像这样在 table 中拆分数据的答案不太可能被视为明智的回应;-)
table数据的图片(显然数据不是如图所示,我这样做是为了速度)
有些项目只分为 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
这有点棘手,但您可以试试这个:
我使用 mockup-table 来模拟您的问题。为了展示我插入的原则 NVARCHAR
-values.
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'शान्तिः');
--现在我更新table设置对应的VARBINARY
-values
UPDATE @mockup SET TheValAsBin=CAST(SomeVal AS VARBINARY(MAX));
--递归 CTE 将 fiddle 所有这些 VARBINARY
值变成一个长值。
--您可以通过将累积的 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;
最后,您必须选择每个 GroupId
中 GroupIndex
最高的行。
把最后一个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!
在这里阅读了很多类似的问题,请让我先说一下,我没有选择拆分数据(Sitecore 做了),我想做的就是重新组合它,这样我就可以提取二进制文件来自 blob table。因此,告诉我不应该像这样在 table 中拆分数据的答案不太可能被视为明智的回应;-)
table数据的图片(显然数据不是如图所示,我这样做是为了速度)
有些项目只分为 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
这有点棘手,但您可以试试这个:
我使用 mockup-table 来模拟您的问题。为了展示我插入的原则 NVARCHAR
-values.
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'शान्तिः');
--现在我更新table设置对应的VARBINARY
-values
UPDATE @mockup SET TheValAsBin=CAST(SomeVal AS VARBINARY(MAX));
--递归 CTE 将 fiddle 所有这些 VARBINARY
值变成一个长值。
--您可以通过将累积的 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;
最后,您必须选择每个 GroupId
中 GroupIndex
最高的行。
把最后一个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!