2010-11-15 118 views
12

¿Hay alguna manera de usar combinaciones en las instrucciones de actualización para DB2?INNER JOIN en UPDATE sql para DB2

Google realmente me ha defraudado en este caso

Esto es más o menos lo que yo estoy tratando de lograr (... excepto, obviamente, trabajando ....)

update file1 inner join file2         
     on substr(file1.firstfield,10,20) = substr(file2.anotherfield,1,10)                  
set file1.firstfield = ('BIT OF TEXT' concat file2.something)                    
where file1.firstfield like 'BLAH%'        

Saludos

Respuesta

6

Las uniones en update las declaraciones no son estándar y no son compatibles con todos los proveedores. Lo que estamos tratando de hacer se puede lograr con un sub-select:

update 
    file1 
set 
    firstfield = (select 'stuff' concat something from file2 where substr(file1.field1, 10, 20) = substr(file2.xxx,1,10)) 
where 
    file1.foo like 'BLAH%' 
-1

En SQL estándar de este tipo de actualización se parece a:

update a 
    set a.firstfield ='BIT OF TEXT' + b.something 
    from file1 a 
    join file2 b 
    on substr(a.firstfield,10,20) = 
     substr(b.anotherfield,1,10) 
where a.firstfield like 'BLAH%' 

Con variaciones sintácticas menores este tipo de cosas va a trabajar en Oracle o SQL Server y (aunque no tengo una instancia de DB/2 a mano para probar) casi seguramente funcionará en DB/2.

+1

Gracias ConcernedOfTunbridge - lamentablemente esto no funciona en DB2, me sale un error que dice "calificador de columna o de la tabla B indefinido" – Hamish

+0

Cualquier otro ideas? – Hamish

+0

has intentado || en lugar de +, y desea escribir inner join en lugar de 'join' - creo que la función substr debe ser '10, 10 'no '10, 20' ver http://publib.boulder.ibm.com/infocenter/ db2luw/v8/index.jsp? topic =/com.ibm.db2.udb.doc/admin/r0000854.htm –

0

La documentación de referencia para the UPDATE statement en DB2 LUW 9.7 da el siguiente ejemplo:

UPDATE (SELECT EMPNO, SALARY, COMM, 
    AVG(SALARY) OVER (PARTITION BY WORKDEPT), 
    AVG(COMM) OVER (PARTITION BY WORKDEPT) 
    FROM EMPLOYEE E) AS E(EMPNO, SALARY, COMM, AVGSAL, AVGCOMM) 
    SET (SALARY, COMM) = (AVGSAL, AVGCOMM) 
    WHERE EMPNO = '000120' 

Los paréntesis después de la actualización pueden contener una selección completa, es decir, cualquier instrucción SELECT válida puede ir allí.

Sobre la base de que, sugeriría lo siguiente:

UPDATE (
    SELECT 
    f1.firstfield, 
    f2.anotherfield, 
    f2.something 
    FROM file1 f1 
    WHERE f1.firstfield like 'BLAH%' 
    INNER JOIN file2 f2 
    ON substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10) 
) 
AS my_files(firstfield, anotherfield, something) 
SET 
    firstfield = ('BIT OF TEXT' || something) 

Edición: Ian es correcto. Mi primer instinto fue probar subselects en su lugar:

UPDATE file1 f1 
SET f1.firstfield = ('BIT OF TEXT' || (
    SELECT f2.something 
    FROM file2 f2 
    WHERE substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10) 
)) 
WHERE f1.firstfield LIKE 'BLAH%' 
AND substr(f1.firstfield,10,20) IN (
    SELECT substr(f2.anotherfield,1,10) 
    FROM file2 f2 
) 

Pero no estoy seguro de si la concatenación funcionaría. También supone que hay una correspondencia 1: 1 entre las subcadenas. Si hay varias filas que coinciden, no funcionaría.

+1

No puede actualizar una selección completa que contiene una combinación, al igual que no puede actualizar una vista que contiene una combinación (sin un activador EN LUGAR DE). Esta declaración devolverá SQL01050N. –

8

No dices a qué plataforma estás apuntando. Sin embargo, hacer referencia a las tablas como archivos me lleva a pensar que NO está ejecutando DB2 en Linux, UNIX o Windows (LUW).

Sin embargo, si está en DB2 LUW, ver la MERGE declaración:

Por su estado de ejemplo, esto puede escribir como:

merge into file1 a 
    using (select anotherfield, something from file2) b 
    on substr(a.firstfield,10,20) = substr(b.anotherfield,1,10) 
when matched and a.firstfield like 'BLAH%' 
    then update set a.firstfield = 'BIT OF TEXT' || b.something; 

