Избягвайте конфликти на числа с Microsoft SQL последователности
Забележка:Ще представя тази тема в групата Access with SQL Server онлайн. Моля, присъединете се към мен на 13 септември в 18:30 CST, присъединете се към групата, за да получите имейл с всички подробности за срещата, безплатно е!
- Трябва ли да гарантирате, че номер в полето ще се използва само веднъж и никога няма да бъде дублиран от друг потребител?
- Имали ли сте ситуация, в която имате нужда от повече от едно автоматично число в таблица?
- Имали ли сте някога нужда от долна и горна граница на последователни номера и не можете да надхвърлите това?
- Имате ли понякога списък с номера, които искате да рециклирате, след като преминете последния?
В SQL Server има функция, която може да се справи доста лесно с това и се нарича последователност. Предлага се от SQL Server 2012.
Подобно на автономер, той може да гарантира, че всеки път ще се издава уникален номер, освен ако не се рециклира.
Наскоро ме помолиха да внедря последователност за клиент, където множество потребители ще създават нови записи и трябва да „извличат“ следващото число в определена последователност. Не можахме да използваме автономер, защото клиентът беше ограничен до определен диапазон, за да не надвишава горен праг. Когато числата се изчерпят, ръководството ще попълни последователността отново.
Защо използването на таблица на Access не работи
Преди да надстроят до SQL Server, потребителите ще споделят таблица, която ще следи кое е следващото число, което да се използва, проблемът с този подход е, че не е доказателство за глупости, двама потребители могат да поискат един и същ номер по точно едно и също време, нарушава бизнес правилото.
Създаване и използване на последователност на SQL сървър
Преди да можете да използвате последователност, тя трябва да бъде създадена със следния синтаксис в SQL Server, трябва да направите това само веднъж:
CREATE SEQUENCE dbo.seqPolicyNumber AS int MIN 50005000 MAX 50005999;
Използвайте следния израз, за да извлечете следващия пореден номер:
ИЗБЕРЕТЕ СЛЕДВАЩА СТОЙНОСТ ЗА dbo.seqPolicyNumber като NextValue
Вашите потребители ще се нуждаят от разрешения за актуализиране, за да използват последователността, но те не трябва да могат да променят обхвата на последователността. Разрешения за актуализиране могат да се дават с помощта на този синтаксис:
ПРЕДОСТАВЯ АКТУАЛИЗИРАНЕ НА dbo.seqPolicyNumber ДО [MyDatabaseUserOrRole];
За да получите следващата стойност на последователност от VBA програма на Microsoft Access, можете да използвате следния израз, за да прочетете следващата стойност в набор от записи ADODB.
strSQL ="ИЗБЕРЕТЕ СЛЕДВАЩА СТОЙНОСТ ЗА dbo .seqPolicyNumber като NextValue"
OpenMyRecordset rs, strSQL
NextValue =rs("NextValue")
Ето как обикновено отваряме ADODB набор от записи в нашата фирма. За повече информация как можете да използвате OpenMyRecordset, можете да кликнете върху друга статия в нашия блог:
Лесни набори от записи и команди на ADODB в Access
Хубавото на синтаксиса за получаване на следващия пореден номер е, че е много лесен за използване в T-SQL. Просто замествате СЛЕДВАЩА СТОЙНОСТ ЗА <име на последователност>, където обикновено получавате стойност от име на поле, параметър или константа. По-долу е показано как може да се използва в инструкция Insert.
INSERT dbo.Orders (OrderID, Name, Qty)
VALUES (СЛЕДВАЩА СТОЙНОСТ ЗА dbo.OrderNumberSequence, 'Tire', 2);
По-голяма гъвкавост от Autonumber
Последователността може да предложи повече гъвкавост от автономер в Access или поле IDENTITY в SQL Server. Първо, можете да имате само едно поле за автономер или самоличност в таблица. Въпреки че можете да зададете повторно поле IDENTITY, не можете да рециклирате стойности. Полетата IDENTITY все още са полезни за първични ключове, когато искаме някакво произволно число, което да идентифицира записа, и то няма значение. Диапазоните на последователностите обаче могат да имат вградено значение.
Вие също не сте ограничени до използване на цели числа като IDENTITY, но поредните номера могат също да бъдат десетични или числови. Също така можете да увеличавате последователността си надолу, вместо само нагоре.
Също така последователността не е обвързана с конкретна таблица и може да се използва в различни таблици, тъй като са необходими нови последователни номера за конкретна таблица.
Попълнете последователността
Когато искате да промените диапазона за последователност, например когато имате нужда от нов диапазон от номера на политики, това трябва да се направи със съхранена процедура. Следва съхранена процедура, която може да направи това.
ЗАДАДЕТЕ ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
СЪЗДАВАНЕ НА ПРОЦЕДУРА [dbo].[usp_AlterPolicySequence] (
@SeqName AS sysname,
@InpMin AS int,
@InpMax AS int
) С ИЗПЪЛНЯВАНЕ КАТО СОБСТВЕНИК КАТО
ЗАПОЧНЕТЕ
ЗАДАДЕТЕ NOCOUNT ON;
ДЕКЛАРИРАНЕ @sql nvarchar(MAX),
@err nvarchar(MAX);
АКО НЕ СЪЩЕСТВУВА (
ИЗБЕРЕТЕ NULL
ОТ sys.sequences AS s
WHERE s.name =@SeqName
И s.schema_id =SCHEMA_ID('dbo')
)
THROW 50000, 'Името на поредицата не е валидно.', 1;
АКО @InpMin IS NULL ИЛИ @InpMax IS NULL
THROW 50000, „Стойностите не могат да бъдат нулеви.“, 1;
SET @sql =CONCAT(N'ALTER SEQUENCE [dbo].', QUOTENAME(@SeqName), N' РЕСТАРТИРАНЕ С ', @InpMin, N' НАРАЩАНЕ С 1′, N' MINVALUE ', @InpMin, N' MAXVALUE ' , @InpMax, N' БЕЗ ЦИКЛ БЕЗ КЕШ;');
EXEC sys.sp_executesql @sql;
;
КРАЙ
Има някои неща, които си струва да се отбележат в тази съхранена процедура. Първо го изпълняваме
С ИЗПЪЛНЕНИЕ КАТО СОБСТВЕНИК.
Ние не искаме обикновеният потребител да може да променя последователност. Но ние искаме да им дадем ограничена способност да го променят само чрез съхранена процедура. (Потребителите се нуждаят само от права за съхранената процедура.)
ПРЕДОСТАВЯТЕ ИЗПЪЛНЕНИЕ НА dbo.usp_AlterPolicySequence КЪМ [MyDatabaseUserOrRole];
Тази съхранена процедура може да се изпълнява от преден край на Access, когато трябва да се инсталира нов диапазон в последователността и това обикновено ще бъде от потребител с администратор, който може да има повече привилегии на SQL Server от обикновен потребител.
Тази съхранена процедура обаче може да се изпълнява и когато нов диапазон от числа чака да бъде зареден в последователността, веднага след като текущата последователност бъде изчерпана. В този случай съхранената процедура може да бъде извикана от всеки потребител, който се нуждае от първия номер на политика за новия диапазон. Затова използваме WITH EXECUTE AS OWNER AS, за да им дадем повече права само за тази ограничена употреба.
Друго нещо, което трябва да забележите е, че е необходимо да се създаде SQL низ и след това да се използва
EXEC sys.sp_executesql
на този низ, ако използваме параметри.
Следният израз ще работи, ако бъде въведен в прозорец за заявка на SSMS или използван в съхранена процедура.
ПРОМЕНЯТЕ ПОСЛЕДОВАТЕЛНОСТ dbo.seqPolicyNumber
РЕСТАРТИРАНЕ С 50005000
НАРАЩАНЕ С 1
МИНИМАЛНА СТОЙНОСТ 50005000
МАКСИМАЛНА СТОЙНОСТ 50005999
БЕЗ ЦИКЪЛ
Обаче следното няма да работи с помощта на параметри в съхранена процедура.
ПРОМЕНЯТЕ ПОСЛЕДОВАТЕЛНОСТ dbo.seqPolicyNumber
РЕСТАРТИРАНЕ С @InpMin
НАРАЩАНЕ С 1
МИНИМАЛНА СТОЙНОСТ @ InpMin
MAXVALUE @InpMax
БЕЗ ЦИКЪЛ
БЕЗ КЕШ
Така че трябва да конструирате низовия израз със стойностите на параметрите, поставени в него.
SET @sql =CONCAT(N'ALTER SEQUENCE [dbo].', QUOTENAME(@SeqName), N' РЕСТАРТИРАНЕ С ', @InpMin, N' НАРАЩАНЕ С 1', N' MINVALUE ', @InpMin, N' MAXVALUE ', @InpMax, N' БЕЗ ЦИКЛ БЕЗ КЕШ;');
EXEC sys.sp_executesql @sql;
Този низ @sql е конструиран с помощта на функциите CONCAT и QUOTENAME. Ще работи и ако сте използвали знаци плюс, за да направите своя последен низ, но е по-добре да го направите като примера, който е безопасен за нула.
Тази съхранена процедура ще произведе (изведе) грешка, ако предоставите липсващи или лоши стойности и няма да ви бъде позволено да продължите. Той автоматично ще генерира грешка, ако всички последователни номера се изразходват.
Вашата процедура за достъп от предния край трябва да провери дали не е възникнала грешка, която трябва да възникне само ако последователността свърши без числа, ако предоставяте правилни входове за параметри. Ако се види грешка, тогава предният край ще трябва по някакъв начин да отмени операцията си.
Има някои други възможности, които можете да зададете с аргументи. CYCLE ще позволи на последователността да се повтори, след като достигне края, и след това ще премине към MINVALUE. Можете дори изрично да го рестартирате в средата на поредица, като му дадете стойност RESTART.
Можете също да му дадете CACHE, например можете да поискате 50 последователни номера наведнъж и той актуализира системните таблици с последователности веднъж на всеки 50 числа, което може да бъде по-бързо, но също така добавя риск, ако има прекъсване на захранването , тъй като тези числа не могат да бъдат използвани повторно
Последното нещо, което си струва да се отбележи в тази съхранена процедура, е, че можете да изтеглите информация (мета-данни) за вашите последователности от системен изглед, наречен sys.sequence. Той съдържа следната информация.
Някои полезни колони, които може да искате да прочетете и предадете на потребителя, са minimal_value, maximum_value и текуща_стойност.
Ако се интересувате, следващите страници в MSDN съдържат много полезна информация за последователностите.
Номера на последователности
Описва последователности и има много добри примери за типична употреба
СЪЗДАВАНЕ НА ПОСЛЕДОВАТЕЛНОСТ (Transact-SQL)
ПРОМЕНИ ПОСЛЕДОВАТЕЛНОСТТА (Transact-SQL)
СЛЕДВАЩА СТОЙНОСТ ЗА (Transact-SQL)
sys.sequences (Transact-SQL)
Описва метаданните, за които можете да потърсите за вашите последователности