我正在使用SSMS 2008,我有以下Scalar函数来获取文本字符串并从Microsoft Word中删除所有元标记。标签包含在“< ...>”中并且一列中可以有任意数量的标签/记录。
我根据以下代码创建了一个标量函数来更新此列中的每一行。但是这个标量函数需要很长时间才能完成。表函数版本会更快吗?如果是这样,我怎么能重写这个函数来使它成为表?
WHILE PATINDEX( '%[%]%', @str ) > 0
SET @str = REPLACE( @str, SUBSTRING( @str,
PATINDEX( '%[%]%', @str ), 1 ), '' )
SELECT @str
这个表功能几乎可以工作。但事实证明它现在不起作用。问题是我试图在临时表上使用此函数。并且原始表没有int PK,我无法在原始表中添加列。
所以我尝试基于这个表创建一个视图,然后向它添加一个PK int列。因为当我尝试使用这个额外的PK int列(“n”)创建视图时,它给了我一个错误:
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'identity'.
但是ALTER VIEW不支持添加列。还有另一种方法吗?这是我试图修改的原始临时表:
select [progress_note].[note_text], [progress_note].[event_log_id]
INTO #TEMP_PN
from [evolv_cs].[dbo].[progress_note]
group by [progress_note].[event_log_id], [progress_note].[note_text]
[note_text]是varchar(max),event_log_id是uniqueidentifier。所以[note_text]包含一堆“<”和“>”字符。如何修改此dbo.ufn_StripHTML函数?
我尝试了你的最新代码,这是超级快!但是,我通过5700行后得到以下错误:
Msg 537, Level 16, State 2, Line 1
Invalid length parameter passed to the LEFT or SUBSTRING function.
你知道这是关于什么的吗?
答案 0 :(得分:1)
这是我写的一个函数,用于删除使用基于集合的HTML标记(< ...>对)。我很想知道你是否可以重新利用来剥离Word元标记。
-----------------------------------------------------------
-- 1. create a number table (this is just a utility table)
-----------------------------------------------------------
set nocount on;
if object_id('dbo.Number') is not null
begin
drop table dbo.Number;
end
go
create table dbo.Number (n int identity(1,1) primary key);
insert dbo.Number default values ;
while scope_identity() < 500
insert dbo.Number default values ;
-----------------------------------------------------------
-- 2. create the function (leverages the utility table)
-----------------------------------------------------------
if object_id('dbo.ufn_StripHTML') is not null
begin
drop function dbo.ufn_StripHTML;
end
go
create function dbo.ufn_StripHTML
( @Input varchar(8000),
@Delimiter char(1)
)
returns varchar(8000)
as
begin
declare @Output varchar(8000)
select @Input = replace(replace(@input, '<', @Delimiter), '>', @Delimiter)
select @Output = isnull(@Output, '') + s
from ( select row_number() over (order by n.n asc) [i],
substring(@Delimiter + @Input + @Delimiter, n.n + 1, charindex(@Delimiter, @Delimiter + @Input + @Delimiter, n.n + 1) - n.n - 1) [s]
from dbo.Number n
where n.n = charindex(@Delimiter, @Delimiter + @Input + @Delimiter, n.n) and
n.n <= len(@Delimiter + @Input)
) d
where i % 2 = 1
return @Output
end
go
-----------------------------------------------------------
--3. Example of calling the function when you query
-----------------------------------------------------------
if object_id('tempdb..TEMP_PN') is not null
drop table #TEMP_PN;
create table #TEMP_PN (note_text varchar(max), event_log_id int);
insert into #TEMP_PN
select '<b>Some very large bolded text here!</b>', 1 union all
select 'no tags here', 2 union all
select '<html><body><h1>My First Heading</h1><p>My first paragraph.</p></body></html>', 3
select [Strip] = dbo.ufn_StripHTML(note_text, '|'),
[Orig] = note_text,
event_log_id
from #TEMP_PN
编辑:将标量移植到表
alter function dbo.ufn_StripHTMLTable
( @Input varchar(8000),
@Delimiter char(1)
)
returns @ret table (OutString varchar(8000))
as
begin
declare @Output varchar(8000)
select @Input = replace(replace(@input, '<', @Delimiter), '>', @Delimiter)
select @Output = isnull(@Output, '') + s
from ( select row_number() over (order by n.n asc) [i],
substring(@Delimiter + @Input + @Delimiter, n.n + 1, charindex(@Delimiter, @Delimiter + @Input + @Delimiter, n.n + 1) - n.n - 1) [s]
from dbo.Number n
where n.n = charindex(@Delimiter, @Delimiter + @Input + @Delimiter, n.n) and
n.n <= len(@Delimiter + @Input)
) d
where i % 2 = 1;
insert into @ret
values(@Output);
return;
end