2008-10-06 12 views
105

मेरे डेटाबेस में Object_Table, Data_Table और Link_Table नामक तीन तालिकाएं हैं। लिंक तालिका में केवल दो कॉलम, ऑब्जेक्ट रिकॉर्ड की पहचान और डेटा रिकॉर्ड की पहचान शामिल है।एसक्यूएल सर्वर: क्या एक ही समय में दो तालिकाओं में सम्मिलित करना संभव है?

मैं जहां यह एक दिया वस्तु पहचान से जुड़ा हुआ है DATA_TABLE से डेटा कॉपी और एक अलग दिया वस्तु पहचान के लिए Data_Table और Link_Table में इसी रिकॉर्ड सम्मिलित करना चाहते हैं।

I तालिका सारणी में चयन करके और प्रत्येक पुनरावृत्ति के लिए दो प्रविष्टियों के माध्यम से लूपिंग कर सकते हैं।

क्या यह करने का सबसे अच्छा तरीका है?

संपादित: मैं दो कारण के लिए एक पाश से बचना चाहते हैं, पहला यह है कि मैं आलसी हूँ और एक पाश/अस्थायी तालिका अधिक कोड की आवश्यकता है, और अधिक कोड एक गलती करते हैं करने के लिए और अधिक स्थानों का अर्थ है और दूसरा कारण है प्रदर्शन के बारे में एक चिंता।

मैं एक ही सूची में सभी डेटा कॉपी कर सकता हूं लेकिन नए डेटा रिकॉर्ड से लिंक करने के लिए लिंक तालिका कैसे प्राप्त करें जहां प्रत्येक रिकॉर्ड में एक नई आईडी है?

+0

मैं, एक सम्मिलित साथ यह करने के लिए कोशिश कर रहा है जब 2 आवेषण के साथ यह कर के हित नहीं मिलता है पूरी तरह से अच्छी तरह से काम करता है। क्या आपका मतलब है कि आप यह सुनिश्चित करना चाहते हैं कि 2 आवेषण दोनों पूरा हो जाएं? फिर आपको यह प्रतिबद्ध/रोलबैक निर्देश जांचना होगा। –

+1

मैं दो आवेषणों से खुश हूं, बस यह कि लिंक तालिका में डालने की आवश्यकताएं पहले डालने में उत्पन्न पहचान हैं। – tpower

उत्तर

15

तालिका चर के प्रयोग से निम्नलिखित स्थिति को स्थापित करता है।

DECLARE @Object_Table TABLE 
(
    Id INT NOT NULL PRIMARY KEY 
) 

DECLARE @Link_Table TABLE 
(
    ObjectId INT NOT NULL, 
    DataId INT NOT NULL 
) 

DECLARE @Data_Table TABLE 
(
    Id INT NOT NULL Identity(1,1), 
    Data VARCHAR(50) NOT NULL 
) 

-- create two objects '1' and '2' 
INSERT INTO @Object_Table (Id) VALUES (1) 
INSERT INTO @Object_Table (Id) VALUES (2) 

-- create some data 
INSERT INTO @Data_Table (Data) VALUES ('Data One') 
INSERT INTO @Data_Table (Data) VALUES ('Data Two') 

-- link all data to first object 
INSERT INTO @Link_Table (ObjectId, DataId) 
SELECT Objects.Id, Data.Id 
FROM @Object_Table AS Objects, @Data_Table AS Data 
WHERE Objects.Id = 1 

धन्यवाद एक और answer कि मुझे आउटपुट खंड की ओर इशारा किया है कि मैं एक समाधान का प्रदर्शन कर सकते हैं:

-- now I want to copy the data from from object 1 to object 2 without looping 
INSERT INTO @Data_Table (Data) 
OUTPUT 2, INSERTED.Id INTO @Link_Table (ObjectId, DataId) 
SELECT Data.Data 
FROM @Data_Table AS Data INNER JOIN @Link_Table AS Link ON Data.Id = Link.DataId 
       INNER JOIN @Object_Table AS Objects ON Link.ObjectId = Objects.Id 
