2008-12-09 24 views
6

Bảng của tôi có một số lượng lớn các cột. Tôi có một lệnh để sao chép một số dữ liệu - nghĩ về nó như nhân bản một sản phẩm - nhưng khi các cột có thể thay đổi trong tương lai, tôi chỉ muốn chọn mọi thứ từ bảng và chỉ thay đổi giá trị của một cột mà không cần phải tham khảo phần còn lại.Làm cách nào để sao chép bản ghi, chỉ thay đổi id?

Ví dụ thay vì:

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

Tôi muốn một cái gì đó giống như

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

Có một cách đơn giản để làm điều này?

Đây là cơ sở dữ liệu DB2 trên iSeries, nhưng các câu trả lời cho mọi nền tảng đều được chào đón.

Trả lời

10

Bạn có thể làm điều này:

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; 
+2

Bạn có thể thực hiện dòng đầu tiên bằng lệnh SELECT INTO . –

1

Ví dụ của bạn gần như hoạt động. Chỉ cần thêm tên cột của bảng mới vào nó.


INSERT INTO MYTABLE 
(id, col1, col2) 
SELECT new_id,col1, col2 
FROM TABLE2 
WHERE ...; 
+1

Đó chỉ bản sao dữ liệu cho các cột cụ thể - Mục đích của tôi là để tránh niêm yết mỗi cột duy nhất. Tôi sẽ làm cho câu hỏi rõ ràng hơn một chút - cảm ơn. –

+1

những gì về việc tạo ra một chức năng hoặc proc lưu trữ hoặc bất cứ điều gì mà xây dựng các truy vấn động cho bạn? – Salamander2007

+0

Vẫn có nghĩa là bạn phải chỉ định các trường mặc dù ... –

3

Tôi không nghĩ rằng đây là doable hoàn toàn trong SQL mà không đi đến những rắc rối của việc tạo ra một bảng temp. Làm nó trong bộ nhớ nên nhanh hơn nhiều. Cẩn thận nếu bạn đi theo con đường bảng tạm thời mà bạn phải chọn một tên duy nhất cho bảng của bạn cho mỗi lời gọi hàm để tránh điều kiện chủng tộc nơi mã của bạn chạy hai lần cùng một lúc và mangles hai hàng dữ liệu vào một bảng tạm thời.

Tôi không biết bạn đang sử dụng loại ngôn ngữ nào nhưng có thể lấy danh sách các trường trong chương trình của bạn. Tôi sẽ làm như sau:

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

Sau đó, bạn có thể đóng gói đó làm chức năng và gọi nó là chỉ định bảng, id cũ và id mới và nó hoạt động thật kỳ diệu.

Trong mã Perl đoạn sau đây sẽ làm:

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

Hope this helps.

2

Ok, hãy thử này:

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; 

Trước khi bạn chạy "sp_executesql" dòng, hãy làm "chọn @qry" để xem những gì các lệnh là bạn đang đi để chạy.

Và tất nhiên, bạn có thể muốn gắn điều này vào một quy trình được lưu trữ và chuyển vào một biến thay vì bit 'Field3'.

Rob

+0

Tôi nên đề cập - đây là phiên bản SQL Server 2005+ ... –

+0

Có, tôi có thể làm điều gì đó tương tự với danh mục hệ thống db2. Sẽ thấy hiệu suất như thế nào so với kỹ thuật copy-copyback nếu tôi có thời gian. Cảm ơn. –

+0

Và tất nhiên, nếu bạn chỉ muốn một số dòng nhất định, chỉ cần thêm mệnh đề WHERE vào @qry. –

-1

Tôi chưa bao giờ làm việc với db2 nhưng trong mssql bạn có thể giải quyết bằng quy trình sau. giải pháp này chỉ hoạt động nếu bạn không quan tâm những gì mới id các mục nhận được.

1.) tạo bảng mới với cùng một lược đồ nhưng trong đó cột id tăng tự động. (mssql "đặc điểm nhận dạng = 1, số nhận dạng = 1)

2.) So với một đơn giản

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

nên là đủ, hãy chắc chắn là không bao gồm cột id của bạn trong tuyên bố trên

Các vấn đề liên quan