इस लेख के पिछले भाग में, हमने बल्क इन्सर्ट स्टेटमेंट की मदद से सीएसवी फाइलों को SQL सर्वर में आयात करने के तरीके पर चर्चा की। हमने बल्क इंसर्ट प्रक्रिया की मुख्य कार्यप्रणाली और परिदृश्यों में BATCHSIZE और MAXERRORS विकल्पों के विवरण पर भी चर्चा की। इस भाग में, हम विभिन्न परिदृश्यों में बल्क इंसर्ट प्रक्रिया के कुछ अन्य विकल्पों (FIRE_TRIGGERS, CHECK_CONSTRAINTS और TABLOCK) से गुजरेंगे।
परिदृश्य 1:क्या हम बल्क इंसर्ट ऑपरेशन के दौरान गंतव्य तालिका में ट्रिगर सक्षम कर सकते हैं?
डिफ़ॉल्ट रूप से, थोक सम्मिलन प्रक्रिया के दौरान, लक्ष्य तालिका में निर्दिष्ट सम्मिलित ट्रिगर सक्रिय नहीं होते हैं, हालांकि, कुछ स्थितियों में हम इन ट्रिगर को सक्षम करना चाह सकते हैं। इस समस्या का समाधान बल्क इंसर्ट स्टेटमेंट में FIRE_TRIGGERS विकल्प का उपयोग करना है। मैं एक नोटिस जोड़ना चाहता हूं कि यह विकल्प थोक सम्मिलन ऑपरेशन प्रदर्शन को प्रभावित और घटा सकता है क्योंकि ट्रिगर/ट्रिगर डेटाबेस में अलग-अलग संचालन कर सकते हैं। निम्नलिखित नमूने में, हम इसे प्रदर्शित करेंगे। सबसे पहले, हम FIRE_TRIGGERS पैरामीटर सेट नहीं करेंगे और बल्क इंसर्ट प्रक्रिया इंसर्ट ट्रिगर को सक्रिय नहीं करेगी। निम्नलिखित टी-एसक्यूएल स्क्रिप्ट में, हम बिक्री तालिका के लिए एक सम्मिलित ट्रिगर परिभाषित करेंगे।
DROP TABLE IF EXISTS Sales
CREATE TABLE [dbo].[Sales](
[Region] [varchar](50) ,
[Country] [varchar](50) ,
[ItemType] [varchar](50) NULL,
[SalesChannel] [varchar](50) NULL,
[OrderPriority] [varchar](50) NULL,
[OrderDate] datetime,
[OrderID] bigint NULL,
[ShipDate] datetime,
[UnitsSold] float,
[UnitPrice] float,
[UnitCost] float,
[TotalRevenue] float,
[TotalCost] float,
[TotalProfit] float
)
DROP TABLE IF EXISTS SalesLog
CREATE TABLE SalesLog (OrderIDLog bigint)
GO
CREATE TRIGGER OrderLogIns ON Sales
FOR INSERT
AS
BEGIN
SET NOCOUNT ON
INSERT INTO SalesLog
SELECT OrderId from inserted
end
GO
BULK INSERT Sales
FROM 'C:\1500000 Sales Records.csv'
WITH (FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR='\n'
);
SELECT Count(*) FROM SalesLog

जैसा कि आप ऊपर देख सकते हैं, सम्मिलित ट्रिगर सक्रिय नहीं हुआ क्योंकि हमने FIRE_TRIGGERS विकल्प सेट नहीं किया था। अब, हम FIRE_TRIGGERS विकल्प को बल्क इंसर्ट स्टेटमेंट में जोड़ देंगे ताकि यह विकल्प फायर ट्रिगर डालने में सक्षम हो जाए।
BULK INSERT Sales FROM 'C:\1500000 Sales Records.csv' WITH (FIRSTROW = 2, FIELDTERMINATOR = ',', ROWTERMINATOR='\n', FIRE_TRIGGERS); GO SELECT Count(*) as [NumberOfRowsinTriggerTable] FROM SalesLog

