SQL सर्वर 2016 ने 'सिस्टम वर्जनेड टेम्पोरल टेबल' नामक एक फीचर पेश किया है। सामान्य तालिका का उपयोग करके, आप वर्तमान डेटा पुनर्प्राप्त कर सकते हैं; सिस्टम-संस्करण वाली अस्थायी तालिका का उपयोग करते समय, आप उस डेटा को पुनः प्राप्त कर सकते हैं जिसे पहले हटा दिया गया था या अद्यतन किया गया था। ऐसा करने के लिए, एक अस्थायी तालिका एक इतिहास तालिका बनाएगी। इतिहास तालिका पुराने डेटा को “start_time . के साथ संग्रहित करेगी ” और “अंत_समय " जो उस समयावधि को इंगित करता है जिसके लिए रिकॉर्ड सक्रिय था।
उदाहरण:यदि आप सामान्य तालिका को क्वेरी करके किसी उत्पाद की कीमत को 30 से 50 तक अपडेट करते हैं, तो आप अपडेट किए गए उत्पाद मूल्य को पुनः प्राप्त कर सकते हैं जो कि 50 है। एक अस्थायी तालिका का उपयोग करके, आप पुराने मान को पुनः प्राप्त कर सकते हैं जो कि 30 है।
टेम्पोरल टेबल का उपयोग करके, कोई निम्न कार्य कर सकता है:
- रिकॉर्ड का इतिहास ट्रैक करें :हम उस विशिष्ट रिकॉर्ड के मूल्य की समीक्षा कर सकते हैं, जिसे समय के साथ बदल दिया गया है।
- रिकॉर्ड-स्तरीय पुनर्प्राप्ति :यदि हमने तालिका से कोई विशिष्ट रिकॉर्ड हटा दिया है या कोई रिकॉर्ड दूषित है, तो हम इसे इतिहास तालिका से पुनर्प्राप्त कर सकते हैं।
टेम्पोरल टेबल रिकॉर्ड अपडेट की भौतिक तिथियों (कैलेंडर तिथि) के आधार पर रिकॉर्ड के दिनांक-समय को कैप्चर करते हैं और हटाते हैं। वर्तमान में, यह तार्किक तिथियों के आधार पर वर्जनिंग का समर्थन नहीं करता है। उदाहरण के लिए, यदि आप दोपहर 1:00 बजे UPDATE स्टेटमेंट का उपयोग करके उत्पाद का नाम अपडेट करते हैं, तो टेम्पोरल टेबल दोपहर 1:00 बजे तक उत्पाद के नाम का इतिहास बनाए रखेगा। उसके बाद नया नाम लागू होगा। हालाँकि, क्या होगा यदि उत्पाद का नाम परिवर्तन दोपहर 2:00 बजे से शुरू होना था? इसका मतलब है कि आपको स्टेटमेंट को काम करने के लिए समय पर पूरी तरह से अपडेट करना होगा और आपको UPDATE स्टेटमेंट को दोपहर 1:00 बजे के बजाय दोपहर 2:00 बजे निष्पादित करना चाहिए था।
अस्थायी तालिकाओं में निम्नलिखित पूर्वापेक्षाएँ होती हैं:
- प्राथमिक कुंजी परिभाषित की जानी चाहिए।
- डेटाटाइम2 डेटाटाइप के साथ प्रारंभ समय और समाप्ति समय रिकॉर्ड करने के लिए दो स्तंभों को परिभाषित किया जाना चाहिए। इन स्तंभों को SYSTEM_TIME स्तंभ कहा जाता है।
उनकी कुछ सीमाएँ भी हैं:
- ट्रिगर और इन-मेमोरी OLTP की अनुमति नहीं है।
- इतिहास तालिकाओं में कोई बाधा नहीं हो सकती।
- इतिहास तालिका में डेटा को संशोधित नहीं किया जा सकता है।
सिस्टम-संस्करण तालिका बनाना
एक साधारण सिस्टम-संस्करण तालिका बनाने के लिए निम्न स्क्रिप्ट का उपयोग किया जाएगा:
Use DemoDatabase Go CREATE TABLE dbo.Prodcuts ( Product_ID int identity (1,1) primary key , Product_Name varchar (500) , Product_Cost int , Quantity int , Product_Valid_From datetime2 GENERATED ALWAYS AS ROW START NOT NULL , Product_Valid_TO datetime2 GENERATED ALWAYS AS ROW END NOT NULL , PERIOD FOR SYSTEM_TIME (Product_Valid_From,Product_Valid_TO) ) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE =dbo.Product_Change_History));
उपरोक्त लिपि में, मैंने dbo नाम के HISTORY_TABLE को परिभाषित किया है। उत्पाद_चेंज_इतिहास। यदि आप इतिहास तालिका के लिए कोई नाम निर्दिष्ट नहीं करते हैं, तो SQL सर्वर स्वचालित रूप से निम्नलिखित संरचना के साथ एक इतिहास तालिका बना देगा।
Dbo.MSSQL_TemporalHistoryFor_xxx, जहां xxx ऑब्जेक्ट आईडी है।
टेम्पोरल टेबल वैसा ही दिखेगा जैसा नीचे स्क्रीनशॉट में दिखाया गया है:
टेम्पोरल टेबल पर डीएमएल स्टेटमेंट निष्पादित करते समय पीरियड कॉलम कैसे अपडेट होंगे?
जब भी हम टेम्पोरल टेबल पर किसी क्वेरी को इंसर्ट, अपडेट और डिलीट करते हैं, तो पीरियड कॉलम (SysStartDate और SysEndDate) अपडेट हो जाएंगे।
क्वेरी सम्मिलित करें
जब हम टेम्पोरल टेबल पर INSERT ऑपरेशन करते हैं, तो सिस्टम SysStartTime कॉलम का मान वर्तमान लेनदेन के प्रारंभ समय पर सेट करता है और पंक्ति को खुले के रूप में चिह्नित करता है।
आइए 'उत्पाद . में कुछ पंक्तियां डालें ' तालिका और समीक्षा करें कि इस तालिका में डेटा कैसे संग्रहीत किया जाता है।
INSERT INTO prodcuts (product_name, product_cost, quantity) VALUES ( 'Mouse', 500, 10 ), ( 'Key-Board', 200, 5 ), ( 'Headset', 500, 1 ), ( 'Laptop', 50000, 1 ) select * from Prodcuts
जैसा कि ऊपर स्क्रीनशॉट में दिखाया गया है, 'Product_Valid_From . का मान ' कॉलम है '2018-04-02 06:55:04.4865670 ' जो पंक्ति डालने की तारीख है। और 'Product_Valid_To . का मान ' कॉलम है '9999-12-31 23:59:59.99999999 ', जो इंगित करता है कि पंक्ति खुली है।
अपडेट क्वेरी
जब हम टेम्पोरल टेबल पर किसी भी अपडेट क्वेरी को निष्पादित करते हैं, तो सिस्टम इतिहास तालिका में पिछली पंक्ति मानों को संग्रहीत करेगा और वर्तमान लेनदेन समय को एंडटाइम के रूप में सेट करेगा। और वर्तमान तालिका को एक नए मान के साथ अपडेट करें। SysStartTime लेन-देन का प्रारंभ समय और SysEndTime . होगा अधिकतम 9999-12-31 होगा।
आइए 'माउस . की उत्पाद लागत बदलें ' 500 से 250 तक। हम 'उत्पाद . के आउटपुट की जांच करेंगे '.
Begin tran UpdatePrice Update Prodcuts set Product_cost=200 where Product_name='Mouse' Commit tran UpdatePrice select * from Prodcuts where Product_name='Mouse'
जैसा कि आप ऊपर दिए गए स्क्रीनशॉट में देख सकते हैं, 'Product_Valid_From . का मान ' कॉलम बदल दिया गया है। नया मान वर्तमान लेनदेन समय (UTC) है। और 'Product_Valid_To . का मान ' कॉलम है '9999-12-31 23:59:59.99999999 ’, जो इंगित करता है कि पंक्ति खुली हुई है और उसने कीमत अपडेट कर दी है।
आइए Product_change_history . के आउटपुट को देखें तालिका को क्वेरी करके।
select * from Product_Change_History where Product_name='Mouse'
जैसा कि आप ऊपर दिए गए स्क्रीनशॉट में देख सकते हैं, Product_change_history में एक पंक्ति जोड़ दी गई है तालिका, जिसमें पंक्ति का पुराना संस्करण है। 'Product_cost . का मान ' 500 है, 'Product_valid_From . का मान ' वह समय है जब रिकॉर्ड डाला गया था और Product_Valid_To . का मान था कॉलम तब होता है जब Product_cost कॉलम . का मान होता है सुधार किया गया था। इस पंक्ति संस्करण को बंद माना जाता है।
क्वेरी हटाएं
जब हम टेम्पोरल टेबल से एक रिकॉर्ड हटाते हैं, तो सिस्टम इतिहास तालिका में पंक्ति के वर्तमान संस्करण को संग्रहीत करेगा और वर्तमान लेनदेन समय को एंडटाइम के रूप में सेट करेगा और वर्तमान तालिका से रिकॉर्ड को हटा देगा।
आइए 'हेडसेट' के रिकॉर्ड को हटा दें।
Begin tran DeletePrice delete from Prodcuts where product_name='Headset' Commit tran DeletePrice
आइए Product_change_history . के आउटपुट को देखें तालिका को क्वेरी करके।
select * from Product_Change_History where Product_name='Headset'
जैसा कि आप ऊपर दिए गए स्क्रीनशॉट में देख सकते हैं, Product_change_history . में एक पंक्ति जोड़ दी गई है तालिका, जिसे वर्तमान तालिका से हटा दिया गया था। 'Product_valid_From . का मान ' वह समय है जब रिकॉर्ड डाला गया था और Product_Valid_To . का मान था कॉलम वह समय है जब पंक्ति को हटा दिया गया था जो इंगित करता है कि पंक्ति संस्करण बंद है।
एक विशिष्ट समय के लिए डेटा परिवर्तनों का ऑडिट करना
किसी विशिष्ट तालिका के डेटा परिवर्तनों का ऑडिट करने के लिए, हमें अस्थायी तालिकाओं का समय-आधारित विश्लेषण करना चाहिए। ऐसा करने के लिए, हमें 'SYSTEM_TIME के लिए . का उपयोग करना चाहिए ' वर्तमान और इतिहास तालिकाओं में क्वेरी डेटा के लिए अस्थायी-विशिष्ट उप-खंडों के साथ खंड। मुझे विभिन्न उप-खंडों का उपयोग करके प्रश्नों के आउटपुट की व्याख्या करने दें। नीचे सेटअप है:
- मैंने सुबह 09:02:25 बजे टेम्पोरल टेबल में सूची मूल्य 0.00 के साथ 'फ्लैट वॉशर 8' नाम का एक उत्पाद डाला।
- मैंने सुबह 10:13:56 बजे सूची मूल्य बदल दिया। नई कीमत 500.00 है।
. के अनुसार
इस खंड का उपयोग AS OF . में एक निश्चित समय के लिए रिकॉर्ड की स्थिति को पुनः प्राप्त करने के लिए किया जाएगा उपखंड। इसे समझने के लिए, आइए कई प्रश्नों को निष्पादित करें:
सबसे पहले, हम AS OF . का उपयोग करके एक क्वेरी निष्पादित करेंगे खंड "SystemTime =10:15:59 . के साथ .
select Name, ListPrice,rowguid,Product_Valid_From,Product_Valid_TO from DemoDatabase.dbo.tblProduct FOR system_time as of '2018-04-20 10:15:56 where name ='Flat Washer 8'के अनुसार DemoDatabase.dbo.tblProduct For system_time से Name, ListPrice, Rowguid,Product_Valid_From,Product_Valid_TO चुनें।
अब जैसा कि आप उपरोक्त स्क्रीनशॉट में देख सकते हैं, क्वेरी ने "ListPrice के अद्यतन मान के साथ एक पंक्ति लौटा दी है। ” और Product_Valid_To . का मान अधिकतम तिथि है।
आइए AS OF c . का उपयोग करके एक और क्वेरी निष्पादित करें "सिस्टमटाइम =09:10:56: . के साथ लॉज़ करें .
अब जैसा कि आप ऊपर दिए गए स्क्रीनशॉट में देख सकते हैं, “ListPrice . का मान " 0.00 है।
से तक
यह खंड
select Name, ListPrice,rowguid,Product_Valid_From,Product_Valid_TO,ListPrice from DemoDatabase.dbo.tblProduct FOR system_time from '2018-04-20 09:02:25 to '2018-04-20 10:13:56 where name = 'Flat Washer 8'
निम्न स्क्रीनशॉट क्वेरी परिणाम दिखाता है:
के बीच और
यह खंड FROM.. . के समान है प्रति खंड। फर्क सिर्फ इतना है कि इसमें वे रिकॉर्ड शामिल होंगे जो
select Name, ListPrice,rowguid,Product_Valid_From,Product_Valid_TO,ListPrice from DemoDatabase.dbo.tblProduct FOR system_time between '2018-04-20 09:02:25.1265684' and '2018-04-20 10:13:56.1265684' where name = 'Flat Washer 8'
निम्न स्क्रीनशॉट क्वेरी परिणाम दिखाता है:
में शामिल (, )
इस उप-खंड में वे रिकॉर्ड शामिल होंगे जो सक्रिय हो गए और निर्दिष्ट तिथि सीमा के भीतर समाप्त हो गए। इसमें सक्रिय रिकॉर्ड शामिल नहीं हैं। इसे समझने के लिए, "Contained IN '2018-04-20 09:02:25 का उपयोग करके नीचे दी गई क्वेरी को निष्पादित करें। ' से '2018-04-20 10:14:56' तक "
select Name, ListPrice,rowguid,Product_Valid_From,Product_Valid_TO,ListPrice from DemoDatabase.dbo.tblProduct FOR system_time Contained IN( '2018-04-20 09:02:25' , '2018-04-20 10:13:56 ') where name = 'Flat Washer 8'
निम्न स्क्रीनशॉट क्वेरी परिणाम दिखाता है:
परिदृश्य
एक संगठन एक इन्वेंट्री सॉफ़्टवेयर का उपयोग कर रहा है। वह इन्वेंट्री सॉफ़्टवेयर एक उत्पाद तालिका का उपयोग करता है जो एक सिस्टम संस्करण अस्थायी तालिका है। एप्लिकेशन बग के कारण, कुछ उत्पादों को हटा दिया गया था, और उत्पादों की कीमतों को भी गलत तरीके से अपडेट किया गया था।
डीबीए के रूप में, हमें इस मुद्दे की जांच करनी चाहिए और उस डेटा को पुनर्प्राप्त करना चाहिए जिसे गलत तरीके से अपडेट किया गया था और तालिका से हटा दिया गया था।
उपरोक्त परिदृश्य का अनुकरण करने के लिए, आइए कुछ सार्थक डेटा के साथ एक तालिका बनाएं। मैं 'tblProduct . नाम की एक नई अस्थायी तालिका बनाने जा रहा हूं ' डेमो डेटाबेस पर जो [उत्पादन] का एक क्लोन है।[उत्पाद] AdventureWorks2014 डेटाबेस की तालिका।
उपरोक्त कार्य करने के लिए, मैंने नीचे दिए गए चरणों का पालन किया है:
- एक्सट्रैक्टेड "क्रिएट टेबल स्क्रिप्ट" [प्रोडक्शन]। [उत्पाद] AdventureWorks2014 डेटाबेस से।
- स्क्रिप्ट से सभी "बाधाएं और अनुक्रमित" हटा दिए गए।
- स्तंभ संरचना को अपरिवर्तित रखा।
- इसे अस्थायी तालिका में बदलने के लिए, मैंने SysStartTime और SysEndTime कॉलम जोड़े।
- सक्षम System_Versioning.
- निर्दिष्ट इतिहास तालिका।
- वें edemo डेटाबेस पर स्क्रिप्ट निष्पादित।
नीचे स्क्रिप्ट है:
USE [DemoDatabase] GO CREATE TABLE [tblProduct]( [ProductID] [int] IDENTITY(1,1) Primary Key, [Name] varchar(500) NOT NULL, [ProductNumber] [nvarchar](25) NOT NULL, [Color] [nvarchar](15) NULL, [SafetyStockLevel] [smallint] NOT NULL, [ReorderPoint] [smallint] NOT NULL, [StandardCost] [money] NOT NULL, [ListPrice] [money] NOT NULL, [Size] [nvarchar](5) NULL, [SizeUnitMeasureCode] [nchar](3) NULL, [WeightUnitMeasureCode] [nchar](3) NULL, [Weight] [decimal](8, 2) NULL, [DaysToManufacture] [int] NOT NULL, [ProductLine] [nchar](2) NULL, [Class] [nchar](2) NULL, [Style] [nchar](2) NULL, [ProductSubcategoryID] [int] NULL, [ProductModelID] [int] NULL, [SellStartDate] [datetime] NOT NULL, [SellEndDate] [datetime] NULL, [DiscontinuedDate] [datetime] NULL, [rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL, [ModifiedDate] [datetime] NOT NULL, Product_Valid_From datetime2 GENERATED ALWAYS AS ROW START NOT NULL , Product_Valid_TO datetime2 GENERATED ALWAYS AS ROW END NOT NULL , PERIOD FOR SYSTEM_TIME (Product_Valid_From,Product_Valid_TO) ) WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE =dbo.Product_History)); GO
मैंने निम्नलिखित स्क्रिप्ट को निष्पादित करके "एडवेंचरवर्क्स2014" डेटाबेस की उत्पाद तालिका से "डेमोडेटाबेस" की उत्पाद तालिका में डेटा आयात किया है:
insert into DemoDatabase.dbo.tblProduct (Name ,ProductNumber ,Color ,SafetyStockLevel ,ReorderPoint ,StandardCost ,ListPrice ,Size ,SizeUnitMeasureCode ,WeightUnitMeasureCode ,Weight ,DaysToManufacture ,ProductLine ,Class ,Style ,ProductSubcategoryID ,ProductModelID ,SellStartDate ,SellEndDate ,DiscontinuedDate ,rowguid ,ModifiedDate) select top 50 Name ,ProductNumber ,Color ,SafetyStockLevel ,ReorderPoint ,StandardCost ,ListPrice ,Size ,SizeUnitMeasureCode ,WeightUnitMeasureCode ,Weight ,DaysToManufacture ,ProductLine ,Class ,Style ,ProductSubcategoryID ,ProductModelID ,SellStartDate ,SellEndDate ,DiscontinuedDate ,rowguid ,ModifiedDate from AdventureWorks2014.Production.Product
मैंने tblProduct से 'थिन-जैम हेक्स नट' से शुरू होने वाले उत्पाद नाम रिकॉर्ड हटा दिए हैं। मैंने 'tblProduct पर फ्लैट वॉशर के नाम से शुरू होने वाले उत्पादों की कीमत भी बदल दी है। निम्न क्वेरी निष्पादित करके तालिका:
delete from DemoDatabase.dbo.Product where name like '%Thin-Jam Hex Nut%' waitfor delay '00:01:00' update DemoDatabase.dbo.tblProduct set ListPrice=500.00 where name like '%Flat Washer%'
हम उस समय से अवगत हैं जब डेटा हटा दिया गया था। इसलिए यह पहचानने के लिए कि कौन सा डेटा हटा दिया गया है, हम Contained-IN उप-खंड का उपयोग करेंगे। जैसा कि मैंने ऊपर उल्लेख किया है, यह मुझे उन अभिलेखों की सूची देगा जिनमें पंक्ति-संस्करण हैं जो सक्रिय हो गए और निर्दिष्ट तिथि सीमा के भीतर समाप्त हो गए। फिर, क्वेरी के नीचे निष्पादित:
declare @StartDateTime datetime declare @EndDateTime datetime set @StartDateTime=convert (datetime2, getdate()-1) set @EndDateTime=convert (datetime2, getdate()) select ProductID, Name, ProductNumber,Product_Valid_From, Product_Valid_To from Product For SYSTEM_TIME Contained IN ( @StartDateTime , @EndDateTime)
उपरोक्त क्वेरी को निष्पादित करके, 22 पंक्तियों को पुनः प्राप्त कर लिया गया है।
निहित-इन क्लॉज उन पंक्तियों को पॉप्युलेट करेगा जिन्हें दिए गए समय के दौरान अद्यतन और हटा दिया गया था।
हटाए गए रिकॉर्ड्स को पॉप्युलेट करें:
हटाए गए रिकॉर्ड्स को पॉप्युलेट करने के लिए, हमें उन रिकॉर्ड्स को छोड़ देना चाहिए जिन्हें कंटेन्ड-इन क्लॉज में निर्दिष्ट समय के दौरान अपडेट किया गया था। नीचे लिपि में, “कहां " क्लॉज उन उत्पादों को छोड़ देगा जो tblProduct . में मौजूद हैं टेबल। हम निम्नलिखित क्वेरी निष्पादित करेंगे:
declare @StartDateTime datetime declare @EndDateTime datetime set @StartDateTime=convert(datetime2,getdate()-1) set @EndDateTime=convert(datetime2,getdate()) select ProductID, Name, ProductNumber,Product_Valid_From, Product_Valid_To from tblProduct For SYSTEM_TIME Contained IN ( @StartDateTime , @EndDateTime) Where Name not in (Select Name from tblProduct)
उपरोक्त क्वेरी ने उन रिकॉर्ड्स को छोड़ दिया है जिन्हें अपडेट किया गया है; इसलिए इसने 13 पंक्तियाँ लौटा दीं। नीचे स्क्रीनशॉट देखें:
उपरोक्त विधि का उपयोग करके, हम उन उत्पादों की सूची प्राप्त करने में सक्षम होंगे जिन्हें tblProduct से हटा दिया गया है टेबल।
अपडेट किए गए रिकॉर्ड पॉप्युलेट करें
अपडेट किए गए रिकॉर्ड्स को पॉप्युलेट करने के लिए, हमें उन रिकॉर्ड्स को छोड़ देना चाहिए जो Contained-IN में निर्दिष्ट समय के दौरान हटा दिए गए थे। खंड। नीचे लिपि में, “कहां " खंड में वे उत्पाद शामिल होंगे जो tblProduct . में मौजूद हैं टेबल। हम निम्नलिखित क्वेरी निष्पादित करेंगे:
declare @StartDateTime datetime declare @EndDateTime datetime set @StartDateTime=convert(datetime2,getdate()-1) set @EndDateTime=convert(datetime2,getdate()) select ProductID, Name, ProductNumber,Product_Valid_From, Product_Valid_To from tblProduct For SYSTEM_TIME Contained IN ( @StartDateTime , @EndDateTime) Where Name in (Select Name from tblProduct)
उपरोक्त क्वेरी ने उन रिकॉर्ड्स को छोड़ दिया है जिन्हें अपडेट किया गया है इसलिए इसने 9 पंक्तियों को वापस कर दिया है। नीचे स्क्रीनशॉट देखें:
उपरोक्त विधि का उपयोग करके, हम उन अभिलेखों की पहचान करने में सक्षम होंगे जिन्हें गलत मानों के साथ अद्यतन किया गया है और जो रिकॉर्ड अस्थायी तालिका से हटा दिए गए हैं।
सारांश
इस लेख में, मैंने कवर किया है:
- अस्थायी तालिकाओं का उच्च-स्तरीय परिचय।
- यह समझाया गया है कि डीएमएल क्वेरी को क्रियान्वित करके अवधि कॉलम कैसे अपडेट किए जाएंगे।
- टेम्पोरल टेबल से उन उत्पादों की सूची को पुनः प्राप्त करने के लिए एक डेमो जिन्हें हटा दिया गया है और गलत कीमत के साथ अपडेट किया गया है। इस रिपोर्ट का उपयोग ऑडिटिंग उद्देश्य के लिए किया जा सकता है।