2008-12-09 8 views
6

Mi tabla tiene una gran cantidad de columnas. Tengo un comando para copiar algunos datos, piénselo como clonar un producto, pero como las columnas pueden cambiar en el futuro, me gustaría seleccionar solo todo de la tabla y solo cambiar el valor de una columna sin tener que hacer referencia a el resto.¿Cómo puedo copiar un registro, cambiando solo la identificación?

Por ejemplo, en lugar de:

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

me gustaría algo parecido

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

¿Hay una manera simple de hacer esto?

Esta es una base de datos DB2 en un iSeries, pero las respuestas para cualquier plataforma son bienvenidas.

Respuesta

10

Usted puede hacer esto:

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

Usted podría hacer la primera línea con un comando SELECT INTO . –

1

Su ejemplo debería funcionar casi. Simplemente agregue los nombres de columna de la nueva tabla.


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

Eso sólo copias de datos para las columnas especificadas - mi objetivo es evitar contenga cada una sola columna. Haré la pregunta un poco más clara, gracias. –

+1

¿qué tal crear una función o un proceso almacenado o lo que sea que construya la consulta dinámicamente para usted? Aún – Salamander2007

+0

significa que tiene que especificar los campos, aunque ... –

3

no creo que esto es factible en su totalidad dentro de SQL sin tener que ir a la molestia de crear una tabla temporal. Hacerlo en memoria debería ser mucho más rápido. Tenga cuidado si va por la ruta de tabla temporal que debe elegir un nombre único para su tabla para cada invocación de función para evitar la condición de carrera donde su código se ejecuta dos veces al mismo tiempo y transforma dos filas de datos en una tabla temporal.

No sé qué tipo de lenguaje está usando, pero debería ser posible obtener una lista de campos en su programa. Yo lo haría así:

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

A continuación, se puede encapsular que a medida que una función y llamarla simplemente especificando mesa, viejo y nuevo ID Identificación y se iba a trabajar su magia.

En el código Perl el siguiente fragmento haría:

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

Espero que esto ayude.

2

Ok, intente esto:

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; 

Antes de ejecutar la línea "sp_executesql", por favor "seleccione @qry" para ver cual es el comando que se va a ejecutar.

Y por supuesto, es posible que desee pegar esto en un procedimiento almacenado y pasar una variable en lugar del bit 'Field3'.

Rob

+0

Debo mencionar - esta es una versión 2005+ –

+0

... Sí, puedo hacer algo similar con el catálogo del sistema de DB2 SQL Server. Veré cómo es el rendimiento en comparación con la técnica de copiar y copiar si tengo tiempo. Gracias. –

+0

Y, por supuesto, si sólo desea ciertas líneas, basta con añadir una cláusula WHERE para @qry. –

-1

Nunca había trabajado con DB2 pero en mssql se podría resolver con siguiente procedimiento. esta solución solo funciona si no te importa qué nueva identificación obtienen los artículos.

1.) crear una nueva tabla con el mismo esquema, pero donde la columna de identificación se incrementa automáticamente. (mssql "especificación de identidad = 1, incremento de identidad = 1)

2.) Que un simple

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

debería ser suficiente, asegúrese de no incluir su Colum id en la declaración anterior

Cuestiones relacionadas