Я думаю, що головна проблема полягає в тому, що не всі бази даних підтримують загальні табличні вирази.
Мій роботодавець використовує 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, на які всі посилалися, потім було основне об'єднання запитів про результати останніх чотирьох.
Це можна зробити за допомогою:
- БД / 2
- PostGreSQL
- Oracle
- MS SQL Server
- MySQL (остання версія; все ще якась нова)
- напевно, інші
Але це триває довгий шлях до того, щоб зробити код чистішим, розбірливішим, більш СУМИМ.
Я розробив "стандартну бібліотеку" CTE, на яку я можу підключатися до різних запитів, що дозволяє мені перейти до мого нового запиту. Деякі з них починають сприймати й інші розробники моєї організації.
З часом може виникнути сенс перетворити деякі з них на види, щоб ця "стандартна бібліотека" була доступна без копіювання / вставки. Але мої CTE в кінцевому підсумку перетворюються настільки незначно для різних потреб, що я не зміг використати жодного CTE так широко, без мод, що, можливо, варто створити перегляд.
Здавалося б, ваша частина захвату - це "чому я не знаю про CTE?" або "чому мій БД не підтримує CTE?"
Що стосується оновлень ... так, ви можете використовувати CTE, але, на мій досвід, ви повинні використовувати їх всередині встановленого пункту AND у пункті where. Було б добре, якби ви могли визначити одну або декілька випереджувачів усієї операції оновлення, а потім просто мати "головний запит" частини в наборі / де застереження, але це не працює таким чином. І не можна уникати незрозумілих імен таблиці / полів у таблиці, яку ви оновлюєте.
Ви можете використовувати CTE для видалення. Може знадобитися кілька CTE, щоб визначити значення PK / FK для записів, які потрібно видалити з цієї таблиці. Знову ж таки, ви не можете уникнути незрозумілих імен таблиці / полів у таблиці, яку ви змінюєте.
Оскільки ви можете зробити вибір для вставки, ви можете використовувати CTE для вставок. Як завжди, ви можете мати справу з неясними іменами таблиці / полів у таблиці, яку ви змінюєте.
SQL НЕ дозволяє створювати еквівалент доменного об'єкта, загортаючи таблицю, за допомогою getters / setters. Для цього вам потрібно буде використовувати якийсь ORM разом із більш процедурною / OO мовою програмування. Я писав речі такого характеру в Java / Hibernate.