मैंने हाल ही में कुछ विशेषताओं पर चर्चा की है जिनका उपयोग करने के खिलाफ Microsoft सलाह देता है, और मुझे लगता है कि आपको अस्तित्व को भी भूल जाना चाहिए। ऐसे मामले थे जहां एक सहयोगी ने लगातार बहिष्कृत पश्चगामी संगतता दृश्य sys.sysprocesses को बढ़ावा दिया था नए डायनेमिक मैनेजमेंट व्यू (DMVs) के बजाय, और एक अन्य मामला जहां एक अलग सहयोगी ने SQL सर्वर प्रोफाइलर का उपयोग करके एक प्रोडक्शन सर्वर को डाउन कर दिया।
मेरी नवीनतम रन-इन चीजों के साथ सबसे अच्छी तरह से भूल गई एक नई संग्रहीत प्रक्रिया है जिसमें ntext . है पैरामीटर। मैंने जाँच की और, निश्चित रूप से, डेटा प्रकार अंतर्निहित तालिका के लिए स्कीमा से मेल खाता है। मेरा दिमाग इन पुराने डेटा प्रकारों के बारे में यह समझाने के लिए दौड़ने लगा कि हमें वास्तव में उनका अब और उपयोग क्यों नहीं करना चाहिए:
- image
- ntext
- text
ये प्रकार कई कारणों से पदावनत सूची में हैं, और बदले जाने के बाद से उस सूची में एक स्थायी स्थान पर हैं। max . द्वारा SQL सर्वर 2005 में वापस टाइप करें। इनमें से कुछ दर्द बिंदुओं में शामिल हैं:
- आप कई स्ट्रिंग फ़ंक्शंस का उपयोग नहीं कर सकते, जैसे
LEFT(),RTRIM(),UPPER(), और अधिकांश तुलना ऑपरेटर; - आपको
TEXTPTR. जैसे कार्यों का उपयोग करने की आवश्यकता है ,WRITETEXT, औरUPDATETEXTसंशोधनों के लिए; - आप स्थानीय चर के रूप में प्रकारों का उपयोग नहीं कर सकते;
- आप
DISTINCTमें कॉलम का संदर्भ नहीं दे सकते हैं ,GROUP BY,ORDER BY, या एक सम्मिलित कॉलम के रूप में (ऐसा नहीं है कि आप इनमें से कोई भी करना चाहते हैं); - छोटे मान जो पंक्ति में फ़िट हो सकते हैं केवल
text in row. के साथ ही ऐसा कर सकते हैं विकल्प।
यह एक संपूर्ण सूची नहीं है; ऐसे अन्य अंतर हैं जिन्हें आप कम या ज्यादा महत्वपूर्ण मान सकते हैं। मेरे लिए सबसे महत्वपूर्ण कारण यह है कि यदि तालिका में इनमें से कोई एक डेटा प्रकार है, तो आप ऑनलाइन संकुल अनुक्रमणिका का पुनर्निर्माण नहीं कर सकते।
आइए कुछ तालिकाओं के साथ एक साधारण डेटाबेस बनाएं:
CREATE DATABASE BadIdeas; GO USE BadIdeas; GO CREATE TABLE dbo.t1(id bigint IDENTITY PRIMARY KEY, msg nvarchar(max)); CREATE TABLE dbo.t2(id bigint IDENTITY PRIMARY KEY, msg ntext);
अब, टेबल पर ऑनलाइन संचालन करने का प्रयास करते हैं:
ALTER TABLE dbo.t1 REBUILD WITH (ONLINE = ON); GO ALTER TABLE dbo.t2 REBUILD WITH (ONLINE = ON);
जबकि पहला कथन सफल होता है, दूसरा इस तरह एक त्रुटि संदेश देता है:
Msg 2725, Level 16, State 2इंडेक्स 'PK__t2__3213E83FEEA1E0AD' के लिए एक ऑनलाइन ऑपरेशन नहीं किया जा सकता क्योंकि इंडेक्स में डेटा टाइप टेक्स्ट, ntext, इमेज या FILESTREAM का कॉलम 'msg' होता है। गैर-संकुल अनुक्रमणिका के लिए, स्तंभ अनुक्रमणिका का सम्मिलित स्तंभ हो सकता है। क्लस्टर्ड इंडेक्स के लिए, कॉलम टेबल का कोई भी कॉलम हो सकता है। यदि DROP_EXISTING का उपयोग किया जाता है, तो कॉलम नए या पुराने इंडेक्स का हिस्सा हो सकता है। ऑपरेशन ऑफ़लाइन किया जाना चाहिए।
एक बार के परिदृश्य में, त्रुटि संदेश से निपटना काफी आसान है:आप या तो तालिका को छोड़ देते हैं या, यदि तालिका को पूरी तरह से फिर से बनाया जाना चाहिए, तो आप अपनी टीमों के साथ एक आउटेज शेड्यूल करने के लिए काम करते हैं। जब आप किसी अनुक्रमणिका रखरखाव समाधान को स्वचालित कर रहे होते हैं या अपने परिवेश में नई संपीड़न सेटिंग्स परिनियोजित कर रहे होते हैं, तो आपके समाधान को वर्तमान या भविष्य की स्थिति में संभालना थोड़ा अधिक दर्द होता है।
क्या करें?
आप इन स्तंभों को उनके अधिक आधुनिक समकक्षों से बदलना शुरू कर सकते हैं। sys.columns . का उपयोग करके उन्हें ट्रैक करने में आपकी सहायता करने के लिए यहां एक प्रश्न दिया गया है कैटलॉग दृश्य, लेकिन आपके एप्लिकेशन कोड में मौजूद किसी भी स्पष्ट संदर्भ के लिए आप स्वयं हैं:
SELECT [Schema] = s.name,
[Object] = o.name,
[Column] = c.name,
[Data Type] = TYPE_NAME(c.user_type_id) + CASE
WHEN c.system_type_id <> c.user_type_id
THEN N' (' + TYPE_NAME(c.system_type_id) + N')'
ELSE N'' END
FROM sys.columns AS c
INNER JOIN sys.objects AS o
ON c.[object_id] = o.[object_id]
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]
WHERE c.system_type_id IN (34, 35, 99)
ORDER BY [Schema], [Object], [Column]; आउटपुट:

