Как я могу скопировать запись, меняя только идентификатор? - PullRequest
6 голосов
/ 09 декабря 2008

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

Например, вместо:

INSERT INTO MYTABLE (
SELECT NEW_ID, COLUMN_1, COLUMN_2, COLUMN_3, etc
FROM MYTABLE)

Я бы хотел что-то похожее

INSERT INTO MYTABLE (
SELECT * {update this, set ID = NEW_ID}
FROM MYTABLE)

Есть ли простой способ сделать это?

Это база данных DB2 в iSeries, но ответы для любой платформы приветствуются.

Ответы [ 5 ]

10 голосов
/ 09 декабря 2008

Вы можете сделать это:

create table mytable_copy as select * from mytable;
update mytable_copy set id=new_id;
insert into mytable select * from mytable_copy;
drop table mytable_copy;
3 голосов
/ 03 августа 2009

Я не думаю, что это полностью выполнимо в SQL без необходимости создавать временную таблицу. Делать это в памяти должно быть намного быстрее. Остерегайтесь, если вы идете по маршруту временной таблицы, вы должны выбрать уникальное имя для своей таблицы для каждого вызова функции, чтобы избежать условия гонки, когда ваш код выполняется дважды одновременно и объединяет две строки данных в одну временную таблицу.

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

array_of_field_names = conn->get_field__list;
array_of_row_values = conn->execute ("SELECT... ");
array_of_row_values ["ID"] = new_id_value
insert_query_string = "construct insert query string from list of field names and values";
conn->execute (insert_query_string);

Затем вы можете инкапсулировать это как функцию и просто вызвать ее, указав таблицу, старый идентификатор и новый идентификатор, и это сработает, это волшебство.

В коде Perl следующий фрагмент кода будет делать:

$table_name = "MYTABLE";
$field_name = "ID";
$existing_field_value = "100";
$new_field_value = "101";

my $q = $dbh->prepare ("SELECT * FROM $table_name WHERE $field_name=?");
$q->execute ($existing_field_value);
my $rowdata = $q->fetchrow_hashref; # includes field names
$rowdata->{$field_name} = $new_field_value;

my $insq = $dbh->prepare ("INSERT INTO $table_name (" . join (", ", keys %$rowdata) . 
    ") VALUES (" . join (", ", map { "?" } keys %$rowdata) . ");";
$insq->execute (values %$rowdata);

Надеюсь, это поможет.

2 голосов
/ 03 августа 2009

Хорошо, попробуйте это:

declare @othercols nvarchar(max);
declare @qry nvarchar(max);

select @othercols = (
select ', ' + quotename(name)
from sys.columns
where object_id = object_id('tableA')
and name <> 'Field3'
and is_identity = 0
for xml path(''));

select @qry = 'insert mynewtable (changingcol' + @othercols + ') select newval' + @othercols;

exec sp_executesql @qry;

Прежде чем запускать строку "sp_executesql", пожалуйста, выберите "select @qry", чтобы увидеть, какую команду вы собираетесь запустить.

И, конечно, вы можете добавить это в хранимую процедуру и передать переменную вместо бита 'Field3'.

Rob

1 голос
/ 09 декабря 2008

Ваш пример должен почти сработать. Просто добавьте в него имена столбцов новой таблицы.


INSERT INTO MYTABLE
(id, col1, col2)
SELECT new_id,col1, col2
FROM TABLE2
WHERE ...;
0 голосов
/ 03 августа 2009

Я никогда не работал с db2, но в mssql вы можете решить эту проблему с помощью следующей процедуры. Это решение работает, только если вам все равно, какой новый идентификатор получают элементы.

1.) Создать новую таблицу с той же схемой, но там, где столбец id увеличивается автоматически. (mssql "спецификация идентичности = 1, приращение идентичности = 1)

2.), Чем простой

insert into newTable(col1, col2, col3)
select (col1, col2, col3) from oldatable

должно быть достаточно, не указывайте ваш идентификатор в вышеприведенном выражении

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...