Số hóa đơn liên tục: vì sao IDENTITY và SEQUENCE nhảy số
Quy định về số hóa đơn điện tử từ 01/7/2026, vì sao IDENTITY và SEQUENCE để lại lỗ trong dãy số, và cách cấp số không hở bằng bảng đếm trên SQL Server.
8:30 sáng 15/9/2026, kế toán của BanHang đối chiếu dãy hóa đơn ký hiệu 1C26TBH của ngày hôm trước. Hóa đơn lập lúc 14:02 mang số 3.006.412, hóa đơn kế tiếp lúc 14:09 mang số 3.007.001: 588 số không có hóa đơn, vì 14:05 máy chủ database mất điện. Sáng hôm đó còn một chỗ hở một số, đúng lúc ký số lỗi và giao dịch ghi hóa đơn rollback. Số đang lấy từ một SEQUENCE có CACHE 1000, chép cách sinh mã đơn ở chương khóa chính. Giờ và số ở đoạn này là minh họa. Bài này đọc quy định về số hóa đơn, đo hai đường làm hở dãy số trên SQL Server 2019, và dựng cách cấp số không hở.
Đọc nhanh
- Từ 01/7/2026, theo Nghị định 254/2026/NĐ-CP, số hóa đơn tối đa 8 chữ số, bắt đầu từ 1 mỗi năm, liên tục trong cùng ký hiệu mẫu số và ký hiệu hóa đơn.
IDENTITYvàSEQUENCEmất số khi rollback và khi dừng đột ngột: đo trên LocalDB 2019, 48 số vớiSEQUENCEmặc định, 998 vớiIDENTITYkiểuint. Dừng sạch không mất số.- Bảng đếm cập nhật cùng giao dịch với
INSERThóa đơn thì không hở: qua 5 lần chạy,SEQUENCEhở 1.582 số cho 1.582 lần rollback, bảng đếm hở 0. - Cái giá là xếp hàng trên một dòng, nhưng lần đo chậm nhất vẫn gấp 7 lần nhu cầu của
BanHang. Cấp số lúc phát hành, ký số sauCOMMIT.
1. Quy định nói gì về số hóa đơn
Từ 01/7/2026, Nghị định 254/2026/NĐ-CP ngày 30/6/2026 thay Nghị định 123/2020/NĐ-CP và Nghị định 70/2025/NĐ-CP (Điều 43). Điều 10 đưa số hóa đơn vào nội dung bắt buộc, phần chi tiết ở mục 2 của Phụ lục. Điểm a:
Số hóa đơn được ghi bằng chữ số Ả-rập có tối đa 8 chữ số, bắt đầu từ số 1 vào ngày 01/01 hoặc ngày bắt đầu sử dụng hóa đơn và kết thúc vào ngày 31/12 hàng năm có tối đa đến số 99 999 999. Hóa đơn được lập theo thứ tự liên tục từ số nhỏ đến số lớn trong cùng một ký hiệu hóa đơn và ký hiệu mẫu số hóa đơn.
Câu sau của điểm a: khi nhiều cơ sở dùng chung một ký hiệu, số liên tục "theo thời điểm người bán ký số, ký điện tử trên hóa đơn". Điểm b: nếu không theo nguyên tắc trên, số phải "tăng theo thời gian" và mỗi số chỉ dùng một lần. Trước 01/7/2026, đoạn gần như giống hệt nằm ở Điều 10 khoản 3 Nghị định 123/2020/NĐ-CP; Nghị định 70/2025/NĐ-CP (Điều 1 khoản 7) sửa Điều 10 nhưng không đụng khoản 3.
Theo Phụ lục I Thông tư 91/2026/TT-BTC (hiệu lực 01/7/2026), mẫu số 1 là hóa đơn giá trị gia tăng. Ký hiệu gồm C (có mã của cơ quan thuế), hai số cuối của năm, chữ T và hai ký tự "do người bán tự xác định căn cứ theo nhu cầu quản lý". BanHang dùng 1C26TBH.
Với database: mỗi cặp mẫu số và ký hiệu một bộ đếm; năm nằm trong ký hiệu nên năm mới là dòng đếm mới, từ 0; trần 99 999 999 dư sức cho 11.700 × 365 = 4.270.500 hóa đơn mỗi năm. Một chỗ hở có vi phạm hay không là việc của kế toán thuế. Hệ thống chỉ cần không tự sinh ra chỗ hở.
2. Hai đường làm hở dãy số
Chương khóa chính đã so sánh IDENTITY với SEQUENCE. Ở đây chỉ tách hai đường hở để đo.
Đường thứ nhất: số được cấp ngoài giao dịch. Tài liệu CREATE SEQUENCE ghi số được sinh ngoài phạm vi giao dịch hiện tại và bị tiêu dù giao dịch commit hay rollback. Tài liệu IDENTITY nói tương tự và gọi đó là lựa chọn vì hiệu năng. Mỗi lần ký số lỗi làm rollback là một số mất.
Đường thứ hai: cache. Với CACHE n, engine giữ n số trong bộ nhớ và chỉ ghi mốc cuối khối xuống bảng hệ thống. Dừng sạch thì giá trị hiện tại được ghi xuống trước. Dừng đột ngột thì phần còn lại của khối mất. NO CACHE ghi xuống mỗi lần cấp. Từ SQL Server 2017, IDENTITY_CACHE = OFF tắt cache của IDENTITY cho cả database.
3. Đo trên LocalDB: mỗi lần dừng mất bao nhiêu số
Thí nghiệm dừng SQL Server nhiều lần, nên dùng một instance LocalDB riêng, KumeoSoHoaDon, chứ không dùng MSSQLLocalDB.
-- 01-tao.sql
CREATE SEQUENCE dbo.seq_MacDinh AS int START WITH 1; -- CACHE mặc định
CREATE SEQUENCE dbo.seq_Cache1000 AS int START WITH 1 CACHE 1000;
CREATE SEQUENCE dbo.seq_KhongCache AS int START WITH 1 NO CACHE;
CREATE TABLE dbo.Id_Int (So int IDENTITY(1, 1) PRIMARY KEY, Ghi char(1) NULL);
CREATE TABLE dbo.Id_Bigint (So bigint IDENTITY(1, 1) PRIMARY KEY, Ghi char(1) NULL);
-- 02-lay-so.sql: lấy một số từ mỗi bộ, in một dòng
SET NOCOUNT ON;
DECLARE @i int, @b bigint;
INSERT dbo.Id_Int (Ghi) VALUES (NULL); SET @i = SCOPE_IDENTITY();
INSERT dbo.Id_Bigint (Ghi) VALUES (NULL); SET @b = SCOPE_IDENTITY();
SELECT NEXT VALUE FOR dbo.seq_MacDinh, NEXT VALUE FOR dbo.seq_Cache1000,
NEXT VALUE FOR dbo.seq_KhongCache, @i, @b;
Script dưới lấy số, dừng instance theo ba cách rồi lấy tiếp. LocalDB tự khởi động khi có kết nối mới.
sqllocaldb create KumeoSoHoaDon 15.0
$S = "(localdb)\KumeoSoHoaDon"; $DB = "Kumeo_sohoadon"
sqlcmd -S $S -Q "CREATE DATABASE Kumeo_sohoadon; ALTER DATABASE Kumeo_sohoadon SET AUTO_CLOSE OFF;"
sqlcmd -S $S -d $DB -i 01-tao.sql
function LaySo { sqlcmd -S $S -d $DB -l 60 -i 02-lay-so.sql -W -s "," -h -1 }
LaySo; LaySo; LaySo
sqlcmd -S $S -Q "SHUTDOWN"; LaySo; LaySo # dừng sạch
sqlcmd -S $S -Q "SHUTDOWN WITH NOWAIT"; LaySo; LaySo # dừng không checkpoint
sqllocaldb stop KumeoSoHoaDon -k; LaySo; LaySo # giết tiến trình, gần như mất điện
sqlcmd -S $S -d $DB -Q "ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF;"
sqllocaldb stop KumeoSoHoaDon -k; LaySo; LaySo
sqllocaldb stop KumeoSoHoaDon -k; LaySo; LaySo
Số mất bằng số đầu tiên sau khi khởi động, trừ số cuối trước khi dừng, trừ 1. LocalDB 15.0.4382 (SQL Server 2019 CU27):
| Bộ sinh số | SHUTDOWN |
NOWAIT |
Giết | Giết, sau IDENTITY_CACHE = OFF |
Giết lần nữa |
|---|---|---|---|---|---|
SEQUENCE, CACHE mặc định |
0 | 48 | 48 | 48 | 48 |
SEQUENCE, CACHE 1000 |
0 | 998 | 998 | 998 | 998 |
SEQUENCE, NO CACHE |
0 | 0 | 0 | 0 | 0 |
IDENTITY, int |
0 | 998 | 998 | 998 | 0 |
IDENTITY, bigint |
0 | 9.998 | 9.998 | 9.998 | 0 |
Dừng đột ngột mất phần còn lại của khối: 50 số với SEQUENCE không ghi CACHE (tài liệu không cam kết kích thước này), 1.000 với IDENTITY kiểu int, 10.000 với bigint. Bật IDENTITY_CACHE = OFF xong, lần giết đầu vẫn mất khối đã giữ từ trước, lần sau thì không. Cài đặt này không đụng tới SEQUENCE.
Database mới trên LocalDB này có is_auto_close_on = 1: phiên cuối thoát là database đóng sạch, cache được ghi xuống, và lần thử đầu không thấy lỗ nào. Vì vậy script tắt AUTO_CLOSE.
4. Bảng đếm: cấp số trong cùng giao dịch
Bảng đếm giữ số cuối đã cấp của mỗi ký hiệu. Thủ tục tăng nó và ghi hóa đơn trong một giao dịch. Thủ tục SEQUENCE ở cuối chỉ để so sánh.
CREATE TABLE dbo.HoaDonDemSo (
MauSo tinyint NOT NULL, -- 1: hóa đơn giá trị gia tăng
KyHieu char(6) NOT NULL, -- C26TBH: có mã, năm 2026, loại T, hai ký tự BH
SoCuoi int NOT NULL CONSTRAINT DF_HoaDonDemSo_SoCuoi DEFAULT 0,
CONSTRAINT PK_HoaDonDemSo PRIMARY KEY CLUSTERED (MauSo, KyHieu),
CONSTRAINT CK_HoaDonDemSo_SoCuoi CHECK (SoCuoi BETWEEN 0 AND 99999999)
);
CREATE TABLE dbo.HoaDon (
MauSo tinyint NOT NULL,
KyHieu char(6) NOT NULL,
SoHoaDon int NOT NULL,
DonHangId bigint NOT NULL,
TongTien decimal(18, 2) NOT NULL,
TrangThai tinyint NOT NULL, -- 1 đã cấp số, 2 đã ký, 3 đã có mã của cơ quan thuế
CapSoLuc datetime2(3) NOT NULL CONSTRAINT DF_HoaDon_CapSoLuc DEFAULT SYSUTCDATETIME(),
CONSTRAINT PK_HoaDon PRIMARY KEY CLUSTERED (MauSo, KyHieu, SoHoaDon),
CONSTRAINT UQ_HoaDon_DonHang UNIQUE (DonHangId)
);
INSERT dbo.HoaDonDemSo (MauSo, KyHieu) VALUES (1, 'C26TBH');
GO
CREATE OR ALTER PROCEDURE dbo.usp_HoaDon_CapSo
@MauSo tinyint, @KyHieu char(6), @DonHangId bigint, @TongTien decimal(18, 2),
@SoHoaDon int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
BEGIN TRANSACTION;
UPDATE dbo.HoaDonDemSo -- khóa X trên dòng đếm, giữ đến COMMIT
SET @SoHoaDon = SoCuoi = SoCuoi + 1
WHERE MauSo = @MauSo AND KyHieu = @KyHieu;
IF @@ROWCOUNT = 0
THROW 50010, N'Ký hiệu chưa có dòng trong dbo.HoaDonDemSo.', 1;
INSERT dbo.HoaDon (MauSo, KyHieu, SoHoaDon, DonHangId, TongTien, TrangThai)
VALUES (@MauSo, @KyHieu, @SoHoaDon, @DonHangId, @TongTien, 1);
COMMIT TRANSACTION;
END;
GO
-- Bản so sánh: số lấy từ SEQUENCE với CACHE mặc định
CREATE SEQUENCE dbo.seq_HoaDon_1C26TBH AS int START WITH 1;
GO
CREATE OR ALTER PROCEDURE dbo.usp_HoaDon_CapSo_Seq
@MauSo tinyint, @KyHieu char(6), @DonHangId bigint, @TongTien decimal(18, 2),
@SoHoaDon int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
SET @SoHoaDon = NEXT VALUE FOR dbo.seq_HoaDon_1C26TBH;
INSERT dbo.HoaDon (MauSo, KyHieu, SoHoaDon, DonHangId, TongTien, TrangThai)
VALUES (@MauSo, @KyHieu, @SoHoaDon, @DonHangId, @TongTien, 1);
END;
GO
SET @SoHoaDon = SoCuoi = SoCuoi + 1 tăng cột và gán cho biến giá trị mới, không phải giá trị cũ, trong một câu. UPDATE giữ khóa X trên dòng đếm tới hết giao dịch, như cách a ở chương transaction. Phiên khác cùng ký hiệu chờ ở câu này, rollback trả SoCuoi về giá trị cũ, và số n + 1 chỉ được cấp sau khi giao dịch cầm số n kết thúc. Với SEQUENCE, số 102 có thể commit trước số 101. UQ_HoaDon_DonHang chặn ứng dụng thử lại sau timeout: lần thứ hai vi phạm ràng buộc và rollback cả lần tăng số. Hóa đơn điều chỉnh và thay thế cần khóa khác, ngoài phạm vi bài.
5. Cái giá: mọi phiên cùng ký hiệu xếp hàng
Chương trình dưới chạy N phiên gọi một trong hai thủ tục trong 5 giây. Ứng dụng mở giao dịch, gọi thủ tục, rồi commit; 2% lần rollback sau khi đã có số. Biến thể thứ hai ngủ 30 ms trước COMMIT, như gọi dịch vụ ký số khi giao dịch còn mở. Cần .NET 10 (dotnet run do-thong-luong.cs) và Microsoft.Data.SqlClient 7.1.1.
#:package Microsoft.Data.SqlClient@7.1.1
using System.Data;
using System.Diagnostics;
using Microsoft.Data.SqlClient;
const string Cs = @"Server=(localdb)\KumeoSoHoaDon;Database=Kumeo_sohoadon;Integrated Security=true;Encrypt=false";
const string WriteLog = "SELECT CAST({0} AS int) FROM sys.dm_os_wait_stats WHERE wait_type = 'WRITELOG'";
long donHangId = 0;
Console.WriteLine("thu_tuc giu_ms phien hoa_don/s tre_tb_ms writelog_ms rollback lo_hong");
foreach (int giuMs in new[] { 0, 30 })
foreach (string thuTuc in new[] { "dbo.usp_HoaDon_CapSo_Seq", "dbo.usp_HoaDon_CapSo" })
foreach (int soPhien in new[] { 1, 4, 16, 64 })
{
Sql("TRUNCATE TABLE dbo.HoaDon; UPDATE dbo.HoaDonDemSo SET SoCuoi = 0;"
+ " ALTER SEQUENCE dbo.seq_HoaDon_1C26TBH RESTART WITH 1;");
int daGhi = 0, rollback = 0, wlLan = -Sql(string.Format(WriteLog, "waiting_tasks_count")),
wlMs = -Sql(string.Format(WriteLog, "wait_time_ms"));
long tongTre = 0;
var sanSang = new Barrier(soPhien + 1);
var dongHo = new Stopwatch();
var phien = Enumerable.Range(0, soPhien).Select(p => new Thread(() =>
{
var rnd = new Random(42_000 + p);
using var conn = new SqlConnection(Cs);
conn.Open();
sanSang.SignalAndWait(); // mọi phiên đã mở kết nối mới bấm giờ
while (dongHo.ElapsedMilliseconds < 5000)
{
long batDau = dongHo.ElapsedTicks;
bool hong = rnd.NextDouble() < 0.02; // 2% lần phát hành lỗi sau khi đã có số
using var tx = conn.BeginTransaction();
using var cmd = new SqlCommand(thuTuc, conn, tx) { CommandType = CommandType.StoredProcedure };
cmd.Parameters.Add("@MauSo", SqlDbType.TinyInt).Value = 1;
cmd.Parameters.Add("@KyHieu", SqlDbType.Char, 6).Value = "C26TBH";
cmd.Parameters.Add("@DonHangId", SqlDbType.BigInt).Value = Interlocked.Increment(ref donHangId);
cmd.Parameters.Add("@TongTien", SqlDbType.Decimal).Value = 1_500_000m;
cmd.Parameters.Add("@SoHoaDon", SqlDbType.Int).Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
if (giuMs > 0) Thread.Sleep(giuMs); // gọi dịch vụ ký số khi giao dịch còn mở
if (hong) { tx.Rollback(); Interlocked.Increment(ref rollback); }
else { tx.Commit(); Interlocked.Increment(ref daGhi); }
Interlocked.Add(ref tongTre, dongHo.ElapsedTicks - batDau);
}
})).ToList();
phien.ForEach(t => t.Start());
sanSang.SignalAndWait();
dongHo.Start();
phien.ForEach(t => t.Join());
double giay = dongHo.Elapsed.TotalSeconds, treMs = tongTre * 1000.0 / Stopwatch.Frequency / (daGhi + rollback);
wlLan += Sql(string.Format(WriteLog, "waiting_tasks_count"));
wlMs += Sql(string.Format(WriteLog, "wait_time_ms"));
int soDaCap = Sql(thuTuc.EndsWith("_Seq")
? "SELECT CAST(current_value AS int) FROM sys.sequences WHERE name = 'seq_HoaDon_1C26TBH'"
: "SELECT SoCuoi FROM dbo.HoaDonDemSo WHERE MauSo = 1 AND KyHieu = 'C26TBH'");
int loHong = soDaCap - Sql("SELECT COUNT(*) FROM dbo.HoaDon");
Console.WriteLine($"{thuTuc,-25} {giuMs,6} {soPhien,5} {daGhi / giay,9:F0} {treMs,9:F1} {(double)wlMs / wlLan,11:F2} {rollback,8} {loHong,7}");
}
static int Sql(string cau)
{
using var conn = new SqlConnection(Cs);
conn.Open();
return new SqlCommand(cau, conn).ExecuteScalar() is int n ? n : 0;
}
Phần đếm không phụ thuộc máy: qua 5 lần chạy, SEQUENCE có 1.582 lần rollback và đúng 1.582 số hở, bảng đếm có 535 lần rollback và 0 số hở. Phần thời gian là trung vị 5 lần trên laptop Intel Core Ultra 5 125U, Windows 11, .NET 10.0.401, khi máy đang chạy nhiều việc khác (writelog_ms từ 0,4 đến 36,7 ms). Chỉ đọc bậc độ lớn.
Giữ giao dịch 30 ms, bảng đếm đứng ở 16 hóa đơn mỗi giây dù thêm phiên
Hóa đơn mỗi giây
Số phiên đồng thời
Bảng số liệu
| Số phiên đồng thời | SEQUENCE | Bảng đếm | SEQUENCE, giữ 30 ms | Bảng đếm, giữ 30 ms |
|---|---|---|---|---|
| 1 | 89 hóa đơn/s | 53 hóa đơn/s | 17 hóa đơn/s | 16 hóa đơn/s |
| 4 | 348 hóa đơn/s | 89 hóa đơn/s | 74 hóa đơn/s | 17 hóa đơn/s |
| 16 | 586 hóa đơn/s | 103 hóa đơn/s | 201 hóa đơn/s | 16 hóa đơn/s |
| 64 | 530 hóa đơn/s | 284 hóa đơn/s | 1.102 hóa đơn/s | 16 hóa đơn/s |
Bảng đếm giữ dòng đếm từ UPDATE tới khi COMMIT ghi log xong, nên thông lượng xấp xỉ 1 chia thời gian giữ một lượt. Giữ thêm 30 ms, một lượt mất khoảng 61 ms và hệ thống đứng ở 16 hóa đơn mỗi giây. Thêm phiên chỉ làm độ trễ tăng, tới 2.980 ms với 64 phiên. SEQUENCE không có dòng chung để chờ nên vẫn lên 1.102. Không giữ gì thêm, bảng đếm dao động từ 23 đến 1.071 hóa đơn mỗi giây, theo độ trễ ghi log lúc đo.
6. Đặt con số cạnh 11.700 hóa đơn mỗi ngày
11.700 hóa đơn mỗi ngày dồn hết vào một giờ cũng chỉ là 11.700 / 3.600 = 3,25 hóa đơn mỗi giây. Lần đo chậm nhất của bảng đếm, 23 hóa đơn mỗi giây, gấp 7 lần mức đó. Thứ đáng lo là việc chậm nằm trong giao dịch: ký số từ xa mất 300 ms thì trần còn khoảng 1 / 0,3 = 3,3 hóa đơn mỗi giây (ước lượng), hết chỗ cho một đợt dồn. Bốn quyết định:
- Cấp số lúc phát hành, không lúc tạo đơn. 13.000 đơn mỗi ngày chỉ ra 11.700 hóa đơn: cấp lúc tạo đơn thì khoảng 1.300 số mỗi ngày rơi vào đơn hủy hoặc dở dang.
- Giao dịch cấp số chỉ gồm
UPDATEvàINSERT. Ký số, gửi cơ quan thuế, gửi khách chạy sauCOMMIT, theo quy tắc đầu tiên của chương transaction. - Ký theo thứ tự số. Mỗi ký hiệu một luồng ký, lấy hóa đơn
TrangThai = 1theoSoHoaDontăng dần, để thứ tự ký khớp thứ tự số. Ký lỗi thì thử lại đúng số đó. - Chỉ tách ký hiệu khi cần quản lý riêng. Phụ lục Nghị định 254/2026/NĐ-CP đã tính trường hợp nhiều cơ sở dùng chung một ký hiệu. Dùng hai ký tự cuối để tách theo kho tổng, như
C26THN, là cách bài đọc cụm "nhu cầu quản lý"; văn bản không nói riêng về chi nhánh, nên cần kế toán thuế xác nhận.
flowchart TD
A["Đơn hoàn tất, TrangThai = 4"] --> B["usp_HoaDon_CapSo: UPDATE dòng đếm, INSERT hóa đơn, COMMIT"]
H["Đơn hủy"] --> X["Không cấp số"]
B --> C["Hàng đợi ký của ký hiệu, SoHoaDon tăng dần"]
C --> D{"Ký số thành công?"}
D -- "Không" --> E["Thử lại với đúng số đó"]
E --> C
D -- "Có" --> F["TrangThai = 2, gửi cơ quan thuế cấp mã"]
F --> G["TrangThai = 3, gửi hóa đơn cho khách"]
Những chỗ hay hiểu sai
- "
NO CACHEhoặcIDENTITY_CACHE = OFFcho số liền nhau." Chỉ bịt đường cache. Rollback vẫn tiêu số. - "Khởi động lại SQL Server làm nhảy số."
SHUTDOWNsạch không mất số nào. Mất số khi dừng đột ngột: mất điện, giết tiến trình,SHUTDOWN WITH NOWAIT. - "Năm của ký hiệu lấy từ
SYSUTCDATETIME()." Từ 00:00 đến 07:00 ngày 01/01 giờ Việt Nam, giờ UTC vẫn là năm cũ. Lấy năm theo giờ Việt Nam, nhưSWITCHOFFSET(SYSDATETIMEOFFSET(), '+07:00').
Đọc tiếp
- Kiểu dữ liệu, collation và khóa chính:
IDENTITYvàSEQUENCElàm khóa thay thế, nơi lỗ hổng vô hại. - Transaction, khóa và mức isolation: khóa
X,XACT_ABORT, và vì sao giao dịch phải ngắn. - Idempotency key: thử lại sau timeout ở chặng cổng thanh toán.
- Chia tiền không lệch một đồng: giảm giá chia vào từng dòng hóa đơn mà tổng vẫn khớp từng đồng.
Nguồn
- Nghị định 254/2026/NĐ-CP, văn bản ký số: Điều 10, Điều 43, Phụ lục mục 2.
- Thông tư 91/2026/TT-BTC, Cổng thông tin điện tử Chính phủ: Phụ lục I.
- Nghị định 123/2020/NĐ-CP, văn bản ký số: Điều 10 khoản 3.
- Nghị định 70/2025/NĐ-CP, văn bản ký số: Điều 1 khoản 7.
- Microsoft Learn: CREATE SEQUENCE, IDENTITY (Property), ALTER DATABASE SCOPED CONFIGURATION, UPDATE.
- Microsoft Learn: ALTER DATABASE SET options, SHUTDOWN, SqlLocalDB utility.