إنشاء قيم تلقائية
قد تحتاج إلى إنشاء قيم متسلسلة لعمود واحد في جدول معين تلقائيًا. يوفر SQL بالطريقتين للقيام بذلك: استخدام الخاصية IDENTITY مع عمود معين في جدول، أو تعريف كائن تسلسل واستخدام القيم التي تم إنشاؤها بواسطة هذا الكائن.
الخاصية IDENTITY
لاستخدام الخاصية IDENTITY، عليك تعريف عمود باستخدام نوع بيانات رقمي بمقياس بالقيمة 0 (بمعنى الأعداد الصحيحة فقط) ثم بادر بتضمين الكلمة الأساسية IDENTITY. تتضمن الأنواع المسموح بها كل أنواع الأعداد الصحيحة والأنواع العشرية حيث يمكنك بوضوح توفير المقياس 0.
يمكن أيضا تحديد قيمة أولية اختيارية (قيمة البدء) وزيادة (قيمة الخطوة). سيؤدي ترك القيم الأولية والزيادة إلى تعيينهما إلى 1.
إشعار
يتم تحديد الخاصية IDENTITY بدلاً من تحديد NUL أو NOT NULL في تعريف العمود. أي عمود يتضمن الخاصة IDENTITY لا يكون بدون قيمة تلقائيًا. يمكنك تحديد NOT NULL فقط للوثائق الذاتية ولكن في حالة تحديد العمود على أنه NULL (بمعنى بدون قيمة)، سيتم من خلال عبارة إنشاء الجدول إنشاء خطأ.
يمكن تعيين الخاصية IDENTITY في عمود واحد في جدول؛ حيث يتم استخدامه بشكل متكرر على أنه المفتاح الأساسي أو مفتاح بديل.
تظهر التعليمات البرمجية التالية إنشاء الجدول Sales.Promotion المستخدم في أمثلة القسم السابق، ولكن هذه المرة مع عمود هوية المسمى PromotionID كمفتاح أساسي:
CREATE TABLE Sales.Promotion
(
PromotionID int IDENTITY PRIMARY KEY,
PromotionName varchar(20),
StartDate datetime NOT NULL DEFAULT GETDATE(),
ProductModelID int NOT NULL REFERENCES Production.ProductModel(ProductModelID),
Discount decimal(4,2) NOT NULL,
Notes nvarchar(max) NULL
);
إشعار
التفاصيل الكاملة لعبارة CREATE TABLE خارج نطاق هذه الوحدة.
إدراج بيانات في عمود هوية
عندما يتم تعريف الخاصية IDENTITY لعمود، لا تحدد عبارات INSERT في الجدول عمومًا قيمة لعمود IDENTITY. يتم من خلال محرك قاعدة البيانات إنشاء قيمة باستخدام القيمة المتوفرة التالية للعمود.
على سبيل المثال، يمكنك إدراج صف في الجدول Sales.Promotion دون تحديد قيمة لعمود PromotionID:
INSERT INTO Sales.Promotion
VALUES
('Clearance Sale', '01/01/2021', 23, 0.10, '10% discount')
لاحظ أنه على الرغم من أن جملة VALUES لا تتضمن قيمة للعمود PromotionID، لا تحتاج إلى تحديد قائمة أعمدة في جملة INSERT - أعمدة الهوية مُعفاة من هذا المتطلب.
إذا كان هذا الصف هو الصف الأول الذي تم إدراجه في الجدول، تكون النتيجة هي صف جديد مثل هذا:
PromotionID
PromotionName
StartDate
ProductModelID
Discount
الملاحظات
1
بيع التخليص
2021-01-01T00:00:00
23
0.1
خصم 10%
عند إنشاء الجدول، لم يتم تعيين القيم الأولية أو الزيادة لعمود IDENTITY، لذلك يتم إدراج الصف الأول بالقيمة 1. سيتم تعيين PromotionID بالقيمة 2 إلى الصف التالي الذي سيتم إدراجه، وهكذا.
استرداد قيمة هوية
لإرجاع أحدث قيمة IDENTITY معينة ضمن نفس جلسة العمل والنطاق، استخدم الدالة SCOPE_IDENTITY؛ مثل هذا:
SELECT SCOPE_IDENTITY();
تُرجع الدالة SCOPE_IDENTITY أحدث قيمة هوية تم إنشاؤها في النطاق الحالي لأي جدول. إذا كنت بحاجة إلى أحدث قيمة هوية في جدول معين، يمكنك استخدام الدالة IDENT_CURRENT، مثل هذا:
SELECT IDENT_CURRENT('Sales.Promotion');
تجاوز قيم الهوية
إذا كنت ترغب في تجاوز القيمة التي تم إنشاؤها تلقائيًا وتعيين قيمة معينة إلى عمود IDENTITY، تحتاج أولاً إلى تمكين إدراجات الهوية باستخدام العبارة SET IDENTITY INSERT table_name ON. مع تمكين هذا الخيار، يمكنك إدراج قيمة صريحة لعمود الهوية، تمامًا مثل أي عمود آخر. عند الانتهاء، يمكنك استخدام العبارة SET IDENTITY INSERT table_name OFF لاستئناف استخدام قيم الهوية التلقائية، باستخدام القيمة الأخيرة التي أدخلتها بشكل صريح كقيمة أولية.
SET IDENTITY_INSERT SalesLT.Promotion ON;
INSERT INTO SalesLT.Promotion (PromotionID, PromotionName, ProductModelID, Discount)
VALUES
(20, 'Another short sale',37, 0.3);
SET IDENTITY_INSERT SalesLT.Promotion OFF;
كما تعلمت، يتم استخدام خاصية IDENTITY لإنشاء تسلسل قيم لعمود داخل جدول. ومع ذلك، فإن خاصية IDENTITY غير مناسبة لتنسيق القيم عبر جداول متعددة داخل قاعدة بيانات. على سبيل المثال، افترض أن مؤسستك تفرق بين المبيعات المباشرة والمبيعات إلى البائعين، وتريد تخزين البيانات لهذه المبيعات في جداول منفصلة. قد يحتاج كلا النوعين من البيع إلى رقم فاتورة فريد، وقد ترغب في تجنب تكرار نفس القيمة لنوعين مختلفين من البيع. أحد الحلول لهذا المتطلب هو الاحتفاظ بمجموعة من القيم التسلسلية الفريدة عبر كلا الجدولين.
إعادة تغذية عمود هوية
في بعض الأحيان، ستحتاج إلى إعادة تعيين قيم الهوية للعمود أو تخطيها. للقيام بذلك، ستقوم "بإعادة تغذية" العمود باستخدام وظيفة DBCC CHECKIDENT. يمكنك استخدام هذا لتخطي العديد من القيم، أو لإعادة تعيين قيمة الهوية التالية إلى 1 بعد حذف كافة الصفوف في الجدول. للحصول على التفاصيل الكاملة باستخدام DBCC CHECKIDENT، راجع الوثائق المرجعية لـTransact-SQL.
تسلسل
في Transact-SQL، يمكنك استخدام كائن تسلسل لتحديد قيم تسلسلية جديدة بشكل مستقل عن جدول معين. يتم إنشاء كائن تسلسل باستخدام عبارة CREATE SEQUENCE، حيث يتم توفير نوع البيانات اختياريًا (يجب أن يكون نوع عدد صحيح أو عشري أو رقمي بمقياس بالقيمة 0)، وقيمة البدء وقيمة الزيادة والقيمة القصوى، والخيارات الأخرى المتعلقة بالأداء.
CREATE SEQUENCE Sales.InvoiceNumber AS INT
START WITH 1000 INCREMENT BY 1;
لاسترداد القيمة المتوفرة التالية من تسلسل، استخدم البناء NEXT VALUE FOR، مثل هذا:
INSERT INTO Sales.ResellerInvoice
VALUES
(NEXT VALUE FOR Sales.InvoiceNumber, 2, GETDATE(), 'PO12345', 107.99);
IDENTITY أو SEQUENCE
عند تحديد ما إذا كان سيتم استخدام أعمدة IDENTITY أو كائن SEQUENCE لقيم التعبئة التلقائية، تذكر النقاط التالية:
استخدم SEQUENCE إذا تطلب التطبيق مشاركة سلسلة واحدة من الأرقام بين جداول متعددة أو أعمدة متعددة داخل جدول.
تسمح SEQUENCE لك بفرز القيم حسب عمود آخر. يمكن أن يتم من خلال البناء NEXT VALUE FOR استخدام الجملة OVER لتحديد عمود الفرز. تضمن جملة OVER أن القيم التي تم إرجاعها يتم إنشاؤها بترتيب جملة ORDER BY الخاصة بجملة OVER. تتيح لك هذه الوظيفة أيضًا إنشاء أرقام صفوف للصفوف أثناء إرجاعها في SELECT. في المثال التالي، يتم فرز الجدول Production.Product حسب العمود Name، والعمود الأول الذي تم إرجاعه هو رقم تسلسلي.
SELECT NEXT VALUE FOR dbo.Sequence OVER (ORDER BY Name) AS NextID, ProductID, Name FROM Production.Product;على الرغم من أن العبارة السابقة كانت مجرد تحديد قيم SEQUENCE لعرضها، إلا أن القيم لا تزال "قيد الاستخدام" ولن تتوفر قيم SEQUENCE المعروضة بعد الآن. في حالة تشغيل SELECT أعلاه عدة مرات، ستحصل على قيم SEQUENCE مختلفة في كل مرة.
استخدم SEQUENCE إذا تطلب التطبيق تعيين أرقام متعددة في نفس الوقت. على سبيل المثال، يحتاج التطبيق إلى حجز خمسة أرقام متسلسلة. قد يؤدي طلب قيم الهوية إلى ثغرات في السلسلة إذا تم أصدرت عمليات أخرى أرقام بشكل متزامن. يمكنك استخدام إجراء النظام sp_sequence_get_range لاسترداد عدة أرقام في التسلسل في وقت واحد.
تسمح SEQUENCE لك بتغيير مواصفات التسلسل، مثل قيمة الزيادة.
تتم حماية قيم IDENTITY من التحديثات. إذا حاولت تحديث عمود يضم الخاصية IDENTITY، فستحصل على خطأ.