आप SQL तालिका में रिकॉर्ड की प्रतिलिपि कैसे बनाते हैं लेकिन नई पंक्ति की अद्वितीय आईडी को स्वैप करते हैं?


123

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

insert into MyTable
    select * from MyTable where uniqueId = @Id;

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

मुझे यकीन है कि इसका एक आसान समाधान है, मैं अभी पर्याप्त TSQL नहीं जानता कि यह क्या है।

जवाबों:


186

इसे इस्तेमाल करे:


insert into MyTable(field1, field2, id_backup)
    select field1, field2, uniqueId from MyTable where uniqueId = @Id;

निर्दिष्ट नहीं किए गए किसी भी फ़ील्ड को उनका डिफ़ॉल्ट मान प्राप्त होना चाहिए (जो कि परिभाषित नहीं होने पर आमतौर पर NULL होता है)।


2
बहुत बढ़िया। एक जादू की तरह काम किया। एक बार लिखने के बाद यह बहुत स्पष्ट था। धन्यवाद!!
किलाहोफर

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

93

ठीक है, मुझे पता है कि यह एक पुराना मुद्दा है लेकिन मैं अपना जवाब वैसे भी पोस्ट करता हूं।

मुझे यह समाधान पसंद है। मुझे केवल पहचान कॉलम निर्दिष्ट करना है।

SELECT * INTO TempTable FROM MyTable_T WHERE id = 1;
ALTER TABLE TempTable DROP COLUMN id;
INSERT INTO MyTable_T SELECT * FROM TempTable;
DROP TABLE TempTable;

"Id" -column पहचान कॉलम है और यह एकमात्र कॉलम है जिसे मुझे निर्दिष्ट करना है। यह वैसे भी अन्य तरीके से बेहतर है। :-)

मैं SQL Server का उपयोग करता हूं। आप " CREATE TABLE" और "" का उपयोग करना चाह सकते हैंUPDATE TABLE पंक्ति 1 और 2 में " । हम्म, मैंने देखा कि मैंने वास्तव में वह उत्तर नहीं दिया जो वह चाहता था। वह आईडी को दूसरे कॉलम में भी कॉपी करना चाहता था। लेकिन यह समाधान नई ऑटो-आईडी के साथ प्रतिलिपि बनाने के लिए अच्छा है।

मैं माइकल डिबेट्स से आइडिया के साथ अपने समाधान को संपादित करता हूं।

use MyDatabase; 
SELECT * INTO #TempTable FROM [MyTable] WHERE [IndexField] = :id;
ALTER TABLE #TempTable DROP COLUMN [IndexField]; 
INSERT INTO [MyTable] SELECT * FROM #TempTable; 
DROP TABLE #TempTable;

आप उन्हें एक "," के साथ अलग करके एक से अधिक कॉलम छोड़ सकते हैं। : आईडी को उस पंक्ति की आईडी से प्रतिस्थापित किया जाना चाहिए जिसे आप कॉपी करना चाहते हैं। MyDatabase, MyTable और IndexField को आपके नाम (निश्चित रूप से) से बदला जाना चाहिए।


1
यह मुश्किल है, आप कैसे सुनिश्चित कर सकते हैं कि आप लाइन 3 में INSERT INTO के दौरान सही आईडी को सही पंक्ति में कॉपी कर रहे हैं?
एर्नो

आईडी-कॉलम एक पहचान स्तंभ है (मेरी तालिका में) इसलिए मुझे मूल्य की परवाह नहीं है। मैं सिर्फ "पुराना" के समान मान रखने वाला एक नया रिकॉर्ड चाहता हूं।
जोनास

9
के लिए TempTable, यह उपयोग करना बेहतर नहीं होगा #TempTable, इसलिए यह एक सच्ची अस्थायी तालिका है?
जेस

3
मैं निम्नलिखित प्रारूप में use MyDatabase; SELECT * INTO #TempTable FROM [TABLE] WHERE [indexfield] = :id; ALTER TABLE #TempTable DROP COLUMN [indexfield]; INSERT INTO [TABLE] SELECT * FROM #TempTable; DROP TABLE #TempTable;इसका उपयोग कर रहा हूं इस तरह से मुझे पता है कि यह बिना किसी देरी के डिस्क को इंटरमिटेंड फाइल लिखने से किसी भी देरी के बिना साफ हो जाएगा।
शाचलैक

3
$identityयदि आप अपना पहचान कॉलम नाम हार्ड कोड नहीं करना चाहते हैं, तो आप उसका उपयोग भी कर सकते हैं
Factor Mystic

12

