Zakładam, że kiedy ponownie podasz pytanie, chcesz składni, która będzie działać zarówno na Oracle, jak i na SQL Server, nawet jeśli nieuchronnie wpłynie tylko na jedną tabelę.
Standardowy kod SQL-92 na poziomie podstawowym jest obsługiwany przez obie platformy, dlatego następujące „podzapytania skalarne” powinny działać:
UPDATE table1
SET my_value = (
SELECT t2.tab1_id
FROM table2 AS t2
WHERE t2.tab1_id = table1.id
)
WHERE id = 1234
AND EXISTS (
SELECT *
FROM table2 AS t2
WHERE t2.tab1_id = table1.id
);
Zauważ, że podczas używania nazwy korelacji t1
dla Ttble1
jest poprawną składnią zgodną ze standardem SQL-92, spowoduje to zmaterializowanie tabeli i UPDATE
następnie celuje w zmaterializowaną tabelę „t1” i pozostawi nienaruszoną tabelę podstawową „table1”, co, jak zakładam, nie jest pożądanym efektem. Chociaż jestem prawie pewien, że zarówno Oracle, jak i SQL Server są niezgodne pod tym względem i że w praktyce działałoby zgodnie z oczekiwaniami, nie ma nic złego w zachowaniu szczególnej ostrożności i trzymaniu się składni SQL-92 poprzez pełne zakwalifikowanie tabeli docelowej.
Ludzie zwykle nie lubią „powtarzanego” kodu w powyższych podzapytaniach (nawet jeśli optymalizator powinien być wystarczająco inteligentny, aby ocenić go tylko raz).
Nowsze wersje Oracle i SQL Server obsługują standard SQL:2003 MERGE
składnia, może być w stanie użyć czegoś zbliżonego do tego:
MERGE INTO table1
USING (
SELECT t2.tab1_id
FROM table2 AS t2
) AS source
ON id = source.tab1_id
AND id = 1234
WHEN MATCHED THEN
UPDATE
SET my_value = source.tab1_id;
Właśnie zauważyłem, że twój przykład jest jeszcze prostszy niż początkowo sądziłem i wymaga jedynie prostego podzapytania, które powinno działać w większości produktów SQL, np.
UPDATE table1
SET my_value = 'foo'
WHERE EXISTS (
SELECT *
FROM table2 AS t2
WHERE t2.tab1_id = table1.id
);