7

द्वारा संदर्भित SQL फ़ंक्शन का संदर्भ लें यदि आप एक तालिकाबद्ध कॉलम सेट करने के लिए तालिका का कॉलम सेट करते हैं जिसका फॉर्मूला फ़ंक्शन कॉल करता है, तो यह अंतर्निहित फ़ंक्शन को बदलने का दर्द बन जाता है। प्रत्येक परिवर्तन के साथ, आपको प्रत्येक कॉलम को ढूंढना होगा जिसका फॉर्मूला फ़ंक्शन का संदर्भ देता है, संदर्भ को हटाता है, तालिका को सहेजता है, फ़ंक्शन को बदलता है, सबकुछ वापस जोड़ता है, और फिर से सहेजता है। यहां तक ​​कि छोटे बदलाव भी दुःस्वप्न हैं।गणना किए गए कॉलम

क्या आप SQL सर्वर को बता सकते हैं कि आपको यह परवाह नहीं है कि फ़ंक्शन को फ़ॉर्मूला द्वारा संदर्भित किया जा रहा है और केवल आगे बढ़ने और अंतर्निहित फ़ंक्शन को बदलने के लिए?

अतिरिक्त विवरण: गणना कॉलम एक एफके बाधा द्वारा जारी या संदर्भित नहीं है क्योंकि यह गैर-निर्धारक है। समारोह वर्तमान समय पर विचार करता है। यह इस सवाल से निपट रहा है कि रिकॉर्ड समाप्त हो गया है या नहीं।

+0

मैं मानता हूं कि यह एक बड़ा दर्द है! अभी यह महसूस कर रहा हूँ! –

+0

मुझे एक ही समस्या है।मुझे लगता है कि एक अच्छा कारण है कि एमएस एसक्यूएल इसे क्यों अनुमति नहीं देता है, लेकिन फिर भी, यह एक वास्तविक दर्द (साझा दुःख के लिए +1) –

उत्तर

5

नहीं, जहां तक ​​मुझे पता है, आप यह नहीं कर सकते हैं - आपको पहले फ़ंक्शन का संदर्भ देने वाले सभी गणना वाले कॉलम को हटाना होगा, फ़ंक्शन को बदलना होगा, और फिर गणना किए गए कॉलम को फिर से बनाना होगा।

शायद एमएस हमें SQL सर्वर 2010/2011 में "निर्माण या परिवर्तित समारोह" आदेश देगा? :-)

मार्क

+0

अच्छा, मुझे लगता है कि आप बस ऐसा नहीं कर सकते हैं। और यही वह है जो आपने कहा था और आपने इसे पहले कहा था। – colithium

+0

वास्तव में? क्या आप कॉलम से बाधा नहीं छोड़ सकते हैं, फिर फ़ंक्शन को बदल सकते हैं और फिर बाधा को फिर से लागू कर सकते हैं? –

0

आप कुछ अच्छी स्कीमा के साथ की कोशिश कर सकते उपकरण की तुलना करें, कि आप के लिए स्क्रिप्ट बनाने :)

+0

मेरे पास एसक्यूएल 8 की तुलना है और अगर मैं इसे करने के लिए मेनू कमांड पा सकता हूं तो डर लगता है ... – jcollum

4

ALTER के परिणामों विशाल हो सकता है।

क्या आपने कॉलम अनुक्रमित किए हैं? Schemabinding के साथ इसे एक दृश्य में इस्तेमाल किया? इसे जारी रखा? इसके साथ विदेशी महत्वपूर्ण संबंध?

क्या होगा यदि ALTER डेटाटाइप, शून्यता या निर्धारणा को बदलता है?

इतने सारे परिदृश्यों के मुकाबले निर्भरताओं के साथ वैकल्पिक समारोह को रोकना आसान है।

+0

फ़ंक्शन समय पर निर्भर है और इसे जारी नहीं किया जा सकता है। इसी कारण से इसमें एफके बाधा नहीं हो सकती है (भले ही कॉलम हमेशा किसी अन्य तालिका के पीके संदर्भित वैध मान होता है)। – colithium

+0

यह * आपका * फ़ंक्शन है, सामान्य मामला नहीं। क्या बेहतर है: निरंतरता के साथ लगातार फ़ंक्शन को अस्वीकार करें या इसे बहुत यादृच्छिक रूप से अनुमति दें? – gbn

