2010-07-12 62 views
8

我必须处理的电话号码,如澳大利亚+6161001161国家代码下面的代码等等,我有我不能再插入任何CASE声明中所说的问题: CASE WHEN LEFT(@BPartyNo, 4) = '+610'Case表达式只能嵌套10级

它说,Case表达式只能嵌套到10级

如何简化这个TSQL这样我就可以把更多的案例?

USE [TelcoStage_PROD] 
GO 
/****** Object: UserDefinedFunction [dbo].[ufn_stg_ProperBPartyNoExtra] Script Date: 07/12/2010 15:27:52 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

--===================================================================================================================== 
-- OBJECT NAME   : dbo.ufn_stg_ProperBPartyNoExtra 
-- INPUTS    : @BPartyNo 
-- OUTPUTS    : VARCHAR(32) 
-- RETURN CODES   : N/A 
-- DEPENDENCIES   : N/A 
-- DESCRIPTION   : This function is used to get the extra after 10 character (MNET or S) 
-- 
-- EXAMPLES (optional) : N/A 
-- 
-- HISTORY: 
-- #----------------------------------------------------------------------------------------------------------------- 
-- # DATE  | VERSION  | MODIFIED BY | DESCRIPTION 
-- #----------------------------------------------------------------------------------------------------------------- 
==================================================================================================================== 


ALTER FUNCTION [dbo].[ufn_stg_ProperBPartyNoExtra](@BPartyNo AS VARCHAR(MAX))RETURNS VARCHAR(32) 
AS 
BEGIN 
    DECLARE @Return VARCHAR(32); 

    SET @Return = ''; 

    IF (LEN(@BPartyNo) > 0) 
     SELECT @Return = CASE WHEN LEFT(@BPartyNo, 4) = '+610' THEN SUBSTRING('0' + SUBSTRING(@BPartyNo, 5, LEN(@BPartyNo)), 11, LEN('0' + SUBSTRING(@BPartyNo, 5, LEN(@BPartyNo)))) ELSE 
            CASE WHEN LEFT(@BPartyNo, 3) = '+61' THEN SUBSTRING('0' + SUBSTRING(@BPartyNo, 4, LEN(@BPartyNo)), 11, LEN('0' + SUBSTRING(@BPartyNo, 4, LEN(@BPartyNo)))) ELSE 
             CASE WHEN LEFT(@BPartyNo, 2) = '61' THEN SUBSTRING('0' + SUBSTRING(@BPartyNo, 3, LEN(@BPartyNo)), 11, LEN('0' + SUBSTRING(@BPartyNo, 3, LEN(@BPartyNo)))) ELSE  
              CASE WHEN LEFT(@BPartyNo, 6) = '001161' THEN SUBSTRING('0' + SUBSTRING(@BPartyNo, 7, LEN(@BPartyNo)), 11, LEN('0' + SUBSTRING(@BPartyNo, 7, LEN(@BPartyNo)))) ELSE 
               CASE WHEN (LEFT(@BPartyNo,2) = '01' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) ELSE 
                CASE WHEN (LEFT(@BPartyNo,2) = '02' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) ELSE 
                 CASE WHEN (LEFT(@BPartyNo,2) = '03' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) ELSE 
                  CASE WHEN (LEFT(@BPartyNo,2) = '04' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) ELSE 
                   CASE WHEN (LEFT(@BPartyNo,2) = '07' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) ELSE 
                    CASE WHEN (LEFT(@BPartyNo,2) = '08' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) ELSE '' END 
                   END 
                  END 
                 END 
                END 
               END 
              END 
             END 
            END 
         END; 
    ELSE 
     SELECT @Return = ''; 

    RETURN @Return 
END 

回答

12

他们并不需要在所有嵌套:

SELECT @Return = CASE WHEN LEFT(@BPartyNo, 4) = '+610' THEN SUBSTRING('0' + SUBSTRING(@BPartyNo, 5, LEN(@BPartyNo)), 11, LEN('0' + SUBSTRING(@BPartyNo, 5, LEN(@BPartyNo)))) 
         WHEN LEFT(@BPartyNo, 3) = '+61' THEN SUBSTRING('0' + SUBSTRING(@BPartyNo, 4, LEN(@BPartyNo)), 11, LEN('0' + SUBSTRING(@BPartyNo, 4, LEN(@BPartyNo)))) 
         WHEN LEFT(@BPartyNo, 2) = '61' THEN SUBSTRING('0' + SUBSTRING(@BPartyNo, 3, LEN(@BPartyNo)), 11, LEN('0' + SUBSTRING(@BPartyNo, 3, LEN(@BPartyNo)))) 
         WHEN LEFT(@BPartyNo, 6) = '001161' THEN SUBSTRING('0' + SUBSTRING(@BPartyNo, 7, LEN(@BPartyNo)), 11, LEN('0' + SUBSTRING(@BPartyNo, 7, LEN(@BPartyNo)))) 
         WHEN (LEFT(@BPartyNo,2) = '01' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) 
         WHEN (LEFT(@BPartyNo,2) = '02' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) 
         WHEN (LEFT(@BPartyNo,2) = '03' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) 
         WHEN (LEFT(@BPartyNo,2) = '04' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) 
         WHEN (LEFT(@BPartyNo,2) = '07' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) 
         WHEN (LEFT(@BPartyNo,2) = '08' AND LEN(@BPartyNo) > 10) THEN SUBSTRING(@BPartyNo, 11, LEN(@BPartyNo)) 
         ELSE '' 
        END 

就个人而言,我会重组你的代码,以确保数据在输入消毒,而不是试图消毒它(现在显然已经太晚了......)。或者至少用你的客户端语言进行转换(即在中调用这个sproc),希望它比T-SQL更适合字符串操作的任务。

+0

'codeka'哈丁:谢谢你。没有意识到我没有嵌套。我必须在这个级别上进行字符串操作,因为客户端实际上是SQL以及哪个ETL进程。 – dcpartners 2010-07-12 06:15:34

+0

@ dewacorp.alliances:ouch :-) – 2010-07-12 06:18:34

9

你不需要嵌套case语句,你可以有很多WHEN ... THEN

CASE WHEN @x = 1 THEN 1 WHEN @x = 2 THEN 2 WHEN @x = 3 THEN 3 ELSE 4 END 
0

这是嵌套案例场景的解决方法,不建议使用。让你的第一个9个案例在一个Coalesce中,然后用一个else null结束它,并将下一个案例放在下一个块中。

COALESCE ((CASE WHEN TRY1 = 1 THEN TRY1  
ELSE CASE WHEN TRY2 = 1 THEN TRY2 
ELSE CASE WHEN TRY3 = 1 THEN TRY3 
ELSE NULL END END 
END), 

CASE WHEN TRY11 = 1 THEN TRY11 
ELSE CASE WHEN TRY12 = 1 THEN TRY12 
ELSE CASE WHEN TRY13 = 1 THEN TRY13 
ELSE NULL END END END 
),0) AS MyValue