C# ve SQL Server ile eşsiz değerler nasıl üretilir (How to generate a unique ID using C# and SQL Server)
Geliştirdiğimiz iş yazılımlarında bir çok veri üretiyoruz, bu üretilen verilerin çoğu bir biri ile bağlantılı. Bu bağlantıyı sağlamak için tüm ilşkili tablolar arasında EŞSİZ bir anahtar değere ihtiaycımız var. Veritabanı ile ilgilenenler bilir bu eşsiz anahtar değer Primary Key (PK) olarak adlandırılır. Bu PK değeri tablo içindeki milyonlarca değer için eşsiz olarak oluşturulur. Amacı milyon kaydın içinden istediğimiz “X” satıra erişebilmek ve onunla gerekli işlemler yapabilmek. Aynı zamanda bu PK değerler tablolar arasında da kullanılır ve zincirleme bir çok tabloyu bir birine bağlar. Daha sonra bu tablolar bir biri ile bağlanıp karmaşık sorgular ve raporlar edle edilebilir.
Şu anda çok şirketin, işyerinin olduğu bir ortamda çalışıyorum. Bu ortamda aynı zamanda çok karmaşık bir satınalma onay süreci var. A şirketinde onay süreci A->B->C olarak gereçekleşiyor. F şirketinde A->D->B->Z şeklinde gerçekleşiyor. Bu karmaşık ortam için kolay kullanılabilen-yönetilebilen ve çok esnek bir onay yapısına sahip Web tabanlı bir SATINALMA yazılımı geliştiriyorum. Bu karmaşık yapı nedeni ile birçok tablo arasında mantıksal bağlantı olmalı. Bu yapının birkaç tablosu aşağıdaki gibi:
CREATE TABLE [dbo].[SATINALMA_TALEP]
(
[ID] [uniqueidentifier] NOT NULL,
[TARIH] [datetime] NOT NULL,
[ACIKLAMA] [varchar](150) NOT NULL,
[SIRKET_ID] [int] NOT NULL,
[ISYERI_ID] [int] NULL,
…
(
[ID] [uniqueidentifier] NOT NULL,
[TARIH] [datetime] NOT NULL,
[ACIKLAMA] [varchar](150) NOT NULL,
[SIRKET_ID] [int] NOT NULL,
[ISYERI_ID] [int] NULL,
…
CREATE TABLE [dbo].[SATINALMA_TALEP_DETAY]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[TALEP_ID] [uniqueidentifier] NOT NULL,
[STOK_KODU] [varchar](35) NULL,
[MIKTAR] [decimal](18, 5) NULL,
…
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[TALEP_ID] [uniqueidentifier] NOT NULL,
[STOK_KODU] [varchar](35) NULL,
[MIKTAR] [decimal](18, 5) NULL,
…
CREATE TABLE [dbo].[SATINALMA_TALEP_HAREKET]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[TALEP_ID] [uniqueidentifier] NOT NULL,
[TARIH] [datetime] NULL,
[GOREVLI_ID] [int] NULL,
…
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[TALEP_ID] [uniqueidentifier] NOT NULL,
[TARIH] [datetime] NULL,
[GOREVLI_ID] [int] NULL,
…
CREATE TABLE [dbo].[SAT_TALEP_EKLER]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[TALEP_ID] [uniqueidentifier] NOT NULL,
[EK] [varchar](250) NULL,
…
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[TALEP_ID] [uniqueidentifier] NOT NULL,
[EK] [varchar](250) NULL,
…
Buradaki tabloları birbirine bağlayan ilk tablodaki ID değeri. Bu değerin eşsiz olarak üretilmesi çok önemli. Bu sayede veriler arasında bağlantı güvenli bir şekilde sağlanmış olacak. Bu değer Primary Key veritabanı tarafından otomatik olarak da üretilebilir (SQL Server’da IDENTITY SEED ve Oracle’da CREATE SEQUENCE). Ama bu ileride birçok veritabanı ile çalışırken ve Database Replikasyonu gibi işlemler yapmak zorunda kalırsak sorun çıkarabiilir. Büyük ve dağınık yapıda veritabanı yapısı tasarlarken kullanılacak en iyi PrimaryKey veri tipi GUID. Bu nedenle biz veriler üzerinde KESİN ve NET kontrol sağlamak için kendi yaratığımız eşsiz ID (GUID) değerlerini üretip kullanacağız. Bu amaçla C# ve T-SQL ile ayrı ayrı bunu nasıl yapacağımızı göstereceğim.
public Guid NewRecordID()
{
//How to generate COMB ID
//Sağlam bir çözüm bunu kullan
//bu değeri SQL Serverda depolamak için …ID [uniqueidentifier] NOT NULL şeklinde olmalı
byte[] destinationArray = Guid.NewGuid().ToByteArray();
DateTime time = new DateTime(0x76c, 1, 1);
DateTime now = DateTime.Now;
DateTime time = new DateTime(0x76c, 1, 1);
DateTime now = DateTime.Now;
// Get the days and milliseconds which will be
// used to build the byte string
TimeSpan span = new TimeSpan(now.Ticks – time.Ticks);
TimeSpan timeOfDay = now.TimeOfDay;
// used to build the byte string
TimeSpan span = new TimeSpan(now.Ticks – time.Ticks);
TimeSpan timeOfDay = now.TimeOfDay;
// Convert to a byte array
// Note that SQL Server is accurate to 1/300th of a
// millisecond so we divide by 3.333333
byte[] bytes = BitConverter.GetBytes(span.Days);
byte[] array = BitConverter.GetBytes(
(long)
(timeOfDay.TotalMilliseconds / 3.333333));
// Note that SQL Server is accurate to 1/300th of a
// millisecond so we divide by 3.333333
byte[] bytes = BitConverter.GetBytes(span.Days);
byte[] array = BitConverter.GetBytes(
(long)
(timeOfDay.TotalMilliseconds / 3.333333));
// Reverse the bytes to match SQL Servers ordering
Array.Reverse(bytes);
Array.Reverse(array);
Array.Reverse(bytes);
Array.Reverse(array);
// Copy the bytes into the guid
Array.Copy(bytes, bytes.Length – 2,
destinationArray,
destinationArray.Length – 6, 2);
Array.Copy(array, array.Length – 4,
destinationArray,
destinationArray.Length – 4, 4);
return new Guid(destinationArray);
}
Array.Copy(bytes, bytes.Length – 2,
destinationArray,
destinationArray.Length – 6, 2);
Array.Copy(array, array.Length – 4,
destinationArray,
destinationArray.Length – 4, 4);
return new Guid(destinationArray);
}
CREATE PROCEDURE [dbo].[NewRecordID]
(@NewId [UNIQUEIDENTIFIER] OUTPUT)
AS
BEGIN
—SET @NewId = NEWID() — generate new ID TEST AMAÇLI
SET @NewId= CAST(CAST(NEWID() AS BINARY(10)) + CAST(GETDATE() AS BINARY(6)) AS UNIQUEIDENTIFIER)
–SELECT @NewId –TEST AMAÇLI
SET @NewId= CAST(CAST(NEWID() AS BINARY(10)) + CAST(GETDATE() AS BINARY(6)) AS UNIQUEIDENTIFIER)
–SELECT @NewId –TEST AMAÇLI
END
Şimdi bu Stored Procedure nasıl şalıştırılacak onu yazalım. Öncelikle stored procedure çalıştırmak için sembolik bir UNIQUEIDENTIFIER değere ihtiyacımız var. Onu kullanarak SP çalıştırılacak ve SP yeni ID değerler üretecek
Exec [dbo].[NewRecordID] ‘B551F2C8-8380-491B-A51F-436E51CDD08F’ –sql SP testi
ve bu SP’nin üretiği eşsiz ID sonuçları :
76FAB26E-FB5F-4E4F-B21D-A38B00D36903
9B4BBA9E-D557-4B6D-BBE1-A38B00D37E62
B0382D9C-1B4A-4CC8-AC63-A38B00D39024
C079B776-0B3F-46D8-9A12-A38B00D3874C
76FAB26E-FB5F-4E4F-B21D-A38B00D36903
9B4BBA9E-D557-4B6D-BBE1-A38B00D37E62
B0382D9C-1B4A-4CC8-AC63-A38B00D39024
C079B776-0B3F-46D8-9A12-A38B00D3874C
KAYNAK : https://apoleptika.wordpress.com/2013/05/01/netsis-cari-hesaplarin-borc-alacak-bakiyelerini-gosteren-mobil-yazilim-gelistirme-1/
Bu değerli ve zaman kazandıran bilgi için Abdurrahman Hacıoğlu' na teşekkür ederim.
0 yorum:
Yorum Gönder