WHERE Objects.Id = 1 

हालांकि यह पता चला है कि यह निम्न त्रुटि

की वजह से है कि वास्तविक जीवन में सरल नहीं है

खंड जांच आउटपुट एक के दोनों ओर (प्राथमिक कुंजी, विदेशी कुंजी) संबंध

पर नहीं हो सकता

मैं अभी भी OUTPUT INTO एक temp तालिका कर सकता हूं और फिर सामान्य सम्मिलन के साथ समाप्त कर सकता हूं। तो मैं अपने लूप से बच सकता हूं लेकिन मैं अस्थायी तालिका से नहीं बच सकता।

+0

[यदि आप SQL Server 2008 पर हैं तो इस त्रुटि के आसपास काम करने के लिए यहां मेरा उत्तर देखें] (http://stackoverflow.com/questions/7408204/is-there-a-way-to-do-another-query- भीतर-द-डालने-क्वेरी/7415501 # 7415501) –

4

यदि आप चाहते हैं कि कार्रवाइयां अधिक या कम परमाणु हों, तो मैं उन्हें लेनदेन में लपेटना सुनिश्चित कर दूंगा। इस तरह आप सुनिश्चित कर सकते हैं कि दोनों हुआ या दोनों आवश्यकतानुसार नहीं हुए।

+2

क्रियाएं परमाणु हैं यदि वे एक लेनदेन में लिपटे हैं, न कि "अधिक या कम" परमाणु। जरूरी नहीं है कि अलगाव का स्तर है, जब तक कि आप इसे निर्दिष्ट न करें। –

2

सम्मिलन एक समय में केवल एक टेबल पर काम कर सकता है। एकाधिक प्रविष्टियों में एकाधिक कथन होना चाहिए।

मुझे नहीं पता कि आपको तालिका चर के माध्यम से लूपिंग करने की आवश्यकता है - क्या आप सिर्फ एक टेबल में द्रव्यमान डालने का उपयोग नहीं कर सकते हैं, फिर द्रव्यमान दूसरे में डालें?

वैसे - मुझे लगता है कि आप ऑब्जेक्ट_Table से डेटा कॉपी करना चाहते हैं; अन्यथा सवाल समझ में नहीं आता है।

27

तुम अब भी दो INSERT बयान की जरूरत है, लेकिन यह लगता है कि आप पहले डालने से IDENTITY हो और दूसरे में उपयोग करना चाहते हैं, जिस स्थिति में है, तो आप OUTPUT या OUTPUT INTO में देखना चाहते हो सकता है: http://msdn.microsoft.com/en-us/library/ms177564.aspx

+1

धन्यवाद! मुझे OUTPUT कीवर्ड के बारे में पता नहीं था, जो मैं खोज रहा था। +1 –

170

एक बयान में: नहीं

एक लेन-देन में : हाँ

BEGIN TRANSACTION 
    DECLARE @DataID int; 
    INSERT INTO DataTable (Column1 ...) VALUES (....); 
    SELECT @DataID = scope_identity(); 
    INSERT INTO LinkTable VALUES (@ObjectID, @DataID); 
COMMIT 

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

+0

इस स्निपेट के लिए धन्यवाद। –

+1

यही वह है जो मैं लंबे समय से खोज रहा हूं। धन्यवाद :) –

+9

यह अभी क्यों डाउनवॉट किया गया था? –

4

ऐसा लगता है कि लिंक तालिका कई को कैप्चर करती है: ऑब्जेक्ट टेबल और डेटा तालिका के बीच कई रिश्ते।

मेरा सुझाव लेनदेन को प्रबंधित करने के लिए संग्रहीत प्रक्रिया का उपयोग करना है। जब आप ऑब्जेक्ट या डेटा टेबल में सम्मिलित करना चाहते हैं तो अपने आवेषण करें, नई आईडी प्राप्त करें और उन्हें लिंक तालिका में डालें।

यह आपके सभी तर्कों को एक आसान कॉल स्पोक में encapsulated रहने की अनुमति देता है।

