2017-05-09 72 views
0

我有以下问题:我想创建等包含一个表,其列“verylongtext”应该在一定不能超过50个字符的字符串被分裂的看法。 此结果集应该在视图中接合。 临时表将创建下列方式:解决办法临时表中查看SQL Server的

create table #results(id int, string varchar(400)) 
declare @results table(id int, string varchar(400)) 
declare @id int 
declare @strings varchar(400) 
set @id = 0 
while exists (select * from roottable where row_id > @id) 
begin 
    select top 1 @id = row_id, @strings = verylongtext from roottable 
    where row_id > @id 
    order by row_id asc 
    insert into #results 
    select @id, data from dbo.Split([dbo].[DelineateEachNth](@strings, 50, '$'), '$') 
end 

问题是当然的,没有临时表允许的看法。 CTE似乎不适用于该函数的结果集。有没有其他可行的方法?我绝对无能为力。提前致谢!!

+0

你可能并不需要为您的要求while循环...这是糟糕的设计的...你可能需要直接选择查询,您可以在视图中直接安装.. –

+0

请放在一起[SQL小提琴] (http://sqlfiddle.com),以便人们可以合作。 – Lucero

回答

0

您可以使用APPLY基表直接打电话给你的分割功能,这意味着没有临时表或要求的循环:

SELECT r.id, s.data 
FROM RootTable AS r 
CROSS APPLY dbo.Split(dbo.DelineateEachNth(r.VeryLongText, 50, '$'), '$') AS s; 

您可能会发现标量函数dbo.DelineateEachNth是性能杀手(就像所有的标量UDF是),作为这样的替代的方式来分割字符串是使用符合表:

CREATE FUNCTION dbo.FixedLengthSplit 
(
    @String  NVARCHAR(MAX), 
    @Length  INT 
) 
RETURNS TABLE 
WITH SCHEMABINDING AS 
RETURN 
( WITH N1 AS (SELECT N FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1), (1)) n (N)), 
    N2(N) AS (SELECT 1 FROM N1 a CROSS JOIN N1 b), 
    N3(N) AS (SELECT 1 FROM N2 a CROSS JOIN N2 b), 
    N4(N) AS (SELECT 1 FROM N3 a CROSS JOIN N3 b), 
    Numbers (N) AS 
    ( SELECT TOP (CONVERT(INT, CEILING(1.0 * ISNULL(LEN(@String),1)/@Length))) 
       ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 
     FROM n4 
    ) 
    SELECT ItemNumber = N + 1, 
      Data = SUBSTRING(@String, 1 + (@Length * N), @Length) 
    FROM Numbers 
); 

那么你的观点只是:

SELECT * 
FROM rootTable AS r 
CROSS APPLY dbo.FixedLengthSplit(r.VeryLongString, 50) AS s; 
+0

非常感谢您的解决方案和fixedlengthsplit功能的建议!我不知道APPLY。 –