मुझे लगता है कि आप सभी स्तंभ नामों को लिखने से बचने की कोशिश कर रहे हैं। यदि आप SQL प्रबंधन स्टूडियो का उपयोग कर रहे हैं, तो आप आसानी से तालिका पर क्लिक कर सकते हैं और सम्मिलित रूप में स्क्रिप्ट कर सकते हैं .. तो आप अपनी क्वेरी बनाने के लिए उस आउटपुट के साथ गड़बड़ कर सकते हैं।


10

सभी फ़ील्ड लेकिन अपनी आईडी फ़ील्ड निर्दिष्ट करें।

INSERT INTO MyTable (FIELD2, FIELD3, ..., FIELD529, PreviousId)
SELECT FIELD2, NULL, ..., FIELD529, FIELD1
FROM MyTable
WHERE FIELD1 = @Id;

6

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

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

यह कोड 'ABC' के लिए 'XYZ' की पंक्ति की प्रतिलिपि बनाता है

SELECT * INTO #TempRow FROM SourceTable WHERE KeyColumn = 'ABC';
UPDATE #TempRow SET KeyColumn = 'XYZ';
INSERT INTO SourceTable SELECT * FROM #TempRow;
DELETE #TempRow;

एक बार जब आप ड्रॉप समाप्त हो गया है अस्थायी तालिका।

DROP TABLE #TempRow;

4

मुझे पता है कि मेरा जवाब पार्टी के लिए देर से है। लेकिन जिस तरह से मैंने हल किया है वह सभी उत्तरों से थोड़ा अलग है।

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

मेरा दृष्टिकोण है,

  1. तालिका के लिए स्तंभों की पूरी सूची प्राप्त करने के लिए क्वेरी Sys.Columns और जहाँ खंड में छोड़ करने के लिए स्तंभों के नाम शामिल हैं।
  2. स्तंभ नाम के रूप में CSV में कनवर्ट करें।
  3. बिल्ड का चयन करें ... इस पर आधारित स्क्रिप्ट में सम्मिलित करें।


declare @columnsToCopyValues varchar(max), @query varchar(max)
SET @columnsToCopyValues = ''

--Get all the columns execpt Identity columns and Other columns to be excluded. Say IndentityColumn, Column1, Column2 Select @columnsToCopyValues = @columnsToCopyValues + [name] + ', ' from sys.columns c where c.object_id = OBJECT_ID('YourTableName') and name not in ('IndentityColumn','Column1','Column2') Select @columnsToCopyValues = SUBSTRING(@columnsToCopyValues, 0, LEN(@columnsToCopyValues)) print @columnsToCopyValues

