質問を再提出すると、必然的に1つのテーブルにしか影響しない場合でも、OracleとSQLServerの両方で機能する構文が必要だと思います。
エントリレベルのSQL-92標準コードは両方のプラットフォームでサポートされているため、次の「スカラーサブクエリ」SQL-92コードが機能するはずです。
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
);
相関名t1
を使用している間は注意してください Ttble1
の場合 SQL-92標準に準拠した有効な構文です。これにより、テーブルとUPDATE
が実体化されます。 次に、マテリアライズされたテーブル't1'をターゲットにし、ベーステーブル'table1`に影響を与えないままにします。これは望ましい影響ではないと思います。 OracleとSQLServerの両方がこの点に準拠しておらず、実際には期待どおりに機能すると確信していますが、ターゲットテーブルを完全に修飾することで、非常に慎重にSQL-92構文に固執しても害はありません。
フォークは、上記のサブクエリの「繰り返される」コードを好まない傾向があります(オプティマイザは、一度だけ評価するのに十分賢いはずですが)。
OracleとSQLServerの最新バージョンは、どちらも標準SQL:2003 MERGE
をサポートしています。 構文は、これに近いものを使用できる可能性があります:
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;
あなたの例は私が最初に考えたよりもさらに単純であり、ほとんどのSQL製品で実行する必要がある単純なサブクエリを必要とするだけであることに気づきました。
UPDATE table1
SET my_value = 'foo'
WHERE EXISTS (
SELECT *
FROM table2 AS t2
WHERE t2.tab1_id = table1.id
);