6

我的表有很多列。我有一个复制一些数据的命令 - 将其视为克隆产品 - 但由于列将来可能会发生变化,我只想从表中选择所有内容并且只更改一列的值而不必参考其余的部分。

例如,而不是:

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)

有没有一种简单的方法可以做到这一点?

这是 iSeries 上的 DB2 数据库,但欢迎任何平台的答案。

4

5 回答 5

10

你可以这样做:

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;
于 2008-12-09T12:34:55.797 回答
3

我不认为这完全可以在 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);

然后你可以将它封装为一个函数,只需指定表、旧 id 和新 id 就可以调用它,它会很神奇。

在 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);

希望这可以帮助。

于 2009-08-03T01:26:50.077 回答
2

好的,试试这个:

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”位。

于 2009-08-03T08:35:26.947 回答
1

您的示例应该几乎可以工作。只需将新表的列名添加到其中即可。


INSERT INTO MYTABLE
(id, col1, col2)
SELECT new_id,col1, col2
FROM TABLE2
WHERE ...;
于 2008-12-09T12:18:26.780 回答
-1

我从未使用过 db2,但在 mssql 中,您可以通过以下过程解决它。此解决方案仅在您不关心项目获得什么新 ID 时才有效。

1.) 创建具有相同方案但 id 列自动递增的新表。(mssql "标识规范 = 1,标识增量 = 1)

2.) 比一个简单的

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

应该够了,一定不要在上面的语句中包含你的 id 列

于 2009-08-03T08:43:29.063 回答