2010-11-15 11 views
12

Czy istnieje sposób użycia sprzężeń w instrukcjach aktualizacji dla produktu DB2?ŁĄCZENIE WEWNĘTRZNE w SIECI AKTUALIZACJI dla DB2

Google naprawdę mnie nie zawiódł się na tej jednej

To jest mniej więcej to, co staram się osiągnąć (... oprócz oczywiście działa ....)

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%'        

Cheers

Odpowiedz

6

Dołączenia w instrukcjach update są niestandardowe i nie są obsługiwane przez wszystkich dostawców. Co ty próbujesz zrobić można osiągnąć z 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

W standardzie SQL tego typu aktualizacji wygląda następująco:

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%' 

z niewielkimi zmianami składniowych tego typu rzeczy będą pracować na Oracle lub SQL Server i (chociaż nie mam instancji DB/2 do ręcznego przetestowania) prawie na pewno zadziała na DB/2.

+1

Dzięki ConcernedOfTunbridge - niestety tego nie robi praca w DB2, dostaję błąd mówiąc „kwalifikator kolumny lub tabeli B nieokreślone” – Hamish

+0

jakiegokolwiek innego pomysły? – Hamish

+0

wypróbowałeś || zamiast +, i chcesz wpisać sprzężenie wewnętrzne zamiast "join" - myślę, że funkcja substr powinna mieć wartość "10, 10", a nie "10, 20", patrz http://publib.boulder.ibm.com/infocenter/ db2luw/v8/index.jsp? topic =/com.ibm.db2.udb.doc/admin/r0000854.htm –

0

Dokumentacja referencyjna the UPDATE statement na DB2 LUW 9,7 podaje następujący przykład:

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' 

Nawiasy po aktualizacji mogą zawierać pełny-select, czyli żadnego ważnego oświadczenia SELECT może tam pojechać.

Na tej podstawie, chciałbym zaproponować następujące:

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) 

Edycja: Ian ma rację. Mój pierwszy instynkt polegał na próbie wybrania subselekcji:

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 
) 

Ale nie jestem pewien, czy połączenie będzie działało. Zakłada się także, że istnieje mapowanie 1: 1 między podciągami. Jeśli istnieje wiele wierszy, które pasują, to nie zadziała.

+1

Nie można zaktualizować pełnej selekcji zawierającej połączenie - tak, jak nie można zaktualizować widoku zawierającego połączenie (bez wyzwalacza INSTEAD OF). To oświadczenie zwróci SQL01050N. –

8

Nie mówisz, na jaką platformę chcesz kierować. Odwołując się do tabel jako plików, prowadzi mnie jednak do przekonania, że ​​NIE uruchamiasz DB2 w systemie Linux, UNIX lub Windows (LUW).

Jeśli jednak na DB2 LUW, zobacz oświadczenie MERGE:

Na wyciągu przykład, byłoby to zapisać jako:

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; 

Uwaga: W przypadku produktu DB2, trzeci Argumentem funkcji SUBSTR jest liczba bajtów do zwrócenia, a nie pozycja końcowa. Dlatego SUBSTR (a.firstfield, 10,20) zwraca CHAR (20). Jednak SUBSTR (b.anotherfield, 1,10) zwraca CHAR (10). Nie jestem pewien, czy zrobiono to celowo, ale może to wpłynąć na twoje porównanie.

+0

Interesujący połów na użycie "pliku", który jest powszechnie używany zamiennie z "tabelą" wśród programistów używających systemu IBM i. W tym systemie operacyjnym tabela DB2 jest zewnętrznie opisanym fizycznym plikiem bazy danych. Jednak wykonywalny obiekt programu nie jest plikiem. – WarrenT

3

Miał podobny problem, DB2 nie obsługuje UPDATE przy użyciu podselekcji i miejsca.Skończyło się na użyciu polecenia MERGE;

MERGE statement

Oświadczenie MERGE aktualizuje cel (tabela lub widoku lub tabel bazowych lub poglądów pełnej selekcji) na podstawie danych ze źródła (wynikiem odniesienia tabeli). Wiersze w celu, które pasują do źródła, mogą zostać usunięte lub zaktualizowane zgodnie z określeniem, a wiersze, które nie istnieją w obiekcie docelowym, mogą zostać wstawione. Aktualizowanie, usuwanie lub wstawianie wiersza w widoku aktualizuje, usuwa lub wstawia wiersz w tabelach, na których oparty jest widok.

+0

Ostatnio często używam scalania - dlatego polecam go, jest dość potężny. @Darren: Użyteczny przykład dla tego przypadku byłby pomocny. –

3

Oto dobry przykład czegoś Właśnie pracy:

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

Aktualizacja odpowiedź https://stackoverflow.com/a/4184237/565525:

jeśli chcesz wiele kolumn, które mogą być zdobytych w ten sposób:

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%' 

Źródło: http://www.dbforums.com/db2/1615011-sql-update-using-join-subquery.html#post6257307

+0

@Hogan - dzięki, zaktualizowany. –

5

Spróbuj i powiedz mi wyniki:

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

Nie knwo, jeśli zauważyłeś, ale OP był ostatnio widziany jej 24 stycznia 2011 o 13:03. jest mało prawdopodobne, że on/ona powróci. – Linger

+1

@Linger Prawda, ale odpowiedzi są nadal wyszukiwane przez wyszukiwarki po latach. Jeśli odpowiedź jest ważna, zawsze może być istotna. – user2338816

+0

Mogę potwierdzić, że działa to również w przypadku produktu DB2 for z/OS –

1

Wystarczy tylko zaktualizować wiersze spełniające warunki i unikać aktualizacją wartości null w innych wierszach:

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

Działa w DB2/AIX64 9.7.8

0

dla pytasz

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%' 

jeśli dołączyć g ive wielokrotnego rezultat można wymusić aktualizację jak to

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%' 

szablonu Methode

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