2011-10-22 14 views
1

私はSSMS 2008を使用しており、次のスカラー関数を使用してテキスト文字列を取得し、Microsoft Wordからすべてのメタタグを削除します。タグは "< ...>"で囲まれており、1つの列に任意の数のタグ/レコードが存在できます。TSQLの置換表関数の作成方法は?

この列の各行を更新するために、このコードに基づいてスカラー関数を作成しました。しかし、このスカラー関数は非常に長い時間がかかります。これのテーブル関数バージョンはより速いでしょうか?もしそうなら、どうすればテーブルを作るためにこの関数を書き直すことができますか?

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型(最大)と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. 

これは何について知っていますか?

+1

SQL ServerのCLRは、考慮すべきオプションです。 –

+0

note_textの長さが>私が提供した500のテストの例よりも多い場合は、Numberテーブルにさらに多くの行が必要な場合があります。また、私のvarchar(8000) - > maxを修正した後にテストをしてください。ここをクリックして読む - > http://www.sqlservercentral.com/articles/T-SQL/62867/ –

答えて

1

Heres 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 
+0

ありがとう!私は好奇心が強いです - @delimiterは何のために使われていますか? – salvationishere

+0

解析するデータにない文字を入力するだけです。私はパイプを使用しますが、あなたのデータにパイプを設定可能な場合には、 –

+0

ちょっとネイサン、もう一度私の質問でもう一度見てください。 – salvationishere

関連する問題