Maßgeschneiderter SQL Server-Codierungs-Sproc – gibt es eine einfachere Möglichkeit, dies zu tun?

StackOverflow https://stackoverflow.com/questions/55340

  •  09-06-2019
  •  | 
  •  

Frage

Ich frage mich nur, ob es in SQL Server 2005 eine bessere Möglichkeit gibt, dies zu tun.

Tatsächlich nehme ich eine originator_id (eine Zahl zwischen 0 und 99) und ein „next_element“ (es ist eigentlich nur ein fortlaufender Zähler zwischen 1 und 999.999).Wir versuchen daraus einen 6-stelligen „Code“ zu erstellen.

Die originator_id wird mit einer Million multipliziert und dann der Zähler addiert, was eine Zahl zwischen 0 und 99.999.999 ergibt.

Dann wandeln wir dies in eine „Basis 32“-Zeichenfolge um – eine gefälschte Basis 32, bei der wir eigentlich nur 0-9 und A-Z verwenden, aber aus Gründen der Übersichtlichkeit einige der verwirrenderen Alphanumeren entfernt haben (I, O, S, Z). .

Dazu teilen wir die Zahl einfach durch Potenzen von 32 auf und verwenden in jeder Phase das Ergebnis, das wir für jede Potenz erhalten, als Index für ein Zeichen aus unserem Array ausgewählter Zeichen.

Thus, an originator ID of 61 and NextCodeElement of 9 gives a code of '1T5JA9'

(61 * 1,000,000) + 9 = 61,000,009
61,000,009 div (5^32 = 33,554,432) =  1 = '1'
27,445,577 div (4^32 =  1,048,576) = 26 = 'T'
   182,601 div (3^32 =     32,768) =  5 = '5'
    18,761 div (2^32 =      1,024) = 18 = 'J'
       329 div (1^32 =         32) = 10 = 'A'
         9 div (0^32 =          1) =  9 = '9'

so my code is 1T5JA9

Zuvor hatte dieser Algorithmus (in Delphi) funktioniert, aber jetzt muss ich ihn unbedingt in SQL Server 2005 neu erstellen können.Natürlich habe ich nicht ganz die gleichen Funktionen wie in Delphi zur Hand, aber das ist meine Sicht auf die Routine.Es funktioniert und ich kann problemlos Codes generieren (oder Codes wieder in ihre Komponenten rekonstruieren).

Aber es sieht etwas langatmig aus, und ich bin mir nicht sicher, ob der Trick, das Ergebnis einer Division in ein Int auszuwählen (also wirklich umzuwandeln), unbedingt „richtig“ ist – gibt es einen besseren SQLS-Ansatz für diese Art? von der Sache?

CREATE procedure dummy_RP_CREATE_CODE @NextCodeElement int, @OriginatorID int,
  @code varchar(6) output
as
begin
  declare @raw_num int;
  declare @bcelems char(32);
  declare @chr int;

  select @bcelems='0123456789ABCDEFGHJKLMNPQRTUVWXY';
  select @code='';

  -- add in the originator_id, scaled into place
  select @raw_num = (@OriginatorID * 1000000) + @NextCodeElement;

  -- now to convert this to a 6-char code

  -- 5^32
  select @chr = @raw_num / 33554432;
  select @raw_num = @raw_num - (@chr * 33554432);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 4^32
  select @chr = @raw_num / 1048576;
  select @raw_num = @raw_num - (@chr * 1048576);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 3^32
  select @chr = @raw_num / 32768;
  select @raw_num = @raw_num - (@chr * 32768);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 2^32
  select @chr = @raw_num / 1024;
  select @raw_num = @raw_num - (@chr * 1024);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 1^32
  select @chr = @raw_num / 32;
  select @raw_num = @raw_num - (@chr * 32);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 0^32  
  select @code = @code + SUBSTRING(@bcelems, 1 + @raw_num, 1);

  -- that's it!
end;

Ich mache mir keine großen Sorgen um die Optimierung, es sei denn, diese Methode ist tatsächlich um eine Größenordnung (oder so) schlechter als jede Alternative.

Der Code wird immer nur in kleinen Stößen ausgeführt, wobei etwa alle 10 Minuten 20 oder 30 Codes generiert werden.Aufgrund des großen Zahlenbereichs möchte ich die Codes nicht in einer großen Tabelle vorab berechnen (in jeder Installation werden nur kleine Bereiche des gesamten Codebereichs verwendet).

Ich bin mir jedoch sicher, dass es wahrscheinlich einen saubereren Weg gibt, das gleiche Ergebnis zu erzielen – insbesondere mit den Divisionen und Subtraktionen.

Konstruktive Kritik, Anmerkungen oder Vorschläge sind uns sehr willkommen.

War es hilfreich?

Lösung

Sehen als es SQL Server ist 2005 aus irgendeinem Grund keine CLR gespeicherte Prozedur zu benutzen? Sie könnten Ihre CLR-Sprache der Wahl verwenden dann und es würde wahrscheinlich eine relativ direkte Schnittstelle Ihres vorhandenen Delphi-Code sein.

Andere Tipps

Obwohl es eindeutig in SQL Server 2005 durchgeführt werden kann, denke ich, dass es eine ausreichende ‚Nicht-Datenbank-ness‘, dass eine Art von vorkompilierte, höhere Programmiersprache Routine makese Sinn.

Ich habe geschrieben DLLs für Interbase / Firebird und T-SQL sprocs für SQL Server, aber nie eine CLR-Routine. Es wird eine interessante Übung sein!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top