Как создать табличную функцию замены TSQL? - PullRequest
1 голос
/ 22 октября 2011

Я использую SSMS 2008 и имею следующую скалярную функцию, чтобы взять текстовую строку и удалить все метатеги из 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 - уникальный идентификатор.Поэтому [note_text] содержит несколько символов "<" и ">".Как я могу изменить эту функцию dbo.ufn_StripHTML?

Я попробовал ваш последний код, и это очень быстро !!Однако после 5700 строк я получил следующую ошибку:

Msg 537, Level 16, State 2, Line 1
Invalid length parameter passed to the LEFT or SUBSTRING function.

Знаешь ли ты, о чем это?

1 Ответ

1 голос
/ 22 октября 2011

Вот функция, которую я написал для удаления тегов 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...