SSMS में जाना और इन स्तंभों के डेटा प्रकारों को मैन्युअल रूप से बदलना आकर्षक हो सकता है, लेकिन इसके अन्य निहितार्थ भी हो सकते हैं। उदाहरण के लिए, कॉलम में उनके साथ जुड़ी डिफ़ॉल्ट बाधाएं हो सकती हैं। और आपके पास पैरामीटर के साथ संग्रहीत कार्यविधियाँ हो सकती हैं जिन्हें अग्रानुक्रम में अद्यतन किया जाना चाहिए:
CREATE PROCEDURE dbo.sp1 @p1 ntext AS PRINT 1; GO
इन सभी मामलों को खोजने के लिए, आप उपरोक्त क्वेरी को sys.parameters के विरुद्ध खोजने के लिए अनुकूलित कर सकते हैं इसके बजाय कैटलॉग दृश्य:
SELECT [Schema] = s.name,
[Object] = o.name,
[Parameter] = p.name,
[Data Type] = TYPE_NAME(p.user_type_id) + CASE
WHEN p.system_type_id <> p.user_type_id
THEN N' (' + TYPE_NAME(p.system_type_id) + N')'
ELSE N'' END
FROM sys.objects AS o
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]
INNER JOIN sys.parameters AS p
ON p.[object_id] = o.[object_id]
WHERE p.system_type_id IN (34, 35, 99)
ORDER BY [Schema], [Object], [Parameter]; आउटपुट:

