2009-06-12 5 views
2

Я пытаюсь закодировать пользовательскую функцию в 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 и так далее. Есть идеи?

Редактировать: данное значение может иметь альфа-префикс длиннее одного символа или вообще отсутствует.

+0

у меня нет никакого решения для вас, но мне любопытно, и это может помочь тем, отвечая на ваш вопрос, к чему вы хотели бы увеличить A99. (A100 - очевидный ответ, но можете ли вы иметь дело с дополнительной цифрой?) –

+0

Дополнительная цифра в порядке, когда предел достигнут. В этом случае A100 - это то, что делает мой интерфейс GUI - мне нужно это под UDF, потому что я кодирую триггер, который будет добавлять данные. –

+0

Является ли альфа-часть всегда одним символом или функция должна обрабатывать больше (например, «AB001» => «AB002»)? – Joe

ответ

4

В настоящее время работает с любой длиной префикса и номер части (а Шифрование до 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)) 
+0

Длина префикса может отличаться. Как ARD0001. Как вы определили длину префикса? –

+1

Используйте PATINDEX, чтобы найти первое число. Ответ обновлен – gbn

+0

Отлично работает, я изменил статический '6' на LEN (@Val) -LEN (@prefix) до NewWal в вашем предыдущем решении, но это тоже работает. Большое спасибо. –

2

Если предположить, что альфа-часть вашего буквенно-цифровой всегда только первый символ, это должно работать.

EDIT: ОК, если альфа-часть меняется по длине, это довольно быстро уродливо для UDF. Это просто быстрое и грязное решение, поэтому его можно немного оптимизировать, но логика должна быть надежной.

EDIT СНОВА: 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 
+0

Я должен был задать вопрос о альфа-части на первом месте, поэтому я сейчас ее отредактировал. –

2
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'); 

 Смежные вопросы

  • Нет связанных вопросов^_^