SQL 服务器:自动生成的自定义格式序列号
SQL Server: auto-generated custom format sequence number
我正在使用 Microsoft SQL Server 2014。在我们的要求中,包含自定义格式的序列号。
序号格式为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一步步的时候,就OK了。它没有显示错误。但是当我 运行 以下命令时:
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
请赐教。提前致谢!
试试这个:
要初始化您的新字段:
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
功能,2012 版 Sql 服务器上可用
大约SEQUENCE
可以看到here
你的函数最大的缺陷是它不适用于批量插入的
由于您 ID
是自动生成的,这里有一个更简单的方法
category_no AS Concat('CAT-', Year(Getdate()), '-', Month(Getdate()), '-', RIGHT(Concat('00000', id), 6))
演示
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
修改你的函数如下
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
最后,我解决了这个问题。我的 函数 如下所示:
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 |
+---+--------------------+--------------+
感谢大家对我的帮助。谢谢!!!
我正在使用 Microsoft SQL Server 2014。在我们的要求中,包含自定义格式的序列号。
序号格式为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一步步的时候,就OK了。它没有显示错误。但是当我 运行 以下命令时:
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
请赐教。提前致谢!
试试这个:
要初始化您的新字段:
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
功能,2012 版 Sql 服务器上可用
大约SEQUENCE
可以看到here
你的函数最大的缺陷是它不适用于批量插入的
由于您 ID
是自动生成的,这里有一个更简单的方法
category_no AS Concat('CAT-', Year(Getdate()), '-', Month(Getdate()), '-', RIGHT(Concat('00000', id), 6))
演示
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
修改你的函数如下
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
最后,我解决了这个问题。我的 函数 如下所示:
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 |
+---+--------------------+--------------+
感谢大家对我的帮助。谢谢!!!