Інші відповіді тут не враховуються, якщо у вас є всі нулі (або навіть один нуль).
Деякі завжди за замовчуванням порожній рядок дорівнює нулю, що неправильно, коли він повинен залишатися порожнім.
Перечитайте оригінальне запитання. Це відповідає тому, що хоче запитувач.
Рішення №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"
Рішення №2 (із зразками даних):
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
Результати:
Підсумок:
Ви можете використати те, що я маю вище, для одноразового видалення "нульових".
Якщо ви плануєте багаторазово використовувати його, розмістіть його у функції вбудованої таблиці з оцінкою (ITVF).
Ваші занепокоєння щодо проблем з ефективністю UDF зрозумілі.
Однак ця проблема стосується лише всіх скалярних функцій та функцій багатосторонніх таблиць.
Використання ITVF - це цілком чудово.
У мене така ж проблема з нашою базою даних сторонніх організацій.
З Альфа-числовими полями багато хто вводиться без провідних просторів, бовтайте людей!
Це робить приєднання неможливим без очищення пропущених нульових нулів.
Висновок:
Замість того, щоб видаляти провідні нулі, можливо, ви захочете розглянути можливість заміщення обрізаних значень лідерами, коли ви приєднуєтесь.
Ще краще, очистіть свої дані в таблиці, додавши провідні нулі, а потім відновіть свої індекси.
Я думаю, це було б ШЛЯХО швидше і менш складним.
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF(' 0A10 ', ''))), 10)--0000000A10
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF('', ''))), 10)--NULL --When Blank.