重构 - 两条可怕的线条

时间:2012-02-28 05:58:14

标签: sql sql-server sql-server-2008 tsql

我一直在研究一个存储过程并且遇到了两条非常可怕的线路。有没有办法在存储过程中以更清晰的方式重写它?如果没有,我将如何创建一个函数来执行此操作?

, REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(l.tenant_trading_name,'~','-'), '"','-'), '#','-'), '%','-'), '*','-'), ':','-'), '<','-'), '>','-'), '?','-'), '/','-'), '\','-'), '{','-'), '|','-'), '}','-') as trading_name
    ,   REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(l.suite_name,'&','-'), '~','-'), '"','-'), '#','-'), '%','-'), '*','-'), ':','-'), '<','-'), '>','-'), '?','-'), '/','-'), '\','-'), '{','-'), '|','-'), '}','-') as suite_name

2 个答案:

答案 0 :(得分:2)

嗯,你可以简单地拥有一个为你做脏工作的功能:

CREATE FUNCTION dbo.CleanCharacters
(
  @InputString VARCHAR(64),
  @UseAmp BIT
)
RETURNS VARCHAR(64)
AS
BEGIN
  RETURN(SELECT REPLACE(REPLACE(REPLACE(...REPLACE(
      @InputString, CASE WHEN @UseAmp = 1 THEN '&' ELSE '-' END, '-'),
      '~', '')...etc etc...)))
  );
END
GO

然后你可以说:

SELECT dbo.CleanCharacters(l.tenant_trading_name, 0),
dbo.CleanCharacters(l.suite_name, 1) FROM ...

这至少将丑陋的REPLACE()调用抽象出来。

(请注意,我并没有完全解析整行,看看是否存在其他差异,但在我看来,唯一的区别是suite_name没有&amp;但是交易名称可以。)

另一种方法是将“坏”字符存储在表格中,使这些替换品的维护更容易一些(一旦填充表格,使功能更加清晰)。

CREATE TABLE dbo.DirtyCharacters(x CHAR(1));

INSERT dbo.DirtyCharacters SELECT '~' 
  UNION ALL SELECT '&' 
  UNION ALL SELECT '*'
-- ...
;

现在你可以让你的功能简单地说:

ALTER FUNCTION dbo.CleanCharacters
(
  @InputString VARCHAR(64),
  @UseAmp BIT
)
RETURNS VARCHAR(64)
AS
BEGIN
  SELECT @InputString = REPLACE(@InputString, x, '-')
    FROM dbo.DirtyCharacters 
    WHERE x <> CASE WHEN @UseAmp = 1 THEN '' ELSE '&' END;

  RETURN (@InputString);
END
GO

答案 1 :(得分:0)

例如,它适用于您的第一个字符串。

 SELECT @Str = REPLACE( @Str , chr , '-' )
      FROM ( SELECT '~' UNION 
         SELECT '"' UNION 
         SELECT '#' UNION
              SELECT '%' UNION 
              SELECT '*' UNION 
              SELECT ':' UNION
              SELECT '<' UNION  
              SELECT '>' UNION  
              SELECT '?' UNION  
              SELECT '/' UNION  
              SELECT '\' UNION  
              SELECT '{' UNION  
              SELECT '|' UNION  
              SELECT '}' UNION  
              SELECT '%' ) D ( chr )
     WHERE CHARINDEX( chr , @Str ) > 0 ;
    SELECT @str ;