+0

किसी और ने आपको क्यों नहीं छोड़ा है? संग्रहीत प्रक्रिया स्पष्ट और सर्वोत्तम तरीका है। Joel Coehoorn के उत्तर के साथ अपने उत्तर को जोड़ो और आपको सबसे अच्छा जवाब मिल गया है! – Rhyous

4

आप अपने सम्मिलन कथन द्वारा आवश्यक कॉलम नामों का चयन करके एक दृश्य बना सकते हैं, INSERT ट्रिगर का एक इंस्टाल जोड़ें, और इस दृश्य में सम्मिलित करें।

2

ओरेकल में एक बहुमूल्य डालने में सक्षम होने से पहले, आप उस दृश्य में एक सम्मिलित एक चाल का उपयोग कर सकते हैं जिसमें इन्सर्ट करने के लिए उस पर ट्रिगर की स्थापना की गई थी। क्या यह SQL सर्वर में किया जा सकता है?

-2

// आप पहली बार तालिका

$qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')"; 

$result = @mysql_query($qry); 

$qry2 = "INSERT INTO table2 (one,two, three) VVALUES('$one','$two','$three')"; 

$result = @mysql_query($qry2); 

// या यदि आप तालिका एक

$qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')"; 


    $result = @mysql_query($qry); 

$qry2 = "INSERT INTO table2 (two) VALUES('$two')"; 

$result = @mysql_query($qry2); 

के कुछ भागों सम्मिलित करना चाहते हैं // मुझे पता है के रूप में ही सम्मिलित करना चाहते हैं, तो यह सही होने के लिए बहुत अच्छा लग रहा है, लेकिन यह काम करता है और आप क्वेरी को जोड़ना जारी रख सकते हैं बस

"$qry"-number and number in @mysql_query($qry"") 

मैं मैं कई एसक्यूएल बयान के साथ MSSQL लेन-देन के लिए

SET XACT_ABORT ON; 

के प्रयोग पर जोर देना चाहते हैं 17 टेबल इस में काम किया है की है।

+0

यदि आवेषण के बीच में कुछ गलत हो जाता है? आपके आवेषण अपूर्ण होंगे। सही? यदि ऐसा कर रहा है .. क्या आपके पास इसका इलाज करने के लिए रोलबैक फ़ंक्शन है? यदि नहीं .. आपको अपनी डेटा अखंडता में कोई समस्या है। – B4NZ41

+6

-1। यह उत्तर PHP में MySQL विधियों का उपयोग प्रतीत होता है। सवाल टैग किया गया है [टैग: एसक्यूएल] और [टैग: एसक्यूएल-सर्वर], माइस्क्लुएल या PHP का कोई उल्लेख नहीं है। – mskfisher

-1
-- ================================================ 
-- Template generated from Template Explorer using: 
-- Create Procedure (New Menu).SQL 
-- 
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below. 
-- 
-- This block of comments will not be included in 
-- the definition of the procedure. 
-- ================================================ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE InsetIntoTwoTable 

(
@name nvarchar(50), 
@Email nvarchar(50) 
) 

AS 
BEGIN 

    SET NOCOUNT ON; 


    insert into dbo.info(name) values (@name) 
    insert into dbo.login(Email) values (@Email) 
END 
GO 
+0

क्या आप कुछ स्पष्टीकरण जोड़ सकते हैं? –

+1

क्या आपने सवाल पढ़ा? –

2

देखें: https://msdn.microsoft.com/en-us/library/ms188792.aspx वे एक बहुत अच्छा उदाहरण प्रदान करते हैं।

तो, अंतिम कोड ऐसा दिखाई देगा:

SET XACT_ABORT ON; 

BEGIN TRANSACTION 
    DECLARE @DataID int; 
    INSERT INTO DataTable (Column1 ...) VALUES (....); 
    SELECT @DataID = scope_identity(); 
    INSERT INTO LinkTable VALUES (@ObjectID, @DataID); 
COMMIT 
संबंधित मुद्दे