主な問題は、すべてのデータベースが共通テーブル式をサポートしているわけではないことです。
私の雇用主はDB / 2を非常に多くのことに使用しています。最新バージョンではCTEがサポートされているため、次のようなことができます。
with custs as (
select acct# as accountNumber, cfname as firstName, clname as lastName,
from wrdCsts
where -- various criteria
)
, accounts as (
select acct# as accountNumber, crBal as currentBalance
from crzyAcctTbl
)
select firstName, lastName, currentBalance
from custs
inner join accounts on custs.accountNumber = accounts.accountNumber
その結果、テーブル/フィールド名を大幅に短縮することができ、より読みやすい名前の一時ビューを本質的に作成し、それを使用できます。確かに、クエリは長くなります。しかし、その結果、かなり明確に分離されたもの(CTEを使用して関数を使用してDRYを取得する)を記述し、非常に読みやすいコードを作成できます。また、サブクエリを分割して、あるサブクエリが別のサブクエリを参照できるため、すべてが「インライン」ではありません。ときどき、1つのCTEを作成し、それから他の4つのCTEがすべてそれを参照し、最後の4つの結果をメインクエリに結合させました。
これは次の方法で実行できます。
- DB / 2
- PostGreSQL
- オラクル
- MS SQLサーバー
- MySQL(最新バージョン、まだ少し新しい)
- おそらく他の人
しかし、コードをよりクリーンで読みやすく、よりドライにするための長い道のりを歩んでいます。
私は、さまざまなクエリにプラグインできるCTEの「標準ライブラリ」を開発しました。これにより、新しいクエリをすぐに始めることができます。それらのいくつかは、私の組織内の他の開発者にも受け入れられ始めています。
そのうち、これらの一部をビューに変換して、この「標準ライブラリ」をコピー/貼り付けする必要なく使用できるようにすることは理にかなっています。しかし、私のCTEは、1つのCTEをmodなしで非常に広く使用することができなかったため、ビューを作成する価値があるかもしれないさまざまなニーズのために、微調整されています。
あなたの不満の一部は「なぜ私がCTEについて知らないのか」と思われるでしょう。または「DBがCTEをサポートしないのはなぜですか?」
更新については...そうです、CTEを使用できますが、私の経験では、set句内およびwhere句内で使用する必要があります。updateステートメント全体の前に1つ以上を定義し、set / where句に「メインクエリ」の部分を含めることができれば便利ですが、それは機能しません。また、更新しているテーブルのあいまいなテーブル/フィールド名を避けることはできません。
削除にCTEを使用できます。そのテーブルから削除するレコードのPK / FK値を決定するには、複数のCTEが必要になる場合があります。繰り返しますが、変更するテーブルのテーブル/フィールド名が不明瞭になることは避けられません。
挿入に対して選択を行うことができるので、挿入にCTEを使用できます。いつものように、変更しているテーブルのあいまいなテーブル/フィールド名を扱っているかもしれません。
SQLでは、getter / setterを使用して、テーブルをラップするドメインオブジェクトに相当するものを作成できません。そのためには、何らかの手続き型のORMと、より手続き的な/ OOプログラミング言語を使用する必要があります。この性質のものをJava / Hibernateで記述しました。