Увеличение буквенно-цифрового значения в определяемой пользователем функции
-
13-09-2019 - |
Вопрос
Я пытаюсь закодировать пользовательскую функцию в SQL Server 2005, которая будет увеличивать целую часть буквенно-цифрового значения на единицу.Например, uf_AlphanumericIncrease ('A000299')
должен вернуть «A000300».Вот что я сделал на данный момент;
ALTER FUNCTION uf_AlphaNumericIncrement
(
@ID varchar(10)
)
RETURNS VARCHAR(10) AS
BEGIN
DECLARE @RES varchar(10);
IF SUBSTRING(@ID,LEN(@ID),1)='9'
SET @RES=SUBSTRING(@ID,1,LEN(@ID)-2)+CAST (CAST(SUBSTRING(@ID,LEN(@ID)-1,1) AS smallint)+1 AS VARCHAR(10))+'0';
ELSE
SET @RES=SUBSTRING(@ID,1,LEN(@ID)-1)+CAST (CAST(SUBSTRING(@ID,LEN(@ID),1) AS smallint)+1 AS VARCHAR(10));
RETURN @RES;
END
Но, как вы можете видеть, это работает только для последней цифры.Мне нужно запустить его в цикл, чтобы он мог работать с A002999 и так далее.Есть идеи?
Редактировать:Данное значение может иметь альфа-префикс длиннее одного символа или вообще не иметь его.
Решение
Теперь работает с любой длиной префикса и части номера (до 20 штук).
DECLARE @prefix varchar(20), @numberstr varchar(20), @number int, @Val varchar(40)
SELECT @Val = 'ABCD000006'
--SELECT @Val = 'A03'
SELECT @prefix = LEFT(@Val, PATINDEX ('%[0-9]%', @Val) -1)
SELECT @numberstr = SUBSTRING(@Val, PATINDEX ('%[0-9]%', @Val), 8000)
SELECT @number = CAST(@numberstr AS int) + 1
SELECT @prefix + RIGHT(REPLACE(SPACE(LEN(@numberstr)), ' ', '0') + CAST(@number AS varchar(20)), LEN(@numberstr))
Другие советы
CREATE FUNCTION dbo.uf_ANinc
(
@in varchar(10)
)
RETURNS varchar(10) AS
BEGIN
DECLARE @prefix varchar(10);
DECLARE @res varchar(10);
DECLARE @pad varchar(10);
DECLARE @num int;
DECLARE @start int;
SET @start = PATINDEX('%[0-9]%',@in);
SET @prefix = LEFT(@in, @start - 1 );
SET @num = CAST( RIGHT( @in, LEN(@in) - @start ) AS int ) + 1
SET @pad = REPLICATE( '0', 10 - LEN(@prefix) - CEILING(LOG(@num)/LOG(10)) );
SET @res = @prefix + @pad + CAST( @num AS varchar);
RETURN @res
END
GO
SELECT dbo.uf_ANinc('ABC000123');
Предполагая, что альфа-часть вашего буквенно-цифрового символа всегда является только первым символом, это должно работать.
РЕДАКТИРОВАТЬ:Хорошо, если альфа-часть различается по длине, для UDF это довольно быстро становится некрасивым.Это всего лишь быстрое решение, поэтому его, вероятно, можно немного оптимизировать, но логика должна быть здравой.
РЕДАКТИРОВАТЬ СНОВА:Patindex() ftw — сегодня я узнал кое-что новое ;-)
ALTER FUNCTION uf_AlphaNumericIncrement
(
@ID varchar(10)
)
RETURNS VARCHAR(10) AS
BEGIN
DECLARE @RES varchar(10);
DECLARE @num int;
DECLARE @prefix varchar(10);
set @prefix = left(@id, patindex('%[0-9]%', @id) -1)
set @num = cast(right(@id, len(@id) - len(@prefix)) as int) + 1
set @res = @prefix + replicate('0', len(@id) - len(@prefix) - len(@num)) + cast(@num as varchar(10))
RETURN @RES;
END