2017-05-09 12 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を知らなかった。 –