J'ai une question, comment réaliser l'incrémentation automatique dans MS SQL. la seule façon que je connaisse jusqu'à présent est de perfixer le tableau par exemple
CREATE TABLE Customer (
CUSId INT NOT NULL IDENTITY(1, 1) PRIMARY KEY
,CUSKey AS 'Cus' + RIGHT('000' + CONVERT(VARCHAR(5), CUSId), 6) PERSISTED
,CusName VARCHAR(50)
,mobileno INT
,Gender VARCHAR(10)
)
je vais avoir quelque chose comme
Cus0001
Cus0002
quoi après Cus9999?
certains comment puis-je atteindre l'incrémentation automatique comme celui-ci
CUSAB000001
CUSAB000002
CUSAB000003
CUSAB000004
CUSAB000005
CUSAB000006
CUSAB000007
CUSAB000008
CUSAB999999
CUSCD000001
CUSYZ999999.
Pour incrémenter des groupes commençant à AA
et se terminant à ZZ
, vous devez convertir la partie gauche du nombre (quel que soit le nombre de chiffres que vous souhaitez conserver sous forme d'entiers) en Base 26. Vous commencez par tronquer la partie droite du nombre afin de n'avoir que la partie gauche, puis vous divisez par 10 ^ IntegerDigits (par exemple 3 chiffres entiers == 10 ^ 3 == 1000) pour obtenir le A_
, puis utilisez modulo sur le même 10 ^ IntegerDigits pour obtenir le côté _A
. Ces valeurs nous obtiendront le décalage par rapport à la valeur ASCII pour A
. Par exemple:
SELECT (123142 / 1000) AS [Truncated],
(123142 / 1000) / 26 AS [SetsOf26],
(123142 / 1000) % 26 AS [Remaining],
CHAR(65) AS [A];
-- Truncated = 123
-- SetsOf26 = 4
-- Remaining = 19
-- A = A
Nous pouvons rassembler tout cela dans un TVF en ligne (à des fins de démonstration, pas pour une utilisation dans une colonne calculée dans un tableau) comme suit:
CREATE FUNCTION dbo.Base26 (@Base10 INT)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN
WITH truncated AS
(
SELECT (@Base10 / 1000) AS [Value]
)
SELECT @Base10 AS [Actual],
tr.Value AS [Truncated],
CHAR(65 + (tr.Value / 26)) AS [1stChar],
CHAR(65 + (tr.Value % 26)) AS [2ndChar],
CHAR(65 + (tr.Value / 26))
+ CHAR(65 + (tr.Value % 26))
+ RIGHT('00' + CONVERT(VARCHAR(20), @Base10 % 1000), 3) AS [EndResult]
FROM truncated tr;
GO
Ensuite, nous pouvons tester avec:
SELECT * FROM dbo.Base26(142);
SELECT * FROM dbo.Base26(3142);
SELECT * FROM dbo.Base26(123142);
SELECT * FROM dbo.Base26(123999);
qui renvoie:
Actual Truncated 1stChar 2ndChar EndResult
142 0 A A AA142
3142 3 A D AD142
123142 123 E T ET142
123999 123 E T ET999
CEPENDANT, Je ne vois absolument aucune raison de mettre cela en œuvre dans votre situation. Il n'y a aucun avantage à avoir une chaîne "CusXXXXXX" où "XXXXXX" est vraiment juste la valeur IDENTITY
. Si vous deviez obscurcir le "XXXXXX" via un hachage ou l'inverse multiplicatif modulaire, alors cela pourrait être correct, bien que je ne sois toujours pas sûr que vous souhaitiez stocker la partie de chaîne "Cus" de celui-ci. Mais sous sa forme actuelle, vous ne tirez aucun avantage de cette opération. Vous gaspillez simplement de l'espace dans la base de données.
Autres notes:
CustomerID
et CustomerName
.INT
) pour stocker les numéros de téléphone. Les nombres sur lesquels vous n'effectuez pas d'opérations mathématiques doivent être stockés sous forme de chaînes. Cela s'applique également aux codes postaux, aux numéros de sécurité sociale (SSN), etc. Dans le cas des numéros de téléphone, ils ont souvent des extensions ou d'autres options non numériques, telles que le préfixe avec +
S'ils se trouvent en dehors du pays de base.Vous ne devez pas utiliser un type de chaîne (c'est-à-dire VARCHAR(10)
) pour stocker un code/une étiquette répété tel que "sexe" (en supposant que les mots complets "mâle" et "femelle" ou similaire sont stockés, et que un classement non binaire/_BIN2
est utilisé). Vous devriez avoir une table de recherche "Genre" avec une colonne GenderID TINYINT
Comme clé primaire (mais pas un IDENTITY
). Ensuite, dans la table Customer
, vous auriez également GenderID TINYINT
Mais ce serait une clé étrangère référençant dbo.Gender (GenderID)
.
OU:
Vous pouvez utiliser une colonne CHAR(1) COLLATE Latin1_General_100_BIN2 NOT NULL
avec une contrainte CHECK
imposant que seuls M
et F
sont acceptables. Cela vous donne un "code" lisible par l'homme tout en étant aussi efficace avec le stockage, la mémoire et les comparaisons qu'un TINYINT
.
Lisez cet excellent article s'il vous plaît.
http://www.sqlteam.com/article/custom-auto-generated-sequences-with-sql-server
Notez que la colonne dbID est une identité standard générée par la base de données qui sera notre clé primaire physique de la table. Cependant, nous ajouterons une colonne CustomerNumber qui sera ce que nous exposons au monde extérieur au format "C0000", comme décrit.
Créons une fonction qui accepte un entier et utilise cet entier pour renvoyer notre numéro de client:
create function CustomerNumber (@id int)
returns char(5)
as
begin
return 'C' + right('0000' + convert(varchar(10), @id), 4)
end
En utilisant cette fonction, nous pouvons simplement ajouter une colonne calculée à notre table comme ceci:
alter table Customers add CustomerNumber as dbo.CustomerNumber(dbID)