Select @query = CONCAT('insert into YourTableName (',@columnsToCopyValues,', Column1, Column2) select ', @columnsToCopyValues, ',''Value1'',''Value2'',', ' from YourTableName where IndentityColumn =''' , @searchVariable,'''')

print @query exec (@query)



1

यदि "कुंजी" आपका PK क्षेत्र है और यह ऑटोनोमेरिक है।

insert into MyTable (field1, field2, field3, parentkey)
select field1, field2, null, key from MyTable where uniqueId = @Id

यह मूल रिकॉर्ड से फ़ील्ड 1 और फ़ील्ड 2 की प्रतिलिपि बनाते हुए एक नया रिकॉर्ड बनाएगा


1

मेरी तालिका में 100 फ़ील्ड हैं, और मुझे सिर्फ काम करने के लिए एक क्वेरी की आवश्यकता है। अब मैं कुछ बुनियादी सशर्त तर्क के साथ किसी भी क्षेत्र को बदल सकता हूं और इसके क्रमिक स्थिति के बारे में चिंता नहीं कर सकता।

  1. नीचे दी गई तालिका नाम को अपनी तालिका नाम से बदलें

    SQLcolums = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE (TABLE_NAME = 'TABLE-NAME')"
    
    Set GetColumns = Conn.Execute(SQLcolums)
    Do WHILE not GetColumns.eof
    
    colName = GetColumns("COLUMN_NAME")
  2. मूल पहचान फ़ील्ड नाम को अपने PK फ़ील्ड नाम से बदलें

    IF colName = "ORIGINAL-IDENTITY-FIELD-NAME" THEN ' ASSUMING THAT YOUR PRIMARY KEY IS THE FIRST FIELD DONT WORRY ABOUT COMMAS AND SPACES
        columnListSOURCE = colName 
        columnListTARGET = "[PreviousId field name]"
    ELSE
        columnListSOURCE = columnListSOURCE & colName
        columnListTARGET = columnListTARGET & colName
    END IF
    
    GetColumns.movenext
    
    loop
    
    GetColumns.close    
  3. तालिका नामों को फिर से बदलें (दोनों लक्ष्य तालिका नाम और स्रोत तालिका नाम); अपनी whereशर्तों को संपादित करें

    SQL = "INSERT INTO TARGET-TABLE-NAME (" & columnListTARGET & ") SELECT " & columnListSOURCE & " FROM SOURCE-TABLE-NAME WHERE (FIELDNAME = FIELDVALUE)" 
    Conn.Execute(SQL)

0

आप इस तरह कर सकते हैं:

INSERT INTO DENI/FRIEN01P 
SELECT 
   RCRDID+112,
   PROFESION,
   NAME,
   SURNAME,
   AGE, 
   RCRDTYP, 
   RCRDLCU, 
   RCRDLCT, 
   RCRDLCD 
FROM 
   FRIEN01P      

112 के बजाय आपको तालिका DENI / FRIEN01P में अधिकतम आईडी की संख्या डालनी चाहिए।


0

यहाँ मैंने एएसपी क्लासिक का उपयोग कैसे किया और ऊपर दिए गए उत्तरों के साथ काम करने के लिए इसे प्राप्त नहीं कर सका और मैं चाहता था कि हमारे सिस्टम में एक उत्पाद को एक नए product_id पर कॉपी किया जा सके और जरूरत पड़ने पर भी हम काम कर सकें। तालिका में और कॉलम जोड़ें।

Cn.Execute("CREATE TEMPORARY TABLE temprow AS SELECT * FROM product WHERE product_id = '12345'")
Cn.Execute("UPDATE temprow SET product_id = '34567'")
Cn.Execute("INSERT INTO product SELECT * FROM temprow")
Cn.Execute("DELETE temprow")
Cn.Execute("DROP TABLE temprow")

मुझे नहीं लगता कि आपको इसे पूरा करने के लिए 5 अलग एसक्यूएल कमांड जारी करने की आवश्यकता है। और यह भी, कि आप 2 डी कमांड में कौन निर्धारित करते हैं, कि उत्पाद आईडी 34567 होनी चाहिए?
ज्यारा

34567 सिर्फ एक उदाहरण है। आप इसे एक चर या जो कुछ भी आप चाहते हैं, पर सेट कर सकते हैं। यदि आपके पास एएसपी क्लासिक में ऐसा करने का बेहतर तरीका है, तो मुझे बताएं। :)
डैनियल नॉर्ड

आप इन सभी को एक पंक्ति में चलाने के लिए एक संग्रहित खरीद लिख सकते हैं। इसके अलावा, आमतौर पर पीके एक ऑटो वेतन वृद्धि मूल्य हुआ करता था। इसलिए खुद को सौंपना अच्छा विचार नहीं है।
ज्यारा

आपने कहा प्रक्रिया कैसे लिखेंगे? कृपया मुझे ज्ञान दो। पी? अगर आपका मतलब आर्टिकल आईडी है, तो हमारे सिस्टम में हम आर्टिकल आईडी का उपयोग करते हैं, जिसके आधार पर हम उन्हें किस स्टोर में बेचते हैं। उदाहरण के लिए हमारे टॉय स्टोर में सभी का आर्टिकल नंबर 30 से शुरू होता है और हमारा स्पोर्ट्स स्टोर 60 से शुरू होता है। इसके अलावा हम स्पेस को बचाते हैं ताकि अगर हम उदाहरण के लिए, एक नया रंग प्राप्त करें, हमारे पास उसी तरह के अन्य लोगों के बगल में एक लेख आईडी हो सकता है। जैसा कि कहा गया, यह मेरा समाधान था जो हमारी प्रणाली में काम करता है। आप कैसे चर निर्धारित करते हैं, यह महत्वपूर्ण नहीं है और अधिकांश प्रोग्रामर समझेंगे कि उनके और उनके सिस्टम के लिए क्या काम करता है।
डैनियल नॉर्ड

पीके प्राथमिक कुंजी के लिए खड़ा है। आपके मामले में इसकी '12345' है। यदि आप नहीं जानते कि क्लासिक एएसपी में संग्रहीत खरीद का उपयोग कैसे करें, इसके लिए stackoverflow.com/questions/21561657/… देखें । ऐसा करने के लिए, उन सभी को एक संग्रहित खरीद में ले जाएं और अपना '12345' पैरामीटर के रूप में पास करें। जिस तरह से आप काम करेंगे, लेकिन इन दिनों पैरामीटर बनाए गए लिपियों की सिफारिश की जाती है।
जायरा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.