Как скопировать запись в таблицу 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
Я знаю, что мой ответ опоздал на вечеринку. Но способ, который я решил, немного отличается от всех ответов.
У меня была ситуация, мне нужно клонировать строку в таблице, за исключением нескольких столбцов. У тех немногих будут новые ценности. Этот процесс должен автоматически поддерживать будущие изменения в таблице. Это подразумевает клонирование записи без указания имен столбцов.
Мой подход к
- Запросите Sys.Columns, чтобы получить полный список столбцов для таблицы и включить имена столбцов, которые необходимо пропустить в предложении where.
- Преобразуйте это в CSV как имена столбцов.
- 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")