2012-06-13 18 views
27

में अपरर्ट (अपडेट या डालने) कैसे करें मेरे पास टेबल है जिसमें मैं कर्मचारी के लिए पंक्तियां डाल रहा हूं लेकिन अगली बार जब मैं पंक्ति डालना चाहता हूं तो मैं उस कर्मचारी के लिए फिर से डेटा डालना नहीं चाहता हूं यदि आवश्यक हो तो आवश्यक कॉलम के साथ अपडेट करें, तो नई पंक्तिएसक्यूएल सर्वर 2005

हम SQL Server 2005 में यह कैसे कर सकते हैं?

मैं jsp उपयोग कर रहा हूँ

मेरी क्वेरी

String sql="insert into table1(id,name,itemname,itemcatName,itemQty)values('val1','val2','val3','val4','val5')"; 

है अगर यह पहली बार तो किसी और डेटाबेस में डालने अद्यतन यह

कैसे करना है मौजूद है?

+1

इसके साथ ** मेरिज क्लॉज ** का उपयोग करने के बारे में उपयोगकर्ता के विवरण के साथ एक अस्थायी तालिका? क्या यह बेहतर नहीं है? –

+0

साखाइल - हाँ यह है - तो आपका जवाब कहां है ... उत्तर .. अनुभाग? –

+0

'MERGE' इस उपयोग के मामले के लिए उपयुक्त होगा लेकिन यह ध्यान दिया जाना चाहिए कि इसे केवल SQL Server 2008 में पेश किया गया था (संभवतः, ओपी अभी भी छह साल बाद 2005 का उपयोग नहीं कर रहा है)। –

उत्तर

32

कोशिश होने की जाँच करने के लिए:

IF NOT EXISTS (SELECT * FROM dbo.Employee WHERE ID = @SomeID) 

    INSERT INTO dbo.Employee(Col1, ..., ColN) 
    VALUES(Val1, .., ValN) 

ELSE 

    UPDATE dbo.Employee 
    SET Col1 = Val1, Col2 = Val2, ...., ColN = ValN 
    WHERE ID = @SomeID 

