我认为主要问题是,并非所有数据库都支持通用表表达式。
我的雇主在很多方面都使用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的方式一样),并且最终得到了清晰易懂的代码。而且因为我能够分解自己的子查询,并让一个子查询引用另一个子查询,所以它并不都是“内联的”。有时,我编写了一个CTE,然后又有四个其他CTE都引用了它,然后让主查询合并了最后四个的结果。
这可以通过以下方式完成:
- DB / 2
- PostGreSQL
- 甲骨文
- MS SQL服务器
- MySQL(最新版本;还是新版本)
- 可能是其他人
但是,这将使代码更清晰,更清晰,更干燥。
我已经开发了CTE的“标准库”,可以将其插入各种查询中,从而使我可以快速开始新查询。我组织中的其他开发人员也开始接受其中的一些。
随着时间的流逝,将其中一些转换为视图可能是有意义的,因此无需复制/粘贴即可使用此“标准库”。但是我的CTE最终因各种需求而进行了微调,以至于我无法在没有Mod的情况下如此广泛地使用单个CTE,因此可能值得创建视图。
您似乎不高兴的部分是“我为什么不了解CTE?” 或“为什么我的数据库不支持CTE?”
至于更新...是的,您可以使用CTE,但以我的经验,您必须在set子句和where子句中使用它们。如果您可以在整个update语句之前定义一个或多个,然后在set / where子句中仅包含“ main query”部分,那将是很好的选择,但是这样做不起作用。而且,无法避免要更新的表上的表/字段名称晦涩难懂。
您可以使用CTE进行删除。可能需要多个CTE才能确定要从该表中删除的记录的PK / FK值。同样,您无法避免要修改的表上的表/字段名晦涩难懂。
由于可以对插入进行选择,因此可以使用CTE插入。与往常一样,您可能正在处理要修改的表上晦涩的表/字段名称。
SQL不允许您使用getters / setters创建与包装表的域对象等效的方法。为此,您将需要使用某种ORM,以及更具过程性的/ OO编程语言。我已经用Java / Hibernate编写了这种性质的东西。