+0

मेरा कार्य कुछ खास नहीं है, इसका व्यवहार गैर-निर्धारक होने से आता है। मैंने स्पष्ट किया कि मेरे प्रश्न में एक संपादन के साथ। गैर-निर्धारक कार्यों को बदलकर कोई दुष्प्रभाव नहीं होना चाहिए। लेकिन क्या यह संभव है? – colithium

0

आप कॉलम को गणना नहीं कर सकते हैं और इसे ट्रिगर द्वारा अपडेट कर सकते हैं।

या आप किसी अन्य चीज़ पर तालिका का नाम बदल सकते हैं, गणना किए गए कॉलम को छोड़ सकते हैं, और मूल तालिका (यानी मूल तालिका नाम के साथ) और "आवश्यक" कॉलम सहित आपको दृश्य बना सकते हैं।

संपादित करें: ध्यान दें कि यह आपके आईएनएसईआरटी के साथ मूल तालिका नाम (अब एक दृश्य) में गड़बड़ कर सकता है। जाहिर है आप पुरानी टेबल रख सकते हैं, गणना किए गए कॉलम को छोड़ सकते हैं, और एक अलग दृश्य बना सकते हैं जिसमें गणना कॉलम शामिल है।

हमें गणना के लिए पर्याप्त समय के साथ काम करना पड़ा है कि वे यह हासिल करने के लिए अधिक परेशानी हैं। विफल-सुरक्षित आवेषण (1), कंप्यूटेड कॉलम वाले टेबल पर दृश्यों में डालने का प्रयास करते हुए, चीजें जिन्हें एसईटी एरिथबॉर्ट के साथ गड़बड़ की आवश्यकता होती है और इसी तरह।

है (1) हम असफल-सुरक्षित आवेषण पसंद:

INSERT INTO MyTable चुनें * MyOtherTable से कहां ...

जो डिजाइन किए हैं विफल करता है, तो एक नया स्तंभ एक मेज और नहीं जोड़ा गया है अन्य। कम्प्यूटटेड कॉलम के साथ हमें स्पष्ट रूप से सभी कॉलम नाम देना होगा, जो हमें सुरक्षा नेट खो देता है।

+0

यह बात है, गणना कॉलम का मान गैर-निर्धारक है। मतलब अगर आप यह पूछते हैं कि यह क्या है तो यह एक बात कह सकता है और फिर एक सेकंड बाद में बिल्कुल कोई डेटा परिवर्तन नहीं हो सकता है, यह कुछ अलग कह सकता है। ट्रिगर यहां काम नहीं करेंगे। – colithium

+0

मैंने पढ़ा था कि कहा गया है कि गैर-निर्धारक था, फिर मेरा दिमाग भटक गया! उसके लिए माफ़ करना। – Kristen

1

कॉलम C1, C2, सी 3, सी 4, सी 5 जहां सी 4 एक गणना स्तंभ

भी मान है साथ तालिका टी 1 मान लें सी 4 संदर्भ में कार्य OldFunc जो आप NewFunc

पहले द्वारा प्रतिस्थापित किया जा करना चाहते हैं, एक अस्थायी तालिका

Select C1, C2, C3, C5 into TmpT1 from T1 
Go 

के बगल में स्थित सभी पंक्तियों से गैर गणना कॉलम ले जाएँ, टी 1

से
Delete From T1 
go 
सभी पंक्तियां हटाएं

अब आप स्तंभ सी 4 को संशोधित कर सकते हैं

Alter table T1 alter column C4 as dbo.NewFunc() 
Go 

अब मूल तालिका में वापस सहेजे गए डेटा डाल

Insert Into T1 (C1,C2,C3,C5) select C1,C2,C3,C5 from TmpT1 

अब इस देर से उत्तर के लिए अस्थायी तालिका

Drop Table TmpT1 
2

क्षमा करें हटाएँ, लेकिन यह उपयोगी हो सकता है।

आप प्रत्येक गणना कॉलम के लिए एक डमी फ़ंक्शन का उपयोग कर सकते हैं जो आपके वास्तविक फ़ंक्शन को कॉल करेगा।

