-
INFORMATION_SCHEMA विचार बस यही हैं - विचार। आप उन्हें अपडेट नहीं कर सकते हैं, इसलिए उनके किसी भी गतिरोध का कारण बनने की संभावना नहीं है। यदि आप वास्तविक स्रोत को निर्धारित करना चाहते हैं (जो मुझे लगता है कि आपके परिवर्तनों के साथ कुछ करना है, या कर्सर के भीतर अन्य कोड जो आपने नहीं दिखाया है, या अन्य कोड जिसे आप इन प्रक्रियाओं को कॉल करने के संयोजन में कॉल कर रहे हैं - चूंकि इसके खिलाफ चयन करता है विचार और फिर चर का चयन करना कारण नहीं हो सकता), मेरा सुझाव है कि पढ़ना गेल शॉ की ब्लॉग पोस्ट गतिरोध की व्याख्या पर ।
-
(1) के बावजूद मैं अभी भी INFORMATION_SCHEMA की तुलना में अधिक आधुनिक कैटलॉग दृश्यों का उपयोग करने का सुझाव देता हूं। वही जानकारी, उदाहरण के लिए, sys.key_constraints से ली जा सकती है।
-
आप डिफ़ॉल्ट कर्सर विकल्पों का उपयोग कर रहे हैं; और आप कर्सर को नेस्ट कर रहे हैं। यदि आप अभी भी कर्सर का उपयोग कर रहे हैं, तो आपको कम संसाधन गहन कर्सर (जैसे LOCAL STATIC FORWARD_ONLY READ_ONLY) का उपयोग करने की आदत डालनी चाहिए।
-
ऐसा करने के लिए आपको वास्तव में कर्सर की आवश्यकता नहीं है। यहां बताया गया है कि मैं PK तालिका स्क्रिप्ट को फिर से कैसे लिखूंगा:
CREATE PROCEDURE dbo.ScriptPKForTable @TableName SYSNAME AS BEGIN SET NOCOUNT ON; DECLARE @pkName SYSNAME, @clustered BIT, @object_id INT, @sql NVARCHAR(MAX); SELECT @object_id = OBJECT_ID(UPPER(@TableName)); SELECT @pkName = kc.name, @clustered = CASE i.[type] WHEN 1 THEN 1 ELSE 0 END FROM sys.key_constraints AS kc INNER JOIN sys.indexes AS i ON kc.parent_object_id = i.[object_id] AND kc.unique_index_id = i.index_id WHERE kc.parent_object_id = @object_id AND kc.[type] = 'pk'; SET @sql = N'ALTER TABLE ' + QUOTENAME(@TableName) + ' ADD CONSTRAINT ' + @pkName + ' PRIMARY KEY ' + CASE @clustered WHEN 1 THEN 'CLUSTERED' ELSE '' END + ' ('; SELECT @sql = @sql + c.name + ',' FROM sys.index_columns AS ic INNER JOIN sys.indexes AS i ON ic.index_id = i.index_id AND ic.[object_id] = i.[object_id] INNER JOIN sys.key_constraints AS kc ON i.[object_id] = kc.[parent_object_id] AND kc.unique_index_id = i.index_id INNER JOIN sys.columns AS c ON i.[object_id] = c.[object_id] AND ic.column_id = c.column_id WHERE kc.[type] = 'PK' AND kc.parent_object_id = @object_id ORDER BY key_ordinal; SET @sql = LEFT(@sql, LEN(@sql) - 1) + ');'; SELECT COALESCE(@sql, ' '); END GO
इंडेक्स निर्माण स्क्रिप्ट के लिए, मुझे लगता है कि ऐसा करने का एक बेहतर तरीका है (फिर स्पष्ट कर्सर के बिना, कर्सर से परहेज करना लक्ष्य नहीं है, लेकिन कोड बहुत क्लीनर होने जा रहा है)। सबसे पहले आपको कुंजी बनाने या इंडेक्स से कॉलम शामिल करने के लिए एक फ़ंक्शन की आवश्यकता होती है:
CREATE FUNCTION dbo.BuildIndexColumns
(
@object_id INT,
@index_id INT,
@included_columns BIT
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE @s NVARCHAR(MAX);
SELECT @s = N'';
SELECT @s = @s + c.name + CASE ic.is_descending_key
WHEN 1 THEN ' DESC' ELSE '' END + ','
FROM sys.index_columns AS ic
INNER JOIN sys.columns AS c
ON ic.[object_id] = c.[object_id]
AND ic.column_id = c.column_id
WHERE c.[object_id] = @object_id
AND ic.[object_id] = @object_id
AND ic.index_id = @index_id
AND ic.is_included_column = @included_columns
ORDER BY ic.key_ordinal;
IF @s > N''
SET @s = LEFT(@s, LEN(@s)-1);
RETURN (NULLIF(@s, N''));
END
GO
उस फ़ंक्शन के साथ, एक ScriptIndexes प्रक्रिया बहुत आसान है:
CREATE PROCEDURE dbo.ScriptIndexesForTable
@TableName SYSNAME
AS
BEGIN
SET NOCOUNT ON;
DECLARE
@sql NVARCHAR(MAX),
@object_id INT;
SELECT @sql = N'', @object_id = OBJECT_ID(UPPER(@TableName));
SELECT @sql = @sql + 'CREATE '
+ CASE i.is_unique WHEN 1 THEN 'UNIQUE ' ELSE '' END
+ CASE i.[type] WHEN 1 THEN 'CLUSTERED ' ELSE '' END
+ ' INDEX ' + i.name + ' ON ' + QUOTENAME(@TableName) + ' ('
+ dbo.BuildIndexColumns(@object_id, i.index_id, 0)
+ ')' + COALESCE(' INCLUDE('
+ dbo.BuildIndexColumns(@object_id, i.index_id, 1)
+ ')', '') + ';' + CHAR(13) + CHAR(10)
FROM
sys.indexes AS i
WHERE
i.[object_id] = @object_id
-- since this will be covered by ScriptPKForTable:
AND i.is_primary_key = 0
ORDER BY i.index_id;
SELECT COALESCE(@sql, ' ');
END
GO
ध्यान दें कि मेरा समाधान यह नहीं मानता है कि पीके क्लस्टर किया गया है (आपकी पीके स्क्रिप्ट हार्ड-कोड क्लस्टर्ड है लेकिन फिर आपकी इंडेक्स स्क्रिप्ट मानती है कि किसी भी इंडेक्स को क्लस्टर किया जा सकता है)। मैं फ़ाइल समूह, विभाजन, या फ़िल्टर किए गए अनुक्रमणिका जैसे अतिरिक्त गुणों को भी अनदेखा करता हूं (2005 में वैसे भी समर्थित नहीं)।