आप आसानी से एक संग्रहीत प्रक्रिया में इस लपेट सकता है और सिर्फ बाहर से संग्रहीत प्रक्रिया कॉल (जैसे सी # या जो भी आप उपयोग कर रहे हैं एक प्रोग्रामिंग भाषा से जैसे) ।

अद्यतन: या तो आप सिर्फ एक लंबी श्रृंखला में इस पूरे बयान लिख सकते हैं (साध्य है - लेकिन वास्तव में बहुत उपयोगी) - या आप एक संग्रहीत प्रक्रिया में लपेट कर सकते हैं:

CREATE PROCEDURE dbo.InsertOrUdpateEmployee 
     @ID INT, 
     @Name VARCHAR(50), 
     @ItemName VARCHAR(50), 
     @ItemCatName VARCHAR(50), 
     @ItemQty DECIMAL(15,2) 
AS BEGIN 
    IF NOT EXISTS (SELECT * FROM dbo.Table1 WHERE ID = @ID) 
     INSERT INTO dbo.Table1(ID, Name, ItemName, ItemCatName, ItemQty) 
     VALUES(@ID, @Name, @ItemName, @ItemCatName, @ItemQty) 
    ELSE 
     UPDATE dbo.Table1 
     SET Name = @Name, 
      ItemName = @ItemName, 
      ItemCatName = @ItemCatName, 
      ItemQty = @ItemQty 
     WHERE ID = @ID 
END 

और फिर बस अपने एडीओ.NET कोड

+0

जहां उपरोक्त एसक्यूएल स्ट्रिंग में कोड ऊपर लिखा गया है या ट्रिगर या प्रक्रिया बनाने की आवश्यकता है। – ybc126

+1

एकल स्ट्रिंग में लिखना यह स्ट्रिंग एसक्यूएल = जैसा दिखता है "अगर कर्मचारी नहीं है (कर्मचारी * आईडी से कुछ चुनें = @ किसी अन्य) कर्मचारी (कॉल 1, ..., वीएलएन) मूल्यों में प्रवेश करें (val1, .., valn) ELSE अद्यतन कर्मचारी सेट col1 = val1, col2 = val2, ..., coln = valN कहां आईडी = @ कुछ आईडी " यह काम करेगा। – ybc126

+0

@ ybc126: यदि आपके पास अपने एसक्यूएल में आवश्यक रिक्त स्थान हैं - हाँ। लेकिन ऐसा कुछ ** ** निश्चित रूप से ** सलाह नहीं है! इसे संग्रहीत प्रक्रिया में डालकर (या इसे संभालने के लिए ओआरएम का उपयोग करना) ** बहुत बेहतर ** –

1

से संग्रहित प्रक्रिया को कॉल करें, आप इसे INSTEAD OF INSERT तालिका पर ट्रिगर के साथ कर सकते हैं, जो पंक्ति के अस्तित्व की जांच करता है और उसके बाद अपडेट/आवेषण पहले से मौजूद है या नहीं। वहाँ कैसे MSDN here पर एसक्यूएल सर्वर 2000 + के लिए यह करने के लिए का एक उदाहरण है:

CREATE TRIGGER IO_Trig_INS_Employee ON Employee 
INSTEAD OF INSERT 
AS 
BEGIN 
SET NOCOUNT ON 
-- Check for duplicate Person. If no duplicate, do an insert. 
IF (NOT EXISTS (SELECT P.SSN 
     FROM Person P, inserted I 
     WHERE P.SSN = I.SSN)) 
    INSERT INTO Person 
     SELECT SSN,Name,Address,Birthdate 
     FROM inserted 
ELSE 
-- Log attempt to insert duplicate Person row in PersonDuplicates table. 
    INSERT INTO PersonDuplicates 
     SELECT SSN,Name,Address,Birthdate,SUSER_SNAME(),GETDATE() 
     FROM inserted 
-- Check for duplicate Employee. If no duplicate, do an insert. 
IF (NOT EXISTS (SELECT E.SSN 
     FROM EmployeeTable E, inserted 
     WHERE E.SSN = inserted.SSN)) 
    INSERT INTO EmployeeTable 
     SELECT EmployeeID,SSN, Department, Salary 
     FROM inserted 
ELSE 
--If duplicate, change to UPDATE so that there will not 
--be a duplicate key violation error. 
    UPDATE EmployeeTable 
     SET EmployeeID = I.EmployeeID, 
      Department = I.Department, 
      Salary = I.Salary 
    FROM EmployeeTable E, inserted I 
    WHERE E.SSN = I.SSN 
END 
11

आपको यह देखना होगा कि क्या पंक्ति सम्मिलित या अद्यतन किया जाना चाहिए @@ROWCOUNT उपयोग कर सकते हैं:

update table1 
set name = 'val2', itemname = 'val3', itemcatName = 'val4', itemQty = 'val5' 
where id = 'val1' 
if @@ROWCOUNT = 0 
insert into table1(id, name, itemname, itemcatName, itemQty) 
values('val1', 'val2', 'val3', 'val4', 'val5') 
इस मामले में अगर में

अद्यतन विफल रहता है, नई पंक्ति

4

(मेरा उत्तर से कम है, लेकिन यह है कि मुझे एहसास हुआ कि बाद Insert into a MySQL table or update if exists में इस पर एक बेहतर सवाल & जवाब है)

012 डाला जाएगा

आप देख सकते हैं पंक्ति मौजूद है, और फिर सम्मिलित या अपडेट करें, लेकिन यह आप दो एसक्यूएल बजाय संचालन एक प्रदर्शन किया जाएगा की गारंटी देता है:

  1. जांच करता है, तो पंक्ति मौजूद है
  2. डालने या अद्यतन पंक्ति

एक बेहतर समाधान हमेशा पहले अद्यतन करने के लिए है, और अगर कोई भी पंक्ति को अद्यतन किया गया है, तो एक सम्मिलित करें, जैसे ऐसा:

update table1 
set name = 'val2', itemname = 'val3', itemcatName = 'val4', itemQty = 'val5' 
where id = 'val1' 

if @@ROWCOUNT = 0 
    insert into table1(id, name, itemname, itemcatName, itemQty) 
    values('val1', 'val2', 'val3', 'val4', 'val5') 

यह या तो पंक्ति में पहले से मौजूद है या नहीं, इस पर निर्भर करता है कि यह एक एसक्यूएल ऑपरेशंस या दो एसक्यूएल ऑपरेशंस लेगा।

लेकिन यदि प्रदर्शन वास्तव में एक मुद्दा है, तो आपको यह पता लगाने की आवश्यकता है कि ऑपरेशन INSERT या UPDATE के होने की अधिक संभावना है या नहीं। यदि अद्यतन अधिक आम हैं, तो ऊपर करें। यदि INSERT अधिक आम हैं, तो आप इसे विपरीत में कर सकते हैं, लेकिन आपको त्रुटि प्रबंधन जोड़ना होगा। अगर आप एक अद्यतन या सम्मिलित करने की ज़रूरत

BEGIN TRY 
    insert into table1(id, name, itemname, itemcatName, itemQty) 
    values('val1', 'val2', 'val3', 'val4', 'val5') 
END TRY 
BEGIN CATCH 
    update table1 
    set name = 'val2', itemname = 'val3', itemcatName = 'val4', itemQty = 'val5' 
    where id = 'val1' 
END CATCH 

वास्तव में कुछ होने के लिए, आप एक ही लेन-देन के भीतर दो आपरेशन क्या करना है। सैद्धांतिक रूप से, पहले अद्यतन या INSERT (या यहां तक ​​कि EXISTS चेक) के ठीक बाद, लेकिन अगले INSERT/UPDATE स्टेटमेंट से पहले, डेटाबेस बदल सकता था, जिससे दूसरा कथन विफल हो गया। यह बहुत दुर्लभ है, और लेनदेन के लिए ओवरहेड इसके लायक नहीं हो सकता है।

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

SQL transaction statements, race conditions, SQL MERGE statement पढ़ने पर विचार करें।

+0

आपके द्वारा उल्लिखित प्रश्न का लिंक MySQL के लिए विशिष्ट है, जहां यह थ्रेड SQL सर्वर से संबंधित है जिसमें ऑन डिप्लिकेट कुंजी अपडेट विकल्प नहीं है। क्या आप स्पष्ट कर सकते हैं कि आप किस उत्तर का मतलब है या यह आपके हिस्से पर एक गलती है? –

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