Jak skopiować rekord w tabeli SQL, ale zamienić unikalny identyfikator nowego wiersza?

To pytanie jest zbliżone do tego, czego potrzebuję, ale mój scenariusz jest nieco inny. Tabela źródłowa i tabela docelowa są takie same, a klucz podstawowy to uniqueidentifier (guid). Kiedy próbuję tego:

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

Oczywiście dostaję naruszenie ograniczenia klucza głównego, ponieważ próbuję skopiować klucz główny. Właściwie to nie chcę kopiować klucza głównego. Raczej chcę stworzyć nowy. Dodatkowo chciałbym wybiórczo skopiować pewne pola, a pozostałe pozostawić null. Aby sprawy były bardziej złożone, muszę wziąć klucz podstawowy oryginalnego rekordu i wstawić go do innego pola w kopii (pole PreviousId).

Jestem pewien, że jest na to łatwe rozwiązanie, po prostu nie znam wystarczająco TSQL, aby wiedzieć, co to jest.

Author: Community, 2008-09-29

10 answers

Spróbuj tego:


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

Wszelkie nieokreślone pola powinny otrzymać wartość domyślną (która jest zwykle NULL, gdy nie jest zdefiniowana).

 162
Author: AaronSieb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-29 20:54:06

Ok, wiem, że to stary numer, ale i tak zamieszczam swoją odpowiedź.

Podoba mi się to rozwiązanie. Muszę tylko określić kolumnę(y) tożsamości.
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;

Kolumna "id" jest kolumną tożsamości i jest to jedyna kolumna, którą muszę określić. I tak jest lepiej niż na odwrót. :-)

Używam SQL Server. Możesz użyć "CREATE TABLE " i "UPDATE TABLE " w wierszu 1 i 2. Hmm, widziałem, że tak naprawdę nie dałem odpowiedzi, że chciał. Chciał skopiować id do innej kolumny również. Ale to rozwiązanie jest dobre do tworzenia kopii z nowym auto-id.

Edytuję moje rozwiązanie za pomocą idéas od Michaela Dibbetsa.

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;

Możesz upuścić więcej niż jedną kolumnę, oddzielając je znakiem",". Id :należy zastąpić id wiersza, który chcesz skopiować. MyDatabase, MyTable i IndexField powinny zostać zastąpione Twoimi nazwami (oczywiście).

 69
Author: Jonas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-19 12:05:11

Określ wszystkie pola oprócz pola ID.

INSERT INTO MyTable (FIELD2, FIELD3, ..., FIELD529, PreviousId)
SELECT FIELD2, NULL, ..., FIELD529, FIELD1
FROM MyTable
WHERE FIELD1 = @Id;
 9
Author: Scott Bevington,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-29 17:37:25

Zgaduję, że próbujesz uniknąć wypisywania wszystkich nazw kolumn. Jeśli używasz SQL Management Studio, możesz łatwo kliknąć prawym przyciskiem myszy na tabeli i skrypt jako Wstaw.. następnie możesz zadzierać z tym wyjściem, aby utworzyć zapytanie.

 9
Author: Matt Hinze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-21 19:49:10
insert into MyTable (uniqueId, column1, column2, referencedUniqueId)
select NewGuid(), // don't know this syntax, sorry
  column1,
  column2,
  uniqueId,
from MyTable where uniqueId = @Id
 2
Author: Jeffrey L Whitledge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-29 17:39:42

Jeśli "klucz" jest twoim polem PK i jest autonumeryczny.

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

Wygeneruje nowy rekord, kopiując field1 i field2 z oryginalnego rekordu

 1
Author: Eduardo Campañó,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-29 17:42:34

Możesz zrobić tak:

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

Tam zamiast 112 powinieneś umieścić numer maksymalnego id w tabeli DENI / FRIEN01P.

 0
Author: Denis Kutlubaev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-18 16:54:25

Moja tabela ma 100 pól i potrzebowałem zapytania, aby po prostu działać. Teraz mogę przełączyć dowolną liczbę pól z jakąś podstawową logiką warunkową i nie martwić się o jego pozycję porządkową.

  1. Zamień poniższą nazwę tabeli na nazwę tabeli

    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. Zastąp oryginalną nazwę pola tożsamości nazwą pola 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. Zastąp ponownie nazwy tabel (zarówno nazwa tabeli docelowej, jak i nazwa tabeli źródłowej); edytuj swoje where warunki

    SQL = "INSERT INTO TARGET-TABLE-NAME (" & columnListTARGET & ") SELECT " & columnListSOURCE & " FROM SOURCE-TABLE-NAME WHERE (FIELDNAME = FIELDVALUE)" 
    Conn.Execute(SQL)
    
 0
Author: Rit Man,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-20 18:33:19

Mam ten sam problem, w którym chcę, aby pojedynczy skrypt działał z tabelą, która ma kolumny dodawane okresowo przez innych programistów. Nie tylko to, ale wspieram wiele różnych wersji naszej bazy danych, ponieważ klienci mogą nie być na bieżąco z aktualną wersją.

Wziąłem rozwiązanie Jonasa i lekko go zmodyfikowałem. To pozwala mi zrobić kopię wiersza, a następnie zmienić klucz główny przed dodaniem go z powrotem do oryginalnej tabeli źródłowej. Jest to również bardzo przydatne do pracy z tabelami, które nie zezwalają na wartości NULL w kolumnach i nie chcesz podawać nazwy każdej kolumny we wkładce.

Ten kod kopiuje wiersz dla " ABC " do " XYZ "

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

Po zakończeniu spadku tabeli temp.

DROP TABLE #TempRow;
 0
Author: TonyT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-05 00:02:29

Wiem, że moja odpowiedź jest spóźniona na przyjęcie. Ale sposób, w jaki rozwiązałem, jest nieco inny niż wszystkie odpowiedzi.

Miałem sytuację, muszę sklonować wiersz w tabeli z wyjątkiem kilku kolumn. Ci nieliczni będą mieli nowe wartości. Proces ten powinien automatycznie wspierać przyszłe zmiany w tabeli. Oznacza to, że należy sklonować rekord bez podawania nazw kolumn.

Moje podejście to,

  1. Query Sys.Kolumny, aby uzyskać pełną listę kolumn dla tabeli i zawierać nazwy kolumn do pominięcia w klauzuli where.
  2. Konwertuj to do pliku CSV jako nazwy kolumn.
  3. Build Select ... Insert into script based on this.


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)

 0
Author: Jeyara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-18 04:55:26