视图 SQL 服务器中临时 Table 的解决方法

Workaround for temporary Table in view SQL Server

我遇到以下问题:我想创建一个视图,其中包含 table,其列 'verylongtext' 应拆分为不得超过 50 个字符的字符串。 此结果集应加入视图中。 临时 table 将按以下方式创建:

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   

问题当然是视图中不允许临时 table。 CTE 似乎不适用于函数的结果集。还有其他可能的方法吗?我完全无能为力。提前致谢!!

您可以使用 APPLY 在基础 table 上直接调用拆分函数,这意味着不需要临时 table 或循环:

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

您可能会发现标量函数 dbo.DelineateEachNth 是性能杀手(因为所有标量 UDF 都是如此),因此拆分字符串的另一种方法是使用计数 table:

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;