2016-10-21 3 views
1

Я работаю с Microsoft SQL Server 2014. В нашем требовании используется индивидуальный отформатированный порядковый номер.SQL Server: автоматический сгенерированный пользовательский формат, порядковый номер

Формат порядкового номера: CAT-YYYY-MM-NNNNNN. Пример данных:

CAT-2016-10-000001 
CAT-2016-10-000002 
       . 
       . 
       . 
CAT-2016-10-999999 

Я не хочу использовать GUID или любой другой, и я хочу работать с процедурой или функцией.

Итак, я пытаюсь с этим:

CREATE TABLE [category] 
(
    [id] int NOT NULL UNIQUE IDENTITY, 
    [category_no] nvarchar(20) NOT NULL, 
    [category_name] nvarchar(50) NOT NULL, 
    PRIMARY KEY ([id]) 
); 

CREATE FUNCTION generate_category_no() 
RETURNS CHAR(20) 
AS 
BEGIN 
    DECLARE @category_no CHAR(20) 
    SET @category_no = (SELECT MAX(category_no) FROM category) 

    IF @category_no IS NULL 
     SET @category_no = 'CAT-' + YEAR(getDate()) + '-' + MONTH(getDate()) + '-000001' 

    DECLARE @no int 
    SET @no = RIGHT(@category_no,6) + 1 

    RETURN 'CAT-' + YEAR(getDate()) + '-' + MONTH(getDate()) + '-' + right('00000' + CONVERT(VARCHAR(10),@no),6) 
END 
GO 

ALTER TABLE category DROP COLUMN category_no; 
ALTER TABLE category ADD category_no AS dbo.generate_category_no(); 

INSERT INTO category (category_name) 
VALUES ('BMW'), ('JAGUAR'); 

Когда я запускаю выше SQL в шаг за шагом, это нормально. Это не показало ошибки. Но когда я запускаю следующую команду:

SELECT * FROM category; 

он показывает следующее сообщение об ошибке:

Msg 217, Level 16, State 1, Line 1
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).

Я не знаю, как решить эту. И даже я не знаю, что моя функция работала или нет. Я ссылаюсь из Интернета на эту функцию.

ДОБАВЛЕНО

мне нужно сбросить последовательность не за каждый месяц. Например. на следующий месяц, не должно быть:

CAT-2016-11-000001 

Прошу, просветите меня. Заранее спасибо!

+0

Что делать, если две сессии выполняются (SELECT MAX (category_no) FROM category) одновременно? Кто получает значение +1? –

+0

Вы получаете ошибку при выборе данных из таблицы или при выполнении функции или при создании функции? Существуют ли триггеры, связанные с таблицей? – Aditya

+0

Нет, в db нет триггера. Только эта функция. –

ответ

0

И наконец, я решил проблему. Моя Функция выглядеть следующим образом:

CREATE FUNCTION generate_category_no() 
RETURNS CHAR(20) 
AS 
BEGIN 
    DECLARE @category_no CHAR(20) 
    SET @category_no = (SELECT MAX(category_no) FROM category WHERE category_no LIKE CONCAT('CAT-', YEAR(getDate()), '-', MONTH(getDate()), '-%')) 
    IF @category_no is null SET @category_no = CONCAT('CAT-', YEAR(getDate()), '-', MONTH(getDate()), '-000000') 
    DECLARE @no INT 
    SET @no = RIGHT(@category_no,6) + 1 
    RETURN CONCAT('CAT-', YEAR(getDate()), '-', MONTH(getDate()), '-', RIGHT('00000' + CONVERT(VARCHAR(10),@no),6)) 
END 
GO 

И я вставить данные следующим образом:

INSERT INTO category (category_no, category_name) VALUES (dbo.generate_category_no(),'BMW'); 
INSERT INTO category (category_no, category_name) VALUES (dbo.generate_category_no(),'JAGUAR'); 

Один вещей является то, что Мы можем вызвать функцию из INSERT запроса.

Так что, когда я запускаю следующий SQL:

SELECT * FROM category; 

Это даст результат, как показано на ниже.

+---+--------------------+--------------+ 
|id |category_no   |category_name | 
+---+--------------------+--------------+ 
| 1 |CAT-2016-10-000001 | BMW   | 
| 2 |CAT-2016-10-000002 | JAGUAR  | 
+---+--------------------+--------------+ 

Спасибо всем за помощь. Благодаря!!!

1

Попробуйте это:

Чтобы инициализировать новое поле:

ALTER TABLE category DROP COLUMN category_no; 
ALTER TABLE category ADD category_no CHAR(20) 

UPDATE category set category_no = dbo.generate_category_no() 

Для другой вставки:

CREATE TRIGGER [dbo].[category_i] 
ON [dbo].[category] 
AFTER INSERT 
AS BEGIN 
    UPDATE category 
    SET category_no = dbo.generate_category_no() 
    FROM inserted 
    WHERE category.pk = inserted.pk 
END 

Но вы можете попробовать использовать SEQUENCE функцию, доступную на Sql Server 2012 версия

О SEQUENCE вы можете увидеть here

+0

Я просто подтверждаю ваш ответ, потому что триггер не моя цель. И ваш ответ прав в одном направлении. Но я просто хочу использовать функцию в столбце. Теперь я понял. Благодарю. –

+1

@NaingWinHtun: Привет, дорогая, благодарю вас за ваше продвижение. Очевидно, что вы согласны с тем, что ответ достиг вашей цели, поэтому правильно, что вы приняли ваши;) Хороший день –

1

Самый большой недостаток в функции он не будет работать для Batch Insert-х

Поскольку вы ID автогенерируемая, вот простой способ сделать это

category_no AS Concat('CAT-', Year(Getdate()), '-', Month(Getdate()), '-', RIGHT(Concat('00000', id), 6)) 

Demo

CREATE TABLE #seq 
    (
    id INT IDENTITY(1, 1), 
    name VARCHAR(10), 
    category_no AS Concat('CAT-', Year(Getdate()), '-', Month(Getdate()), '-', RIGHT(Concat('00000', id), 6)) 
) 

INSERT INTO #seq 
      (name) 
VALUES  ('val') 

Результат:

id name category_no 
-- ---- ----------- 
1 val  CAT-2016-10-000001 
2

Измените функцию, как показано ниже

ALTER TABLE category DROP COLUMN category_no; 

alter FUNCTION dbo.generate_category_no(@id int) 
RETURNS CHAR(20) 
AS 
BEGIN 

    RETURN 'CAT-' + cast(YEAR(getDate()) as varchar(10)) + '-' + cast(MONTH(getDate()) as varchar(10))+ '-' + right('00000' + CONVERT(VARCHAR(10),@id),6) 
END 



ALTER TABLE category ADD category_no AS dbo.generate_category_no(id); 

INSERT INTO category 
(category_name) 
VALUES 
('BMW13'), 
('JAGUAR'); 

SELECT * FROM категории даст результат ниже.

1 BMW  CAT-2016-10-000001 
2 JAGUAR CAT-2016-10-000002 
3 BMW1 CAT-2016-10-000003 
4 BMW13 CAT-2016-10-000004 
+0

Хорошее решение, просто Примечание: вы связали category_no с id, поэтому, если есть пробел в пределах идентификатора, category_no также имеет такой же объем пробела. это вопрос о бизнесе или нет? –

+1

Затем попробуйте под запросом выбрать id, category_name, 'CAT-2016-10-00000' + cast (row_number() over (order by id) как varchar (10)) как catid из категории – User