我有一个函数用于将RTF格式的文本转换为纯文本。它在过去一直很好用,到目前为止在相关文本上看起来效果还不错。
但是,在我的230,000条记录的数据集中的某个地方,它会进行一次糟糕的SUBSTRING调用并中止整个事件(不告诉我有问题的记录)。
有什么方法可以得到一些反馈到正在发生的事情? 我知道SQLServer函数不允许PRINT语句或INSERT语句。 而230,000条记录的数据集不是我的,而是客户。我真的不想尝试按记录记录,看看哪一个导致错误。
下面的SQL函数:
CREATE FUNCTION [dbo].[RTF2Text]
(
@rtf nvarchar(max)
)
RETURNS nvarchar(max)
AS
BEGIN
DECLARE @Pos1 int;
DECLARE @Pos2 int;
DECLARE @hex varchar(316);
DECLARE @Stage table
(
[Char] char(1),
[Pos] int
);
INSERT @Stage
(
[Char]
, [Pos]
)
SELECT SUBSTRING(@rtf, [Number], 1)
, [Number]
FROM [master]..[spt_values]
WHERE ([Type] = 'p')
AND (SUBSTRING(@rtf, Number, 1) IN ('{', '}'));
SELECT @Pos1 = MIN([Pos])
, @Pos2 = MAX([Pos])
FROM @Stage;
DELETE
FROM @Stage
WHERE ([Pos] IN (@Pos1, @Pos2));
WHILE (1 = 1)
BEGIN
SELECT TOP 1 @Pos1 = s1.[Pos]
, @Pos2 = s2.[Pos]
FROM @Stage s1
INNER JOIN @Stage s2 ON s2.[Pos] > s1.[Pos]
WHERE (s1.[Char] = '{')
AND (s2.[Char] = '}')
ORDER BY s2.[Pos] - s1.[Pos];
IF @@ROWCOUNT = 0
BREAK
DELETE
FROM @Stage
WHERE ([Pos] IN (@Pos1, @Pos2));
UPDATE @Stage
SET [Pos] = [Pos] - @Pos2 + @Pos1 - 1
WHERE ([Pos] > @Pos2);
SET @rtf = STUFF(@rtf, @Pos1, @Pos2 - @Pos1 + 1, '');
END
SET @rtf = REPLACE(@rtf, '\pard', '^*^');
SET @rtf = REPLACE(@rtf, '\par', '^*^');
SET @rtf = REPLACE(@rtf, '\t', '^~^');
SET @rtf = STUFF(@rtf, 1, CHARINDEX(' ', @rtf), '');
IF len(@rtf) > 0
WHILE (Right(@rtf, 1) IN (' ', CHAR(13), CHAR(10), '}'))
BEGIN
SELECT @rtf = SUBSTRING(@rtf, 1, (LEN(@rtf + 'x') - 2));
IF LEN(@rtf) = 0 BREAK
END
SET @Pos1 = CHARINDEX('\''', @rtf);
WHILE @Pos1 IS NOT NULL AND @Pos1 > 0
BEGIN
IF @Pos1 IS NOT NULL AND @Pos1 > 0
BEGIN
SET @hex = '0x' + SUBSTRING(@rtf, @Pos1 + 2, 2);
SET @rtf = REPLACE(@rtf, SUBSTRING(@rtf, @Pos1, 4), CHAR(CONVERT(int, CONVERT (binary(1), @hex,1))));
SET @Pos1 = CHARINDEX('\''', @rtf);
END
END
SET @rtf = COALESCE(@rtf, '') + ' ';
SET @Pos1 = PATINDEX('%\%[0123456789][\ ]%', @rtf);
WHILE @Pos1 IS NOT NULL AND @Pos1 > 0 AND @rtf != ''
BEGIN
SET @Pos2 = CHARINDEX(' ', @rtf, @Pos1 + 1);
IF @Pos2 < @Pos1
SET @Pos2 = CHARINDEX('\', @rtf, @Pos1 + 1);
IF @Pos2 < @Pos1
BEGIN
SET @rtf = SUBSTRING(@rtf, 1, @Pos1 - 1);
SET @Pos1 = 0;
END
ELSE
BEGIN
SET @rtf = STUFF(@rtf, @Pos1, @Pos2 - @Pos1 + 1, '');
SET @Pos1 = PATINDEX('%\%[0123456789][\ ]%', @rtf);
END
END
IF RIGHT(@rtf, 1) = ' '
SET @rtf = SUBSTRING(@rtf, 1, LEN(@rtf) -1);
RETURN @rtf;
END
答案 0 :(得分:0)
不要太粗鲁,但你真的测试了你的功能吗?
您是否运行过任何单元测试以尝试破坏您的功能,例如无效的值,边界条件等。
您是否检查过文档以了解SUBSTRING
可以在什么条件下抛出异常?
我已经运行了这些案例并且遇到了异常:
SELECT dbo.[RTF2Text]( NULL )
SELECT dbo.[RTF2Text]( '' )
SELECT dbo.[RTF2Text]( '1' )
SELECT dbo.[RTF2Text]( 'blah' )
如果您知道在什么条件/输入值下您的功能会失败,那么在表格中检查这些是一件简单的事情。
答案 1 :(得分:0)
我也遇到类似的情况,但是对SQL函数的了解很少,但是需要剥离RTF并尝试使用此代码。调试提示此函数失败,因为我收到了无效的长度参数。
IF RIGHT(@rtf, 1) = ' '
SET @rtf = SUBSTRING(@rtf, 1, LEN(@rtf) -1);
由于我所掌握的知识最少且没有时间,因此我只是添加了一点,以确保它没有进行减法处理,即从0开始为我的数据集减-1。
IF RIGHT(@rtf, 1) = ' '
IF LEN(@rtf) > 0
SET @rtf = SUBSTRING(@rtf, 1, LEN(@rtf) -1);