Some thoughts: Please note this is a Java centric response, but its the bulk of my recent (last 10years) experience
(1) Concurrent development by a (a large) team of developers. If you're application is sufficiently complex that each developer can't set up their own private version of the DB (with attended links/ref data/etc...)it is very difficult to have an entire TEAM of developers all working on the same set of PL-SQL (for example) packages at the same time stored in a shared DEVL DB? Then your stuck (my experience) with working in a DB with invalid procedures / mismatch of code to tables as people make changes...
As a Java architect, I think its much easier to have each developer have a private JBoss instance on their desktop and work easily on their own set of functionality, and integrating at their own pace without impacting everyone else ... which brings me to ...
(2) Continuous Integration toolsets
While there exist some similar 'concepts' in the DB world, my experience has shown me that the combo of (i'm picking my current best-of-breed favs here):
- mvn - build system
- junit - automated unit testing
- nexus - repo manager (manages artifact's lifecycles version, snapshots and releases)
- hudson - ci build server
- sonar - static analysis tool / code coverage reports / ALOT
more
Running a large project using all of the above (free tools) allows a consistent / easy way to deliver XP to the masses and enforce quality controls over a whole IT staff.
Oracle / PL-SQL doesn't have the toolsets to match
(3) tools / libraries / etc...
Java has access to an amazing set of services that other platforms cannot touch - some free, some not.
even basic ones, like log4j (yes they have it for PL/SQL, but pulease...its not nearly the same) allows for things like allowing developers to create flexibly adjustable logging that can be changed on the fly (perfect for dubugging). Automated API documentation (via javadoc). Automated unit test coverage reports. Incredible IDEs (Eclipse) with integrated debuggers / autodeploy to app servers. An API to interface with every type of service under the sun, open source libraries to do ANYTHING, and 100% support by every vendor
(4) reuse of services. what someone commented on is true. If you have heavy duty data driven business rules then you can argue that these should live in the DB layer. Why? to prevent having the middle tier(s) all having to duplicate that logic.
But the same can be said for business rules that are not data driven or sufficiently complex that OO is a more natural choice. If you stick ALL business logic in the DB, then they're available only via the DB.
- What if you want to have validation done in the client or middle app tier and save a round trip to the DB?
- What if you want to cache read only data in the middle tier (for performance) and have business rules execute against the cached data?
- What if you have a middle tier service that doesn't require DB access, or you have a client that can supply their own data?
- What if the data dependent portion of the business rules then needs to access external services? Then you end with with fragmented business logic that looks like this:
i
retCode = validateSomeDate(date);
if (retCode == 1) then
evaluateIfCustomerGetsEmail(...)//probably more stored proc invocations here...
sendEmailMsg(....)
else if (retCode == 2) then
performOtherBizLogicStuf(...) //again, may need data, may not need data
triggerExternalsystemToDoSomething(...) //may not be accessible via PL/SQL
fi
I'm sure we've all seen systems written like the one above and had to debug them at 2AM. Its extremely difficult to get a coherent sense of a complex process when the business logic is fragmented between tiers, and in some cases it gets to be impossible to maintain.