Как преобразовать скалярную функцию Tsql в табличную функцию? - PullRequest
1 голос
/ 25 октября 2011

Я использую SSMS 2008, и у меня есть следующая скалярная функция, чтобы взять текстовую строку и удалить все метатеги из Microsoft Word. Теги заключены в «<...>», и в одном столбце может быть любое количество тегов / записей.

Я создал эту скалярную функцию для обновления каждой строки в этом столбце.

create function dbo.ufn_StripHTML
    (   @Input      varchar(max),
        @Delimiter  char(1)
    )
returns varchar(max)
as

begin

    declare @Output varchar(max)
    select  @Input = replace(replace(@input, '<', @Delimiter), '>', @Delimiter)

    select @Output = isnull(@Output, '') + s
    from    (    select   row_number() over (order by n.id asc) [i],
                 substring(@Delimiter + @Input + @Delimiter, n.id + 1, charindex(@Delimiter, @Delimiter + @Input + @Delimiter, n.id + 1) - n.id - 1) [s]
            from    [evolv_cs].[dbo].[progress_note] n
            where   n.id = charindex(@Delimiter, @Delimiter + @Input + @Delimiter, n.id) and
                 n.id <= len(@Delimiter + @Input)
            ) d
    where i % 2 = 1

    return @Output

end

Эта скалярная функция сработала бы, если бы [progress_note] имел столбец id. Но это не так, и я не могу изменить эту таблицу, добавив столбец int. Так что проблема в том, что я пытаюсь использовать эту функцию для временной таблицы.

Поэтому я попытался создать представление на основе этой таблицы, а затем добавить к нему столбец PK int. Потому что, когда я пытался создать представление с помощью этого дополнительного столбца PK int («id»), он выдал ошибку:

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

Конечно, если я попытаюсь заменить таблицу [progress_note] на #TEMP_PN в этой функции, она выдаст ошибку, потому что не распознает ее. Итак, как я могу изменить эту функцию для моего случая?

Тем временем я разработал табличную функцию, которая принимает и выводит параметр таблицы. Это не ошибка, но она не возвращает проанализированные данные, на которые я надеялся. Чего не хватает?

CREATE TYPE dbo.MyTableType AS TABLE 
(
    col1 int identity(1,1) NOT NULL,
    col2 varchar(max) NULL
)
GO

CREATE TABLE [dbo].[MyTable] (
    [col1] [int] identity(1,1) NOT NULL,
    [col2] [varchar](max) NULL
    )   
GO

create PROC usp_AddRowsToMyTable @MyTableParam MyTableType READONLY, @Delimiter varchar(30)
    as
    INSERT INTO MyTable([col2])
    SELECT [col2]   
    FROM @MyTableParam

    --update MyTable
    --set col2 = replace(replace(MyTable.col2, '<', @Delimiter), '>', @Delimiter)
    select s, i, t
    from(
    select MyTableInput.col1 [i],
    replace(replace(MyTable.col2, '<', @Delimiter), '>', @Delimiter) as t,
    substring(@Delimiter + MyTableInput.col2 + @Delimiter, MyTable.col1 + 1, 
    charindex(@Delimiter, @Delimiter + MyTableInput.col2 + @Delimiter, MyTable.col1 + 1) - MyTable.col1 - 1) [s]
    from MyTable
    inner join MyTable as MyTableInput on MyTable.col1 = MyTableInput.col1
    where MyTable.col1 = CHARINDEX(@Delimiter, @Delimiter + MyTableInput.col2 + @Delimiter, MyTable.col1)
     and MyTable.col1 <= LEN(@Delimiter + MyTableInput.col2)
) d


DECLARE @MyTable MyTableType

INSERT INTO @MyTable(col2)
VALUES ('<h><dsf>2000<h><dsf>'),
    ('<sd><dsf>2001'),
    ('2002<vnv><dsf>'),
    ('<gsd><dsf>2003<h><dsf>'),
    ('<eefs><dsf><h><dsf>2004<dfgd><dsf>')

EXEC dbo.usp_AddRowsToMyTable @MyTableParam = @MyTable, @Delimiter = '|'

1 Ответ

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

Не уверен, что я понимаю ваш вопрос, но вот как вы бы изменили свою функцию, чтобы она возвращала таблицу (она называется функцией с табличным значением):

create function dbo.ufn_StripHTML 
    (   @Input      varchar(max), 
        @Delimiter  char(1) 
    ) 
returns @retYourNewTable table
(
    id int primary key clustered not null,
    yoursecond column varchar(100) null,
    ....
) 
as
....

Это то, что выищете?

...