यदि आपको इस डेटा को सभी डेटाबेस में वापस करने की आवश्यकता है, तो आप sp_ineachdb . ले सकते हैं , एक प्रक्रिया जिसे मैंने लिखा (और यहां और यहां प्रलेखित) छोटी गाड़ी, गैर-दस्तावेज, और असमर्थित sp_MSforeachdb में कई सीमाओं को पार करने के लिए . तब आप यह कर सकते हैं:
EXEC master.dbo.sp_ineachdb @command = N'SELECT [Database] = DB_NAME(),
[Schema] = s.name,
[Object] = o.name,
[Column] = c.name,
[Data Type] = TYPE_NAME(c.user_type_id) + CASE
WHEN c.system_type_id <> c.user_type_id
THEN N'' ('' + TYPE_NAME(c.system_type_id) + N'')''
ELSE N'''' END
FROM sys.columns AS c
INNER JOIN sys.objects AS o
ON c.[object_id] = o.[object_id]
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]
WHERE c.system_type_id IN (34, 35, 99)
ORDER BY [Schema], [Object], [Column];
SELECT [Database] = DB_NAME(),
[Schema] = s.name,
[Object] = o.name,
[Parameter] = p.name,
[Data Type] = TYPE_NAME(p.user_type_id) + CASE
WHEN p.system_type_id <> p.user_type_id
THEN N'' ('' + TYPE_NAME(p.system_type_id) + N'')''
ELSE N'''' END
FROM sys.objects AS o
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]
INNER JOIN sys.parameters AS p
ON p.[object_id] = o.[object_id]
WHERE p.system_type_id IN (34, 35, 99)
ORDER BY [Schema], [Object], [Parameter];'; यहां एक दिलचस्प पक्ष नोट है:यदि आप इसे सभी डेटाबेस के विरुद्ध चलाते हैं, तो आप पाएंगे कि, SQL सर्वर 2019 में भी, Microsoft अभी भी इनमें से कुछ पुराने प्रकारों का उपयोग कर रहा है।
आप इसे और अधिक स्वचालित कर सकते हैं, इसे PowerShell या जो भी स्वचालन उपकरण आप SQL सर्वर के कई उदाहरणों को प्रबंधित करने के लिए उपयोग करते हैं, से चलाकर।
बेशक, यह सिर्फ शुरुआत है - यह केवल एक सूची तैयार करता है। ALTER TABLE . का ड्राफ़्ट संस्करण तैयार करने के लिए आप इसे आगे बढ़ा सकते हैं आदेश आपको सभी तालिकाओं को अद्यतन करने की आवश्यकता होगी, लेकिन उन आदेशों को निष्पादित करने से पहले उनकी समीक्षा करने की आवश्यकता होगी, और आपको अभी भी प्रक्रियाओं को स्वयं संशोधित करने की आवश्यकता होगी (ALTER PROCEDURE उत्पन्न करना) कमांड जिनमें केवल उन पैरामीटर प्रकार के नाम सही तरीके से बदले गए हैं, किसी भी तरह से आसान अभ्यास नहीं है)। यहां एक उदाहरण दिया गया है जो ALTER TABLE उत्पन्न करता है आदेश, अशक्तता को ध्यान में रखते हुए लेकिन डिफ़ॉल्ट बाधाओं जैसी कोई अन्य जटिलता नहीं:
SELECT N'ALTER TABLE ' + QUOTENAME(s.name)
+ N'.' + QUOTENAME(o.name)
+ N' ALTER COLUMN ' + QUOTENAME(c.name) + N' '
+ CASE c.system_type_id
WHEN 34 THEN N'varbinary'
WHEN 35 THEN N'varchar'
WHEN 99 THEN N'nvarchar'
END + N'(max)'
+ CASE c.is_nullable
WHEN 0 THEN N' NOT'
ELSE N'' END + N' NULL;'
FROM sys.columns AS c
INNER JOIN sys.objects AS o
ON c.[object_id] = o.[object_id]
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]
WHERE c.system_type_id IN (34, 35, 99); आउटपुट:
वैकल्पिक तालिका [डीबीओ]। [टी 2] वैकल्पिक कॉलम [संदेश] nvarchar (अधिकतम) नल;
और यदि आप सोच रहे हैं, नहीं, आप यह एक बार का ऑपरेशन एक स्पष्ट WITH (ONLINE = ON) के साथ नहीं कर सकते हैं विकल्प:
ऑनलाइन ALTER COLUMN ऑपरेशन टेबल 't2' के लिए नहीं किया जा सकता क्योंकि कॉलम 'msg' में वर्तमान में एक असमर्थित डेटाटाइप है या बदल रहा है:टेक्स्ट, ntext, इमेज, CLR टाइप या फ़ाइल धारा। ऑपरेशन ऑफ़लाइन किया जाना चाहिए।
निष्कर्ष
उम्मीद है कि यह कुछ अच्छी पृष्ठभूमि प्रदान करता है कि आप इन बहिष्कृत प्रकारों को क्यों खत्म करना चाहते हैं, और वास्तव में परिवर्तन करने के लिए एक प्रारंभिक बिंदु। Microsoft ने कठिन तरीके से सीखा कि इतनी कार्यक्षमता नहीं है कि वे उत्पाद से बाहर निकल सकें, इसलिए मुझे इस बात की चिंता नहीं है कि ये वास्तव में मेरे जीवनकाल में मौजूद रहेंगे। लेकिन हटाने का डर ही आपका एकमात्र प्रेरक नहीं होना चाहिए।