2017-05-09 73 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。 –