उदाहरण:
गणना स्तंभ का उपयोग करें सूत्र: dbo.link_comp ('123')
यह आगे समारोह तर्क और कॉल और वापसी समारोह dbo.link ('123') (आपका वास्तविक समारोह)
दोनों कार्यों को केवल एक ही तर्क का उपयोग करने की आवश्यकता है और उसी प्रकार को वापस करने की आवश्यकता है।

फिर, लॉक किया गया फ़ंक्शन dbo.link_comp है और आप अभी भी dbo.link को बदल सकते हैं।
इसके अलावा, यदि आपका फ़ंक्शन अन्य एसक्यूएल से कहा जाता है, तो भी आप अपने असली फ़ंक्शन नाम dbo.link का उपयोग कर सकते हैं, डमी फ़ंक्शन dbo.link_comp केवल गणना कॉलम के लिए है।

0

मुझे पता है कि यह पार्टी के लिए देर हो चुकी है लेकिन मुझे आज भी यही समस्या हो रही थी और वास्तव में इस मुद्दे को हल करने वाला कुछ भी नहीं मिला, इसलिए मैंने जल्दी ही एक को लिपि।

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

यदि आपको परिभाषाओं के भीतर पैरामीटर में परिवर्तन करना है (जैसे मुझे चाहिए) तो आप बस उस भाग को स्क्रिप्ट कर सकते हैं जहां परिभाषाएं फिर से बनाई गई हैं।

यदि आपने इंडेक्स या अन्य ज़रूरतों के भीतर कॉलम की गणना की है तो आप कोड पर आसानी से विस्तार कर सकते हैं लेकिन यह मेरी आवश्यकताओं के दायरे से बाहर था।

आशा है कि यह किसी और के लिए उपयोगी हो सकता है।

/* Create temporary table to hold definitions */ 
CREATE TABLE [#FUNCTION] 
(
    [TABLE_NAME] nvarchar(255) NOT NULL, 
    [COLUMN_NAME] nvarchar(255) NOT NULL, 
    [DEFINITION] nvarchar(255) NOT NULL 
) 
GO 

/* Add data to temp table */ 
INSERT INTO [#FUNCTION] ([TABLE_NAME], [COLUMN_NAME], [DEFINITION]) 
SELECT TABLE_NAME, COLUMN_NAME, definition FROM INFORMATION_SCHEMA.COLUMNS 
INNER JOIN sys.computed_columns ON (object_id = object_id(TABLE_NAME) AND name = COLUMN_NAME) 
WHERE definition LIKE '%MyFunctionName%' 
GO 

/* Remove columns */ 
DECLARE @TABLE_NAME nvarchar(255) 
DECLARE @COLUMN_NAME nvarchar(255) 

DECLARE c_CursorName CURSOR LOCAL FOR SELECT [TABLE_NAME], [COLUMN_NAME] FROM [#FUNCTION] 
OPEN c_CursorName 

FETCH NEXT FROM c_CursorName INTO @TABLE_NAME, @COLUMN_NAME 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    EXEC('ALTER TABLE [' + @TABLE_NAME + '] DROP COLUMN [' + @COLUMN_NAME + ']') 

    FETCH NEXT FROM c_CursorName INTO @TABLE_NAME, @COLUMN_NAME 
END 

CLOSE c_CursorName 
DEALLOCATE c_CursorName 
GO 

/* Update function */ 
-- Update function here 
GO 

/* Recreate computed columns */ 
DECLARE @TABLE_NAME nvarchar(255) 
DECLARE @COLUMN_NAME nvarchar(255) 
DECLARE @DEFINITION nvarchar(255) 

DECLARE c_CursorName CURSOR LOCAL FOR SELECT [TABLE_NAME], [COLUMN_NAME], [DEFINITION] FROM [#FUNCTION] 
OPEN c_CursorName 

FETCH NEXT FROM c_CursorName INTO @TABLE_NAME, @COLUMN_NAME, @DEFINITION 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    EXEC('ALTER TABLE [' + @TABLE_NAME + '] ADD [' + @COLUMN_NAME + '] AS ' + @DEFINITION) 

    FETCH NEXT FROM c_CursorName INTO @TABLE_NAME, @COLUMN_NAME, @DEFINITION 
END 

CLOSE c_CursorName 
DEALLOCATE c_CursorName 
GO 

/* Remove temp table */ 
DROP TABLE [#FUNCTION] 
GO 
संबंधित मुद्दे