2014-05-06 4 views
8

क्या एक ही लेनदेन के दौरान कॉलम बनाना और मूल्यों को सम्मिलित करना संभव है? यह एक अपग्रेड स्क्रिप्ट का हिस्सा है। मुझे निम्नलिखित विधि online मिली, लेकिन यह काम नहीं करता है; मुझे एक त्रुटि मिलती है: Invalid column name 'IndexNumber'.। मुझे लगता है कि ऐसा इसलिए है क्योंकि लेनदेन ने अभी तक स्तंभ नहीं बनाया है, इसलिए इसमें सम्मिलित करने के लिए कुछ भी नहीं है।कॉलम बनाएं और उसी लेनदेन में डालें?

मेरी स्क्रिप्ट के प्रासंगिक भागों:

Print 'Beginning Upgrade' 
Begin Transaction 
    -- -------------------------------------------------------------------- 
    USE [MyDatabase]; 

    /* Widgets now can be ordered and the order can be modified */ 
    ALTER TABLE [dbo].[Widgets] ADD [IndexNumber] [int] NULL; 

    DECLARE @ind INT 
    SET @ind = 0 
    UPDATE [dbo].[Widgets] 
    SET @ind = [IndexNumber] = @ind + 1; 

    ALTER TABLE [dbo].[Widgets] ALTER COLUMN [IndexNumber] [int] NOT NULL; 
    -- -------------------------------------------------------------------- 
Commit tran 
Print 'Upgrade completed' 

कारण है कि [IndexNumber] एक पहचान स्तंभ नहीं है कि यह संपादन योग्य होना चाहिए है।

उत्तर

14

एक अन्य विकल्प कमिट, यदि आप अलग बैचों में कोड विभाजित करने के लिए नहीं करना चाहते, के लिए EXEC उपयोग करने के लिए है एक नेस्टेड स्कोप/बैच बनाएं:

Print 'Beginning Upgrade' 
Begin Transaction 
    -- -------------------------------------------------------------------- 
    USE [MyDatabase]; 

    /* Widgets now can be ordered and the order can be modified */ 
    ALTER TABLE [dbo].[Widgets] ADD [IndexNumber] [int] NULL; 

    EXEC('DECLARE @ind INT 
    SET @ind = 0 
    UPDATE [dbo].[Widgets] 
    SET @ind = [IndexNumber] = @ind + 1;'); 

    ALTER TABLE [dbo].[Widgets] ALTER COLUMN [IndexNumber] [int] NOT NULL; 
    -- -------------------------------------------------------------------- 
Commit tran 
Print 'Upgrade completed' 

कारण मूल कोड काम नहीं करता है पारिस्थितिकी यह को संकलित करने से पहले पूरे बैच को संकलित करने की कोशिश करता है - संकलन विफल रहता है और इसलिए यह लेनदेन शुरू नहीं करता है, साथ ही टेबल को बदल देता है।

+0

उलझन में अच्छा लगता है। किसी निष्पादन का उपयोग लेनदेन के बाहर या इसके बाद कथन का निष्पादन करने का कारण होगा? वास्तविक अपग्रेड के बारे में आपकी पिछली टिप्पणी के लिए काम नहीं कर रहा है, यह मामला हो सकता है लेकिन इस समय यह मेरा एकमात्र सीसा है। – Nenotlep

+0

@Nenotlep - नहीं, यह अभी भी एक ही लेनदेन के भीतर होगा। –

+0

यह वास्तव में जाने का सबसे आसान तरीका लगता है, जो मेरे लिए सबसे अच्छा समानार्थी है। इसके बजाय इसका उपयोग करना मुझे अपने लेबल को पुन: व्यवस्थित करने या मेरे स्क्रिप्ट प्रवाह पर पुनर्विचार करने की आवश्यकता नहीं है। चीयर्स! – Nenotlep

2

आप एक नया कॉलम नहीं जोड़ सकते हैं और उसी बैच के भीतर इसका उपयोग नहीं कर सकते हैं। कॉलम जोड़ने और इसका उपयोग करने के बीच आपको GO डालने की आवश्यकता है।

लेनदेन अभी भी ठीक है (आप Commit tran से rollback tran को बदलकर परीक्षण कर सकते हैं ताकि कोई बदलाव नहीं किया जा सके)।

Print 'Beginning Upgrade' 
Begin Transaction 
    -- -------------------------------------------------------------------- 
    USE [MyDatabase]; 

    /* Widgets now can be ordered and the order can be modified */ 
    ALTER TABLE [dbo].[Widgets] ADD [IndexNumber] [int] NULL; 

    GO 

    DECLARE @ind INT 
    SET @ind = 0 
    UPDATE [dbo].[Widgets] 
    SET @ind = [IndexNumber] = @ind + 1; 

    ALTER TABLE [dbo].[Widgets] ALTER COLUMN [IndexNumber] [int] NOT NULL; 
    -- -------------------------------------------------------------------- 
Commit tran 
Print 'Upgrade completed' 
+0

यह सबसे अच्छा समाधान की तरह दिखता है। एकमात्र मुद्दा यह है कि लेनदेन शुरू करने के बाद, मैं एक संस्करण की जांच करता हूं और यदि यह विफल रहता है, तो मैं 'गोटो फेलओवर' करता हूं। फेलओवर लेबल वास्तव में 'कमिट ट्रैन' के बाद थोड़ा सा घोषित किया जाता है, इसलिए घोषण घोषणा की तुलना में एक अलग बैच में है -> असफल। इसके लिए कोई सुझाव? – Nenotlep

+0

क्या आप उस लेबल को गोटो से पहले ले जा सकते हैं? – Szymon

+0

यह मुश्किल हो सकता है .. यहां अपग्रेड स्क्रिप्ट का एक बड़ा पेस्ट है: http://pastebin.com/FwKimM66 – Nenotlep

1

कॉल 'जाना' के बाद आप तालिका में परिवर्तन

USE [MyDatabase]; 

/* Widgets now can be ordered and the order can be modified */ 
ALTER TABLE [dbo].[Widgets] ADD [IndexNumber] [int] NULL; 
go 

DECLARE @ind INT 
SET @ind = 0 
UPDATE [dbo].[Widgets] 
SET @ind = [IndexNumber] = @ind + 1; 

ALTER TABLE [dbo].[Widgets] ALTER COLUMN [IndexNumber] [int] NOT NULL; 
-- -------------------------------------------------------------------- 

ट्रॅन

संबंधित मुद्दे