Vyhněte se konfliktům čísel se sekvencemi Microsoft SQL
Poznámka:Na toto téma budu prezentovat online ve skupině Access with SQL Server. Připojte se ke mně 13. září v 18:30 CST, připojte se ke skupině a dostanete e-mail se všemi podrobnostmi o schůzce, je to zdarma!
- Potřebujete zaručit, že číslo v poli bude použito pouze jednou a nikdy je nezduplikuje jiný uživatel?
- Zažili jste situaci, kdy jste potřebovali více než jedno automatické číslování v tabulce?
- Potřebovali jste někdy dolní a horní hranici sekvenčních čísel a nemohli jste ji překročit?
- Máte někdy seznam čísel, která chcete recyklovat poté, co přejdete přes to poslední?
V SQL Serveru existuje funkce, která si s tím docela snadno poradí a nazývá se sekvence. Je k dispozici od SQL Server 2012.
Stejně jako automatické číslo může zajistit, že pokaždé bude přiděleno jedinečné číslo, pokud se nerecykluje.
Nedávno jsem byl požádán o implementaci sekvence pro klienta, kde více uživatelů vytvoří nové záznamy a musí „načíst“ další číslo v určité sekvenci. Nemohli jsme použít automatické číslo, protože zákazník byl omezen na určitý rozsah, který nepřekročil horní práh. Když jsou čísla vyčerpána, management by sekvenci znovu doplnil.
Proč použití Accessové tabulky nefunguje
Před upgradem na SQL Server by uživatelé sdíleli tabulku, která by držela přehled o tom, jaké je další číslo k použití, problém s tímto přístupem je v tom, že není spolehlivý, dva uživatelé mohou požadovat stejné číslo přesně ve stejnou dobu, porušení obchodního pravidla.
Vytvoření a použití sekvence serveru SQL
Než budete moci použít sekvenci, musí být vytvořena s následující syntaxí na serveru SQL Server, stačí to udělat pouze jednou:
CREATE SEQUENCE dbo.seqPolicyNumber AS int MIN 50005000 MAX 50005999;
K získání dalšího pořadového čísla použijte následující příkaz:
VYBERTE DALŠÍ HODNOTU PRO dbo.seqPolicyNumber jako NextValue
Vaši uživatelé budou potřebovat oprávnění k aktualizaci, aby mohli sekvenci používat, ale neměli by mít možnost měnit rozsah sekvence. Oprávnění k aktualizaci lze udělit pomocí této syntaxe:
GRANT UPDATE ON dbo.seqPolicyNumber TO [MyDatabaseUserOrRole];
Chcete-li získat další hodnotu sekvence z programu Microsoft Access VBA, můžete použít následující příkaz k načtení další hodnoty do sady záznamů ADODB.
strSQL ="SELECT NEXT VALUE FOR dbo .seqPolicyNumber jako NextValue"
OpenMyRecordset rs, strSQL
NextValue =rs("NextValue")
Takto obvykle otevíráme sadu záznamů ADODB v naší firmě. Pro více informací o tom, jak můžete používat OpenMyRecordset, můžete kliknout na jiný článek v našem blogu:
Snadné sady záznamů a příkazy ADODB v Access
Pěkná věc na syntaxi pro získání dalšího pořadového čísla je, že se velmi snadno používá v T-SQL. Stačí nahradit NEXT VALUE FOR
INSERT dbo.Orders (ID objednávky, název, množství)
VALUES (DALŠÍ HODNOTA PRO dbo.OrderNumberSequence, 'Tire', 2);
Větší flexibilita než automatické číslování
Sekvence může nabídnout větší flexibilitu než automatické číslování v aplikaci Access nebo pole IDENTITY na serveru SQL Server. Za prvé, v tabulce můžete mít pouze jedno automatické číslo nebo pole identity. I když můžete znovu nasadit pole IDENTITY, nemůžete recyklovat hodnoty. Pole IDENTITY jsou stále užitečná pro primární klíče, když chceme nějaké libovolné číslo k identifikaci záznamu a nemá to žádný význam. Rozsahy sekvencí však mohou mít vložený význam.
Také nejste omezeni na používání celých čísel jako IDENTITY, ale pořadová čísla mohou být také desítková nebo číselná. Můžete také zvyšovat svou sekvenci směrem dolů, nikoli pouze nahoru.
Sekvence také není svázána s žádnou konkrétní tabulkou a lze ji použít napříč tabulkami, protože pro konkrétní tabulku jsou potřeba nová sekvenční čísla.
Doplňte sekvenci
Když chcete změnit rozsah pro sekvenci, jako když potřebujete nový rozsah čísel zásad, mělo by to být provedeno pomocí uložené procedury. Toto je uložená procedura, která to dokáže.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
POSTUP VYTVOŘENÍ [dbo].[usp_AlterPolicySequence] (
@SeqName JAKO sysname,
@InpMin AS int,
@InpMax AS int
) S EXECUTE JAKO VLASTNÍK JAKO
BEGIN
SET NOCOUNT ON;
DECLARE @sql nvarchar(MAX),
@err nvarchar(MAX);
POKUD NEEXISTUJE (
SELECT NULL
FROM sys.sequences AS s
WHERE s.name =@SeqName
AND s.schema_id =SCHEMA_ID('dbo')
)
THROW 50000, 'Název sekvence není platný.', 1;
POKUD JE @InpMin NULL NEBO @InpMax JE NULL
THROW 50000, ‚Hodnoty nemohou být null.‘, 1;
SET @sql =CONCAT(N'ALTER SEQUENCE [dbo].', QUOTENAME(@SeqName), N' RESTART WITH ', @InpMin, N' INCREMENT BY 1′, N' MINVALUE ', @InpMin, N' MAXVALUE ' , @InpMax, N' NO CYCLE NO CACHE;');
EXEC sys.sp_executesql @sql;
;
KONEC
V této uložené proceduře stojí za zmínku některé věci. Nejprve jej spustíme
S EXECUTE AS OWNER AS.
Nechceme, aby každodenní uživatel mohl měnit sekvenci. Ale chceme jim poskytnout omezenou možnost změnit to pouze prostřednictvím uložené procedury. (Uživatelé potřebují pouze práva k uložené proceduře.)
GRANT EXECUTE ON dbo.usp_AlterPolicySequence TO [MyDatabaseUserOrRole];
Tuto uloženou proceduru lze spustit z frontendu Accessu, kdykoli je třeba nainstalovat nový rozsah v sekvenci, což by normálně provedl uživatel admin, který může mít více oprávnění SQL Server než běžný uživatel.
Tato uložená procedura však může být také spuštěna, když nový rozsah čísel čeká na načtení do sekvence, hned po vyčerpání aktuální sekvence. V tomto případě může uloženou proceduru volat jakýkoli uživatel, který potřebuje první číslo zásady pro nový rozsah. Používáme tedy S EXECUTE AS OWNER AS, abychom jim poskytli více práv právě pro toto omezené použití.
Další věc, kterou je třeba si všimnout, je, že je nutné vytvořit řetězec SQL a poté použít
EXEC sys.sp_executesql
na tomto řetězci, pokud používáme parametry.
Následující příkaz bude fungovat, pokud bude zadán do okna dotazu SSMS nebo použit v uložené proceduře.
ALTER SEQUENCE dbo.seqPolicyNumber
RESTARTUJTE S 50005000
ZVÝŠENÍ O 1
MIN. HODNOTA 50005000
MAX.HODNOTA 50005999
ŽÁDNÝ CYKLUS
ŽÁDNÝ CYKLUS
Následující však nebude fungovat pomocí parametrů v uložené proceduře.
ALTER SEQUENCE dbo.seqPolicyNumber
RESTARTUJTE S @InpMin
ZVÝŠENÍ O 1
MINVALUE @ InpMin
MAXHODNOTA @InpMax
ŽÁDNÝ CYKLUS
ŽÁDNÁ CACHE
Takže musíte vytvořit příkaz řetězce s vloženými hodnotami parametrů.
SET @sql =CONCAT(N'ALTER SEQUENCE [dbo].', QUOTENAME(@SeqName), N' RESTARTUJTE S ', @InpMin, N' ZVÝŠENÍ O 1', N' MINVALUE ', @InpMin, N' MAXVALUE ', @InpMax, N' NO CYCLE NO CACHE;');
EXEC sys.sp_executesql @sql;
Tento řetězec @sql je vytvořen pomocí funkcí CONCAT a QUOTENAME. Bude to také fungovat, pokud jste k vytvoření konečného řetězce použili znaménka plus, ale je lepší to udělat jako v příkladu, který je bezpečný pro nulu.
Tato uložená procedura vytvoří (vyhodí) chybu, pokud zadáte chybějící nebo špatné hodnoty, a nebudete moci pokračovat. Pokud jsou všechna sekvenční čísla vyčerpána, automaticky vygeneruje chybu.
Vaše procedura frontend Access by měla zkontrolovat, zda nenastala chyba, která by se měla objevit pouze v případě, že sekvence překročí čísla, pokud poskytujete správné vstupy parametrů. Pokud je vidět chyba, bude frontend muset nějak zrušit svou operaci.
Existují některé další možnosti, které můžete nastavit pomocí argumentů. CYCLE umožní sekvenci opakovat cyklus poté, co dosáhne konce, a poté přejít na MINVALUE. Můžete jej dokonce explicitně restartovat uprostřed sekvence zadáním hodnoty RESTART.
Můžete mu také dát CACHE, například můžete požádat o 50 sekvenčních čísel najednou a aktualizuje systémové tabulky sekvencí každých 50 čísel, což může být rychlejší, ale také přidává riziko, pokud dojde k výpadku napájení. , protože tato čísla nelze znovu použít
Poslední věcí, která stojí za zmínku v této uložené proceduře je, že můžete získat informace (metadata) o vašich sekvencích ze systémového pohledu nazvaného sys.sequences. Obsahuje následující informace.
Některé užitečné sloupce, které byste si mohli chtít přečíst a sdělit uživateli, jsou minimální_hodnota, maximální_hodnota a aktuální_hodnota.
Pokud máte zájem, následující stránky na MSDN obsahují velmi užitečné informace o sekvencích.
Čísla sekvencí
Popisuje sekvence a má velmi dobré příklady pro typické použití
CREATE SEQUENCE (Transact-SQL)
ALTER SEQUENCE (Transact-SQL)
DALŠÍ HODNOTA PRO (Transact-SQL)
sys.sequences (Transact-SQL)
Popisuje metadata, na která se můžete dotazovat ve svých sekvencích