D'autres réponses ici à ne pas prendre en compte si vous avez des zéros (ou même un seul zéro).
Certains mettent toujours par défaut une chaîne vide à zéro, ce qui est faux quand elle est censée rester vide.
Relisez la question initiale. Cela répond à ce que veut le questionneur.
Solution n ° 1:
--This example uses both Leading and Trailing zero's.
--Avoid losing those Trailing zero's and converting embedded spaces into more zeros.
--I added a non-whitespace character ("_") to retain trailing zero's after calling Replace().
--Simply remove the RTrim() function call if you want to preserve trailing spaces.
--If you treat zero's and empty-strings as the same thing for your application,
-- then you may skip the Case-Statement entirely and just use CN.CleanNumber .
DECLARE @WackadooNumber VarChar(50) = ' 0 0123ABC D0 '--'000'--
SELECT WN.WackadooNumber, CN.CleanNumber,
(CASE WHEN WN.WackadooNumber LIKE '%0%' AND CN.CleanNumber = '' THEN '0' ELSE CN.CleanNumber END)[AllowZero]
FROM (SELECT @WackadooNumber[WackadooNumber]) AS WN
OUTER APPLY (SELECT RTRIM(RIGHT(WN.WackadooNumber, LEN(LTRIM(REPLACE(WN.WackadooNumber + '_', '0', ' '))) - 1))[CleanNumber]) AS CN
--Result: "123ABC D0"
Solution n ° 2 (avec des exemples de données):
SELECT O.Type, O.Value, Parsed.Value[WrongValue],
(CASE WHEN CHARINDEX('0', T.Value) > 0--If there's at least one zero.
AND LEN(Parsed.Value) = 0--And the trimmed length is zero.
THEN '0' ELSE Parsed.Value END)[FinalValue],
(CASE WHEN CHARINDEX('0', T.Value) > 0--If there's at least one zero.
AND LEN(Parsed.TrimmedValue) = 0--And the trimmed length is zero.
THEN '0' ELSE LTRIM(RTRIM(Parsed.TrimmedValue)) END)[FinalTrimmedValue]
FROM
(
VALUES ('Null', NULL), ('EmptyString', ''),
('Zero', '0'), ('Zero', '0000'), ('Zero', '000.000'),
('Spaces', ' 0 A B C '), ('Number', '000123'),
('AlphaNum', '000ABC123'), ('NoZero', 'NoZerosHere')
) AS O(Type, Value)--O is for Original.
CROSS APPLY
( --This Step is Optional. Use if you also want to remove leading spaces.
SELECT LTRIM(RTRIM(O.Value))[Value]
) AS T--T is for Trimmed.
CROSS APPLY
( --From @CadeRoux's Post.
SELECT SUBSTRING(O.Value, PATINDEX('%[^0]%', O.Value + '.'), LEN(O.Value))[Value],
SUBSTRING(T.Value, PATINDEX('%[^0]%', T.Value + '.'), LEN(T.Value))[TrimmedValue]
) AS Parsed
Résultats:
Résumé:
Vous pouvez utiliser ce que j'ai ci-dessus pour une suppression ponctuelle des zéro non significatifs.
Si vous prévoyez de le réutiliser beaucoup, placez-le dans un Inline-Table-Valued-Function (ITVF).
Vos préoccupations concernant les problèmes de performance avec les UDF sont compréhensibles.
Toutefois, ce problème s'applique uniquement à All-Scalar-Functions et Multi-Statement-Table-Functions.
Utiliser ITVF est parfaitement bien.
J'ai le même problème avec notre base de données tierce.
Avec les champs alphanumériques, beaucoup sont entrés sans les espaces principaux, dang humains!
Cela rend les jointures impossibles sans nettoyer les zéros de tête manquants.
Conclusion:
Au lieu de supprimer les zéros non significatifs, vous pouvez envisager de simplement compléter vos valeurs découpées avec des zéros non significatifs lorsque vous effectuez vos jointures.
Mieux encore, nettoyez vos données dans le tableau en ajoutant des zéros non significatifs, puis en reconstruisant vos index.
Je pense que ce serait bien plus rapide et moins complexe.
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF(' 0A10 ', ''))), 10)--0000000A10
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF('', ''))), 10)--NULL --When Blank.