परिदृश्य 2:बल्क इंसर्ट ऑपरेशन के दौरान चेक बाधा को कैसे सक्षम किया जा सकता है?
जाँच की कमी हमें SQL सर्वर तालिकाओं में डेटा अखंडता को लागू करने की अनुमति देती है। बाधा का उद्देश्य उनके सिंटैक्स विनियमन के अनुसार सम्मिलित, अद्यतन या हटाए गए मानों की जांच करना है। जैसे, NOT NULL बाधा यह प्रदान करती है कि एक निर्दिष्ट कॉलम को NULL मान द्वारा संशोधित नहीं किया जा सकता है। अब, हम बाधाओं और बल्क इंसर्ट इंटरैक्शन पर ध्यान केंद्रित करेंगे। डिफ़ॉल्ट रूप से, बल्क इंसर्ट प्रक्रिया के दौरान किसी भी चेक और विदेशी कुंजी बाधाओं को नजरअंदाज कर दिया जाता है, लेकिन इस विकल्प में कुछ अपवाद हैं। Microsoft दस्तावेज़ के अनुसार "अद्वितीय और प्राथमिक कुंजी बाधाएं हमेशा लागू की जाती हैं। किसी वर्ण स्तंभ में आयात करते समय जिसके लिए NOT NULL बाधा परिभाषित की गई है, टेक्स्ट फ़ाइल में कोई मान न होने पर बल्क INSERT एक रिक्त स्ट्रिंग सम्मिलित करता है।" निम्नलिखित टी-एसक्यूएल स्क्रिप्ट में, हम ऑर्डरडेट कॉलम में एक चेक बाधा जोड़ेंगे जो 01.01.2016 से अधिक ऑर्डर तिथि को नियंत्रित करता है।
DROP TABLE IF EXISTS Sales
CREATE TABLE [dbo].[Sales](
[Region] [varchar](50) ,
[Country] [varchar](50) ,
[ItemType] [varchar](50) NULL,
[SalesChannel] [varchar](50) NULL,
[OrderPriority] [varchar](50) NULL,
[OrderDate] datetime,
[OrderID] bigint NULL,
[ShipDate] datetime,
[UnitsSold] float,
[UnitPrice] float,
[UnitCost] float,
[TotalRevenue] float,
[TotalCost] float,
[TotalProfit] float
)
ALTER TABLE [Sales] ADD CONSTRAINT OrderDate_Check
CHECK(OrderDate >'20160101')
BULK INSERT Sales
FROM 'C:\1500000 Sales Records.csv'
WITH (FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR='\n'
);
GO
SELECT COUNT(*) AS [UnChekedData] FROM
Sales WHERE OrderDate <'20160101'

जैसा कि आप उपरोक्त नमूने में देख सकते हैं, बल्क इंसर्ट प्रक्रिया चेक बाधा नियंत्रण को छोड़ देती है। हालाँकि, SQL सर्वर चेक बाधा को अविश्वसनीय के रूप में इंगित करता है।
SELECT is_not_trusted ,* FROM sys.check_constraints where name='OrderDate_Check'

यह मान इंगित करता है कि किसी ने चेक बाधा को छोड़ कर इस कॉलम में कुछ डेटा डाला या अपडेट किया है, साथ ही इस कॉलम में उस बाधा के संदर्भ में असंगत डेटा हो सकता है। अब, हम CHECK_CONSTRAINTS विकल्प के साथ बल्क इंसर्ट स्टेटमेंट को निष्पादित करने का प्रयास करेंगे। परिणाम बहुत आसान है, जाँच बाधा अनुचित डेटा के कारण त्रुटि देता है।
BULK INSERT Sales
FROM 'C:\1500000 Sales Records.csv'
WITH (FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR='\n'
);

परिदृश्य 3:एक गंतव्य तालिका में एकाधिक थोक प्रविष्टियों में प्रदर्शन कैसे बढ़ाएं?
SQL सर्वर में लॉकिंग मैकेनिज्म का मुख्य उद्देश्य डेटा की अखंडता की रक्षा करना और सुनिश्चित करना है। SQL सर्वर लॉकिंग आलेख की मुख्य अवधारणा में, आप लॉक तंत्र के बारे में विवरण प्राप्त कर सकते हैं। अब, हम बल्क इंसर्ट प्रोसेस लॉकिंग विवरण पर ध्यान केंद्रित करेंगे। यदि आप TABLELOCK विकल्प के बिना बल्क इंसर्ट स्टेटमेंट चलाते हैं, तो यह लॉक पदानुक्रम के अनुसार पंक्तियों या तालिका के लॉक को प्राप्त कर लेता है। हालाँकि, कुछ मामलों में, हम एक गंतव्य तालिका के विरुद्ध कई बल्क इंसर्ट प्रक्रियाओं को निष्पादित करना चाह सकते हैं, इसलिए हम बल्क इंसर्ट के संचालन समय को कम कर सकते हैं। सबसे पहले, हम दो बल्क इंसर्ट स्टेटमेंट को एक साथ निष्पादित करेंगे और लॉकिंग तंत्र के व्यवहार का विश्लेषण करेंगे। हम SQL सर्वर प्रबंधन स्टूडियो में दो क्वेरी विंडो खोलेंगे और एक साथ निम्नलिखित बल्क इंसर्ट स्टेटमेंट चलाएंगे।
BULK INSERT Sales
FROM 'C:\1500000 Sales Records.csv'
WITH (FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR='\n'
);

