Как скопировать запись в таблицу SQL, но замените уникальный идентификатор новой строки?

Этот вопрос близок к тому, что мне нужно, но мой сценарий несколько отличается. Таблица источников и таблица назначения одинаковы, а первичный ключ - уникальный идентификатор (guid). Когда я пробую это:

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

Я, очевидно, получаю нарушение ограничения первичного ключа, так как я пытаюсь скопировать первичный ключ. На самом деле, я не хочу вообще копировать первичный ключ. Скорее, я хочу создать новую. Кроме того, я хотел бы выборочно скопировать определенные поля и оставить остальные нулями. Чтобы усложнить ситуацию, мне нужно взять первичный ключ исходной записи и вставить ее в другое поле в копии (поле "Предыдущее" ).

Я уверен, что есть простое решение, я просто не знаю, сколько TSQL знает, что это такое.

Ответ 1

Попробуйте следующее:


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

Любые поля, не указанные, должны получать свое значение по умолчанию (которое обычно равно NULL, если не определено).

Ответ 2

Хорошо, я знаю, что это старая проблема, но я все равно отправляю свой ответ.

Мне нравится это решение. Мне нужно указать только столбец (ы).

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" -колонник - это столбец идентификатора и единственный столбец, который я должен указать. В любом случае это лучше, чем наоборот.: -)

Я использую SQL Server. Вы можете использовать "CREATE TABLE" и "UPDATE TABLE" в строках 1 и 2. Хм, я видел, что я действительно не дал ответ, который хотел. Он хотел также скопировать идентификатор в другой столбец. Но это решение хорошо для создания копии с новым автоматическим идентификатором.

Я редактирую свое решение с idéas от Майкла Диббеца.

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;

Вы можете удалить более одного столбца, разделив их на ",". Идентификатор: id должен быть заменен идентификатором строки, которую вы хотите скопировать. MyDatabase, MyTable и IndexField должны быть заменены вашими именами (конечно).

Ответ 3

Укажите все поля, кроме поля вашего идентификатора.

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

Ответ 4

Я предполагаю, что вы пытаетесь избежать записи всех имен столбцов. Если вы используете SQL Management Studio, вы можете легко щелкнуть правой кнопкой мыши по таблице и Script Вставить. Затем вы можете использовать этот вывод для создания своего запроса.

Ответ 5

insert into MyTable (uniqueId, column1, column2, referencedUniqueId)
select NewGuid(), // don't know this syntax, sorry
  column1,
  column2,
  uniqueId,
from MyTable where uniqueId = @Id

Ответ 6

Если "ключ" - ваше поле PK и оно автономическое.

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

он сгенерирует новую запись, скопировав поле1 и поле2 из исходной записи

Ответ 7

Вы можете сделать следующее:

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

Вместо 112 вы должны поместить номер максимального идентификатора в таблицу DENI/FRIEN01P.

Ответ 8

В моей таблице есть 100 полей, и мне нужен запрос, чтобы просто работать. Теперь я могу отключить любое количество полей с некоторой базовой условной логикой и не беспокоиться о его порядковой позиции.

  • Замените имя ниже таблицы именем своей таблицы

    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")
    
  • Замените исходное имя поля имени вашего поля 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    
    
  • Замените имена таблиц еще раз (имя целевой таблицы и имя исходной таблицы); измените условия where

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

Ответ 9

У меня такая же проблема, когда я хочу, чтобы один script работал с таблицей, в которой столбцы периодически добавляются другими разработчиками. Не только это, но я поддерживаю множество разных версий нашей базы данных, так как клиенты могут не быть в курсе текущей версии.

Я принял решение Джонаса и немного изменил его. Это позволяет мне сделать копию строки, а затем изменить первичный ключ, прежде чем добавлять его обратно в исходную исходную таблицу. Это также очень удобно для работы с таблицами, которые не допускают значения 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;

Как только вы закончите падение таблицы temp.

DROP TABLE #TempRow;

Ответ 10

Я знаю, что мой ответ опоздал на вечеринку. Но способ, который я решил, немного отличается от всех ответов.

У меня была ситуация, мне нужно клонировать строку в таблице, за исключением нескольких столбцов. У тех немногих будут новые ценности. Этот процесс должен автоматически поддерживать будущие изменения в таблице. Это подразумевает клонирование записи без указания имен столбцов.

Мой подход к

  1. Запросите Sys.Columns, чтобы получить полный список столбцов для таблицы и включить имена столбцов, которые необходимо пропустить в предложении where.
  2. Преобразуйте это в CSV как имена столбцов.
  3. Build Select... Вставить в сценарий на основе этого.


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)

Ответ 11

Вот как я это сделал, используя ASP classic, и не смог заставить его работать с ответами, приведенными выше, и я хотел иметь возможность скопировать продукт в нашей системе в новый 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")