SQL子查询删除前导零

时间:2018-05-02 15:09:15

标签: sql-server

我创建了一个返回表的函数。该表有两列,PostalCode Nvarchar(255)和Passed Bit。当我直接调用它时,该功能正常工作:

SELECT PostalCode FROM fnPostalCodeFormatCheck('FR','68',1,2)

输出:00068

如果邮政编码需要前导零,如欧洲邮政编码那样,这个功能就是这样,它会把它们放在那里。

现在,当我在带有另一个表的子查询中使用此函数以查看当前系统中的每个邮政编码时,将删除前导零。例如:

SELECT 
(SELECT PFC.PostalCode 
 FROM fnPostalCodeFormatCheck (RT.OriginCounty,RT.OriginZip,RT.CustomerID,RT.WorldRegionID) PFC
) [CorrectCode]
,RT.OriginCountry
,RT.OriginZip
,RT.CustomerID
,RT.WorldRegionID
FROM dbo.tr_tblRateTemplates RT
INNER JOIN dbo.tdw_qryPostalCodeRule PCRO
ON PCRO.WorldRegionID = RT.WorldRegionID
AND PCRO.ShipperID = RT.CustomerID
AND PCRO.CountryCode = RT.OriginCountry
WHERE RT.CustomerID=1
AND RT.WorldRegionID=2
AND OriginZip IS NOT NULL
AND OriginCountry <>'ES'

输出:

CorrectCode,OriginCountry,OriginZip,CustomerID,WorldRegionID
7884,       DK,           7884,     1,         2
68,         FR,           68,       1,         2

函数中的数据类型为nvarchar(255),为什么要更改此值?

功能:

ALTER FUNCTION [fnPostalCodeFormatCheck]
(@Country AS NVARCHAR(255)
,@PostalCode AS NVARCHAR(255)
,@ShipperID AS INT
,@WorldRegionID AS int) 
RETURNS @rtnTable TABLE (PostalCode nvarchar(255), Passed BIT)
AS
BEGIN
    /*
    341 SCHED_JOB_ALCOA_EU@alcoa.com
    340 SCHED_JOB_ALCOA_NA@alcoa.com
    792 SCHED_JOB_ARCONIC_NA@arconic.com
    */

    --Local variables
    IF NOT EXISTS(SELECT TOP 1 CountryCode FROM dbo.tdw_qryPostalCodeRule
                    WHERE CountryCode=@Country
                    AND WorldRegionID=@WorldRegionID
                    AND ShipperID=@ShipperID)
        BEGIN
            --Just leave. There is nothing to evaluate
            INSERT INTO @rtnTable(PostalCode, Passed) Values( @PostalCode, 1)
            RETURN 
        END


    /*
    Column like '%-%-%' there cannot be two dashes
    Column not like '%[0-9]-[0-9]%' there must a be a digit to the left and right of the dash
    Column not like %[-/@#$%&*()%^a-zA-Z]% can not have these special characters and must have numbers only
    */

    DECLARE @Compare AS NVARCHAR(255) --this is the must have format
    DECLARE @Compare2 AS NVARCHAR(255) --This is the MUST NOT have format

    SELECT 
    @PostalCode=RIGHT(REPLICATE('0',(CASE WHEN LEN(@PostalCode)>Maximum THEN LEN(@PostalCode) ELSE Maximum END)) 
    + CONVERT(VARCHAR(255), @PostalCode), (CASE WHEN LEN(@PostalCode)>Maximum THEN LEN(@PostalCode) ELSE Maximum END))
    ,@Compare= 
    (CASE WHEN SpecialCharacter IS NOT NULL THEN  
            (CASE WHEN NumericOnly=1 THEN 
                REPLICATE('['+ SpecialCharacter + '0-9]' ,Maximum)
            ELSE 
                '%[' + SpecialCharacter + 'a-zA-Z0-9]' 
            END)  
        ELSE 
            (CASE WHEN NumericOnly=1 THEN 
                            REPLICATE('[0-9]',Maximum)
            ELSE 
                '' 
            END)
        END)
    ,@Compare2='%[' 
        + REPLACE('- /@#$%&*()%',ISNULL(SpecialCharacter,''),'')
        + (CASE WHEN NumericOnly=1 THEN '^a-zA-Z' ELSE '' END)
        + ']%'
    FROM dbo.tdw_qryPostalCodeRule
    WHERE CountryCode=@Country
    AND WorldRegionID=@WorldRegionID
    AND ShipperID=@ShipperID

    SET @Compare=dbo.fnCheckNvarcharValue(@Compare)
    SET @Compare2=dbo.fnCheckNvarcharValue(@Compare2)
    IF @Compare IS NOT NULL
        SET @Compare=@Compare + (CASE WHEN LEFT(@Compare,1)='%' THEN '%' ELSE '' END)

    --%[.,/-@#$&*()]%

    IF @Compare IS NOT NULL
        BEGIN
            IF @PostalCode COLLATE Latin1_General_BIN LIKE @Compare 
                BEGIN 
                    IF @Compare2 IS NULL 
                        BEGIN 
                            --'PASS' 
                            --SELECT 'Pass1',@Country,@PostalCode,@Compare,@Compare2,@UserID,@WorldRegionID,@ShipperID
                            INSERT INTO @rtnTable(PostalCode, Passed) Values( @PostalCode, 1)
                            RETURN 
                        END
                    ELSE
                        BEGIN
                            IF @PostalCode NOT LIKE @Compare2 
                                BEGIN
                                    --SELECT 'Pass 2',@Country,@PostalCode,@Compare,@Compare2,@UserID,@WorldRegionID,@ShipperID
                                    INSERT INTO @rtnTable(PostalCode, Passed) Values( @PostalCode, 1)
                                    RETURN 
                                END
                            ELSE
                                BEGIN
                                    --'FAILED'
                                    --SELECT 'Failed 1',@Country,@PostalCode,@Compare,@Compare2,@UserID,@WorldRegionID,@ShipperID
                                    INSERT INTO @rtnTable(PostalCode, Passed) Values( @PostalCode, 0)
                                    RETURN 
                                END
                        END
                END
            ELSE 
                BEGIN
                    --'FAIL' 
                    --SELECT 'Failed 2',@Country,@PostalCode,@Compare,@Compare2,@UserID,@WorldRegionID,@ShipperID
                    INSERT INTO @rtnTable(PostalCode, Passed) Values( @PostalCode, 0)
                    RETURN 
                END
                --,@PostalCode,@Compare,@Compare2
        END
    ELSE
        BEGIN
            --SELECT 'PASS',@WorldRegionID,@ShipperID --We don't care
            --SELECT 'Pass 3',@Country,@PostalCode,@Compare,@Compare2,@UserID,@WorldRegionID,@ShipperID
            INSERT INTO @rtnTable(PostalCode, Passed) Values( @PostalCode, 1)
            RETURN
        END
    RETURN
END

规则表的数据如下: COUNTRYCODE,最小值,最大值,NumericOnly,SpecialCharacter,WorldRegionID,ShipperID FR 5 5 1 NULL 2 1

这意味着法国(FR)必须有5个字符,仅限数字,不允许特殊字符,以及此规则的WorldRegion和Shipper。

1 个答案:

答案 0 :(得分:-1)

由于看起来您正在寻找邮政编码,因此它们的长度始终相同。您可以使用以下代码:SELECT Right('00000' + [PostalCodeColumn], 5) AS PostCode