it-swarm.com.de

Automatische Inkrementierung in MS SQL-Buchstaben und -Zahlen

Ich habe eine Frage, wie man ein automatisches Inkrementieren in MS SQL erreicht. Der einzige Weg, den ich bisher kenne, ist das Perfixieren in der Tabelle, z

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)
    )

ich werde so etwas bekommen

Cus0001
Cus0002

was nach Cus9999?

einige, wie kann ich Auto-Inkrement so erreichen

CUSAB000001
CUSAB000002
CUSAB000003
CUSAB000004
CUSAB000005
CUSAB000006
CUSAB000007
CUSAB000008
CUSAB999999
CUSCD000001
CUSYZ999999.
5
Anis Maredia

Um Gruppen zu erhöhen, die bei AA beginnen und bei ZZ enden, müssen Sie den linken Teil der Zahl (was auch immer über der Anzahl der Stellen liegt, die Sie als Ganzzahlen behalten möchten) in Base konvertieren 26. Sie kürzen zunächst den rechten Teil der Zahl, sodass Sie nur den linken Teil haben, und dividieren dann durch 10 ^ IntegerDigits (z. B. 3 ganzzahlige Ziffern == 10 ^ 3 == 1000), um den A_ Seite, dann verwenden Sie Modulo auf derselben 10 ^ IntegerDigits, um die Seite _A zu erhalten. Diese Werte erhalten den Offset vom Wert ASCII für A. Zum Beispiel:

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

All dies können wir in einem Inline-TVF (für Demozwecke, nicht zur Verwendung in einer berechneten Spalte in einer Tabelle) wie folgt zusammenfassen:

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

Dann können wir testen mit:

SELECT * FROM dbo.Base26(142);
SELECT * FROM dbo.Base26(3142);
SELECT * FROM dbo.Base26(123142);
SELECT * FROM dbo.Base26(123999);

was zurückgibt:

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

JEDOCH Ich sehe absolut überhaupt keinen Grund, dies in Ihrer Situation umzusetzen. Es hat keinen Vorteil, einen String "CusXXXXXX" -Wert zu haben, wobei "XXXXXX" wirklich nur der IDENTITY -Wert ist. Wenn Sie das "XXXXXX" über einen Hash oder Modular Multiplicative Inverse verschleiern würden, wäre dies möglicherweise in Ordnung, obwohl ich immer noch nicht sicher bin, ob Sie den "Cus" -String-Teil davon speichern möchten. In der jetzigen Form profitieren Sie jedoch in keiner Weise davon. Sie verschwenden nur Speicherplatz in der Datenbank.

Weitere Hinweise:

  • Sie sind besser dran , wenn Sie nicht "Kunde" als "CUS" als Präfix für Spalten in dieser Tabelle abkürzen. Verwenden Sie einfach den vollständigen Tabellennamen, insbesondere für die ID-Spalte: CustomerID und CustomerName.
  • Sie sollten keinen numerischen Typ (d. H. INT) zum Speichern von Telefonnummern verwenden. Zahlen, für die Sie keine mathematischen Operationen ausführen, sollten als Zeichenfolgen gespeichert werden. Dies gilt auch für Postleitzahlen, Sozialversicherungsnummern (SSNs) usw. Bei Telefonnummern gibt es häufig Nebenstellen oder andere nicht numerische Optionen, z. B. das Präfix +, Wenn sie sich außerhalb der Basisland.
  • Sie sollten keinen Zeichenfolgentyp (dh VARCHAR(10)) verwenden, um einen wiederholten Code/eine wiederholte Bezeichnung wie "gender" zu speichern (vorausgesetzt, die vollständigen Wörter "männlich" und "weiblich" oder ähnliches werden gespeichert, und das eine nicht-binäre/_BIN2 Kollatierung wird verwendet). Sie sollten eine Nachschlagetabelle "Geschlecht" mit einer Spalte GenderID TINYINT Als Primärschlüssel haben (aber nicht ein IDENTITY ). Dann hätten Sie in der Tabelle Customer auch GenderID TINYINT, Aber es wäre ein Fremdschlüssel, der auf dbo.Gender (GenderID) verweist.

    ODER:

    Sie können eine CHAR(1) COLLATE Latin1_General_100_BIN2 NOT NULL - Spalte mit einer CHECK - Einschränkung verwenden, die erzwingt, dass nur M und F zulässig sind. Auf diese Weise erhalten Sie einen "Code", der von Menschen gelesen werden kann und dennoch so effizient mit Speicher, Speicher und Vergleichen ist wie ein TINYINT.

8
Solomon Rutzky

Lesen Sie bitte diesen ausgezeichneten Artikel.

http://www.sqlteam.com/article/custom-auto-generated-sequences-with-sql-server

Beachten Sie, dass die dbID-Spalte eine standardmäßige, von der Datenbank generierte Identität ist, die unser physischer Primärschlüssel der Tabelle ist. Wir werden jedoch eine CustomerNumber-Spalte hinzufügen, die wir wie beschrieben im "C0000" -Format der Außenwelt zur Verfügung stellen.

Lassen Sie uns eine Funktion erstellen, die eine Ganzzahl akzeptiert und diese Ganzzahl verwendet, um unsere Kundennummer zurückzugeben:

create function CustomerNumber (@id int) 
returns char(5) 
as 
begin 
return 'C' + right('0000' + convert(varchar(10), @id), 4) 
end

Mit dieser Funktion können wir unserer Tabelle einfach eine berechnete Spalte wie folgt hinzufügen:

alter table Customers add CustomerNumber as dbo.CustomerNumber(dbID)