2017-02-21 118 views
0

我需要編寫一個函數,從varchar列中刪除所有前導零。例如:0300必須變爲300,A0300必須變成A300。第一個退出容易,但我不能得到第二個工作(A0300-> A300)。任何人都可以將我指向正確的方向嗎?Leftrimming Zero與字符串中包含的字符與字符

+0

總是以字母'A'開頭還是它可能是字符串的不同長度? –

+0

它可以是任何字符或多個字母,如ABC0150 – ImperialBert

+0

所以''zer0''應該變成''zer''和''0''應該變成'''''? – HABO

回答

1
WITH test AS 
(
    SELECT 'A0300' AS code 
    UNION 
    SELECT '0300' 
), 
strip AS (
SELECT code, SUBSTRING(code, PATINDEX('%[0-9]%', code), LEN(code)) AS number 
from test 
) 

select REPLACE(code, number, CAST(number as INT)) 
FROM strip 
0

在舊版本,其中PATINDEX不起作用,或者如果PATINDEX太慢:

做的情況下,並使用LIKE '[0-9]'/ NOT LIKE '[0-9]'找到正確的分裂點 - 假設知道您的字符串的最大長度,以便您可以根據需要準備多個案例。 您可以在數字開頭找到正確的字符編號,並將右邊的部分作爲INT進行轉義以消除前導0,然後將結果作爲VARCHAR進行轉換,以重新彙總您的前導字母。

會製造類似如下: 選擇 CASE WHEN LEFT(列名,1)NOT LIKE '[0-9]' 和substring(列名,2,1)LIKE '[0-9]' 然後離開( (列名,2)(LEN(columnname)-2))AS INT)AS VARCHAR(25)) 當左(列名,2)不像'[0-9]'和底層(columnname,3,1).... END

如果您不確定前導/尾隨空格,您應該用LTRIM(RTRIM(columnname))修剪空格,因爲我們要計算字符可能更可靠。

0

下面的潰爛代碼演示了一種方式,用一個平凡的狀態機遍歷字符串,並解析出邪惡的零。要查看內部發生了什麼,可以在CTE之後切換select

-- Sample data. 
declare @Samples as Table (SampleId Int Identity, Sample VarChar(100)); 
insert into @Samples (Sample) values 
    ('0300'), ('A0300'), ('zer0'), ('0'), ('000'), ('00000Q050098'); 
select * from @Samples; 

-- Fiendish thingy. 
declare @False as Bit = 0, @True as Bit = 1; 
with 
    Characters as (
    select SampleId, Sample, 1 as Position, Substring(Sample, 1, 1) as Character, 
     case when Substring(Sample, 1, 1) = '0' then @True else @False end as IsZero, 
     case when Substring(Sample, 1, 1) = '0' then @True else @False end as FirstZeroes 
     from @Samples 
    union all 
    select SampleId, Sample, Position + 1, Substring(Sample, Position + 1, 1), 
     case when Substring(Sample, Position + 1, 1) = '0' then @True else @False end, 
     case 
     when FirstZeroes is NULL then NULL -- We're done with this string. 
     when FirstZeroes = @True and Substring(Sample, Position + 1, 1) <> '0' then NULL -- We just finished with this string. 
     when Substring(Sample, Position + 1, 1) = '0' then @True -- We're (still) going with this string. 
     else @False end 
     from Characters 
     where Position < Len(Sample)) 
-- select * from Characters order by SampleId, Position; -- Use this statement to see the intermediate results. 
    select C.SampleId, C.Sample, 
    Coalesce(Stuff((select Character from Characters where SampleId = C.SampleId and (FirstZeroes = 0 or FirstZeroes is NULL) order by Position for XML path(''), type).value('.[1]', 'VarChar(max)'), 1, 0, ''), '') as DeZeroed 
    from Characters as C 
    group by SampleId, Sample