Tenga en cuenta: Para DB2, el tercer El argumento de la función SUBSTR es el número de bytes a devolver, no la posición final. Por lo tanto, SUBSTR (a.firstfield, 10,20) devuelve CHAR (20). Sin embargo, SUBSTR (b.anotherfield, 1,10) devuelve CHAR (10). No estoy seguro de si esto se hizo a propósito, pero puede afectar su comparación.

+0

Atracción interesante sobre el uso de "archivo", que se usa comúnmente de forma intercambiable con "tabla" entre los desarrolladores que usan IBM i. En este sistema operativo, una tabla de DB2 es un archivo de base de datos física descrito externamente. Sin embargo, un objeto de programa ejecutable no es un archivo. – WarrenT

3

Tenía un problema similar, DB2 no es compatible con la ACTUALIZACIÓN utilizando la selección secundaria y dónde.Terminé usando el comando MERGE;

MERGE statement

La declaración de mezcla actualiza un destino (tabla o vista, o las tablas subyacentes o puntos de vista de una selección completa) utilizando datos de una fuente (resultado de una referencia de tabla). Las filas en el destino que coincidan con la fuente se pueden eliminar o actualizar según lo especificado, y las filas que no existen en el destino se pueden insertar. La actualización, eliminación o inserción de una fila en una vista actualiza, elimina o inserta la fila en las tablas en las que se basa la vista.

+0

Últimamente utilizo fusionar mucho, así lo recomiendo, es bastante poderoso. @Darren: Un ejemplo de trabajo para este caso sería útil. –

3

Aquí es un buen ejemplo de algo que acaban de trabajo:

update cac c 
set ga_meth_id = (
    select cim.ga_meth_id 
    from cci ci, ccim cim 
    where ci.cus_id_key_n = cim.cus_id_key_n 
    and ci.cus_set_c = cim.cus_set_c 
    and ci.cus_set_c = c.cus_set_c 
    and ci.cps_key_n = c.cps_key_n 
) 
where exists (
    select 1 
    from cci ci2, ccim cim2 
    where ci2.cus_id_key_n = cim2.cus_id_key_n 
    and ci2.cus_set_c = cim2.cus_set_c 
    and ci2.cus_set_c = c.cus_set_c 
    and ci2.cps_key_n = c.cps_key_n 
) 
2

actualización a la respuesta https://stackoverflow.com/a/4184237/565525:

si quieres varias columnas, que pueden ser Achived como esto:

update file1 
set 
    (firstfield, secondfield) = (
     select 'stuff' concat 'something from file2', 
       'some secondfield value' 
     from file2 
     where substr(file1.field1, 10, 20) = substr(file2.xxx,1,10)) 
where 
    file1.foo like 'BLAH%' 

Fuente: http://www.dbforums.com/db2/1615011-sql-update-using-join-subquery.html#post6257307

+0

@Hogan - gracias, actualizado. –

5

Prueba esto y luego me dicen los resultados:

UPDATE File1 AS B       
SET b.campo1 = (SELECT DISTINCT A.campo1 
        FROM File2 A   
        INNER JOIN File1  
        ON A.campo2 = File1.campo2 
        AND A.campo2 = B.campo2) 
+1

No sé si lo notaron, pero el OP fue visto por última vez el 24 de enero de 2011 a las 13:03. es poco probable que él/ella regrese. – Linger

+1

@Linger Verdadero, pero los buscadores todavía encuentran las respuestas años después. Si una respuesta es válida, siempre puede ser relevante. – user2338816

+0

Puedo confirmar que esto también funciona en DB2 para z/OS –

1

Sólo para actualizar sólo las filas que coinciden con las condiciones, y evitar la actualización de los valores nulos en las otras filas:

update table_one set field_1 = 'ACTIVE' where exists 
(select 1 from table_two where table_one.customer = table_two.customer); 

Funciona de DB2/AIX64 9.7.8

0

pues le piden

update file1 f1 
set file1.firstfield= 
(
select 'BIT OF TEXT' || f2.something 
from file2 f2 
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10) 
) 
where exists 
(
select * from file2 f2 
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10) 
) 
and f1.firstfield like 'BLAH%' 

si unirse g ive resultado múltiple puede forzar la actualización como esto

update file1 f1 
set file1.firstfield= 
(
select 'BIT OF TEXT' || f2.something 
from file2 f2 
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10) 
fetch first rows only 
) 
where exists 
(
select * from file2 f2 
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10) 
) 
and f1.firstfield like 'BLAH%' 

plantilla méthode

update table1 f1 
set (f1.field1, f1.field2, f1.field3, f1.field4)= 
(
select f2.field1, f2.field2, f2.field3, 'CONSTVALUE' 
from table2 f2 
where (f1.key1, f1.key2)=(f2.key1, f2.key2) 
) 
where exists 
(
select * from table2 f2 
where (f1.key1, f1.key2)=(f2.key1, f2.key2) 
)