जब हम निम्नलिखित dmv (डायनामिक मैनेजमेंट व्यू) क्वेरी को निष्पादित करते हैं, जो बल्क इंसर्ट प्रक्रिया की स्थिति की निगरानी करने में मदद करती है।
SELECT session_id,command ,status,last_wait_type,text FROM sys.dm_exec_requests cross apply sys.dm_exec_sql_text(sys.dm_exec_requests.sql_handle) where text like '%BULK INSERT Sales%' and session_id <>@@SPID

जैसा कि आप उपरोक्त छवि, सत्र 61 में देख सकते हैं, लॉकिंग के कारण बल्क इंसर्ट प्रक्रिया की स्थिति निलंबित है। यदि हम समस्या को सत्यापित करते हैं, तो सत्र 59 बल्क इंसर्ट डेस्टिनेशन टेबल को लॉक कर देता है और सेशन 61 बल्क इंसर्ट प्रक्रिया को जारी रखने के लिए इस लॉक के जारी होने की प्रतीक्षा करता है। अब, हम बल्क इंसर्ट स्टेटमेंट में TABLOCK विकल्प जोड़ेंगे और प्रश्नों को निष्पादित करेंगे।


जब हम dmv मॉनिटरिंग क्वेरी को फिर से निष्पादित करते हैं, तो हम कोई निलंबित बल्क इंसर्ट प्रक्रिया नहीं देख सकते हैं क्योंकि SQL सर्वर एक विशेष लॉक प्रकार का उपयोग करता है जिसे बल्क अपडेट लॉक (BU) कहा जाता है। यह लॉक प्रकार एक ही टेबल पर एक साथ कई बल्क इंसर्ट ऑपरेशंस को प्रोसेस करने की अनुमति देता है और यह विकल्प बल्क इंसर्ट प्रोसेस के कुल समय को भी कम करता है।
जब हम बल्क इंसर्ट प्रक्रिया के दौरान निम्नलिखित क्वेरी को निष्पादित करते हैं, तो हम लॉकिंग विवरण और लॉक प्रकारों की निगरानी कर सकते हैं।
SELECT dm_tran_locks.request_session_id,
dm_tran_locks.resource_database_id,
DB_NAME(dm_tran_locks.resource_database_id) AS dbname,
CASE
WHEN resource_type = 'OBJECT'
THEN OBJECT_NAME(dm_tran_locks.resource_associated_entity_id)
ELSE OBJECT_NAME(partitions.OBJECT_ID)
END AS ObjectName,
partitions.index_id,
indexes.name AS index_name,
dm_tran_locks.resource_type,
dm_tran_locks.resource_description,
dm_tran_locks.resource_associated_entity_id,
dm_tran_locks.request_mode,
dm_tran_locks.request_status
FROM sys.dm_tran_locks
LEFT JOIN sys.partitions ON partitions.hobt_id = dm_tran_locks.resource_associated_entity_id
LEFT JOIN sys.indexes ON indexes.OBJECT_ID = partitions.OBJECT_ID AND indexes.index_id = partitions.index_id
WHERE resource_associated_entity_id > 0
AND resource_database_id = DB_ID()

निष्कर्ष
इस लेख में, हमने SQL सर्वर में बल्क इंसर्ट ऑपरेशन के सभी विवरणों की खोज की। विशेष रूप से, हमने बल्क इंसर्ट कमांड और इसकी सेटिंग्स और विकल्पों का उल्लेख किया है, और हमने विभिन्न परिदृश्यों का भी विश्लेषण किया है जो वास्तविक जीवन की समस्याओं के करीब हैं।
संदर्भ
बल्क इंसर्ट (ट्रांजैक्ट-एसक्यूएल)
थोक आयात में न्यूनतम लॉगिंग के लिए पूर्वापेक्षाएँ
थोक आयात के लिए लॉकिंग व्यवहार को नियंत्रित करना
आगे पढ़ना
बीसीपी उपयोगिता के साथ फ्लैट फ़ाइल में डेटा निर्यात करना और बल्क इंसर्ट के साथ डेटा आयात करना
उपयोगी टूल:
dbForge डेटा पंप - SQL डेटाबेस को बाहरी स्रोत डेटा से भरने और सिस्टम के बीच डेटा माइग्रेट करने के लिए एक SSMS ऐड-इन।