Andere Antworten hier nicht zu berücksichtigen, wenn Sie alle Nullen (oder sogar eine einzelne Null) haben.
Einige setzen eine leere Zeichenfolge standardmäßig auf Null, was falsch ist, wenn sie leer bleiben soll.
Lesen Sie die ursprüngliche Frage erneut. Dies beantwortet, was der Fragesteller will.
Lösung 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"
Lösung Nr. 2 (mit Beispieldaten):
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
Ergebnisse:
Zusammenfassung:
Sie könnten das, was ich oben habe, für eine einmalige Entfernung von führenden Nullen verwenden.
Wenn Sie vorhaben, es häufig wiederzuverwenden, platzieren Sie es in einer Inline-Table-Valued-Funktion (ITVF).
Ihre Bedenken hinsichtlich Leistungsproblemen mit UDFs sind verständlich.
Dieses Problem gilt jedoch nur für All-Scalar-Funktionen und Multi-Statement-Table-Funktionen.
Die Verwendung von ITVFs ist vollkommen in Ordnung.
Ich habe das gleiche Problem mit unserer Datenbank von Drittanbietern.
Mit alphanumerischen Feldern werden viele ohne die führenden Leerzeichen eingegeben, verdammte Menschen!
Dies macht Verknüpfungen unmöglich, ohne die fehlenden führenden Nullen zu bereinigen.
Fazit:
Anstatt die führenden Nullen zu entfernen, sollten Sie Ihre abgeschnittenen Werte bei Ihren Verknüpfungen nur mit führenden Nullen auffüllen.
Besser noch, bereinigen Sie Ihre Daten in der Tabelle, indem Sie führende Nullen hinzufügen und dann Ihre Indizes neu erstellen.
Ich denke, das wäre viel schneller und weniger komplex.
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF(' 0A10 ', ''))), 10)--0000000A10
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF('', ''))), 10)--NULL --When Blank.