After a few years, the question is still important...
Simple rule-of-thumb for me: if it's a logical constraint or an ubiquitous expression (single statement), place it in the database (yes, foreign keys and check constraints are business logic, too!). If it's procedural, by containing loops and conditional branches (and really can't be changed into an expression), put it in code.
Avoid trash dump DBs
Attempts to place really all business logic in application code will likely degenerate the (relational) database into a trash dump, where relational design is mostly to completely omitted, where data can have any inconsistent state, and normalization is missing (often mainly XML, JSON, CSV etc. trashbin columns).
This kind of application-only logic is probably one of the main reasons for the rise of NoSQL - of course with the downside that the application has to take care of all the logic itself, what has been built into relational DB for decades. However, NoSQL databases are more suitable for this kind of data handling, for example, data documents maintain an implicit "relational integrity" within themselves. For relational DBs, it's simply abuse, causing ever more trouble.
Expressions (set-based) instead of procedural code
In best case, every data query or operation should be coded as an expression, rather than procedural code. A great support for this is when programming languages support expressions, such as LINQ in the .NET world (unfortunately, only queries currently, no manipulation). On the relational DB side, it has been taught for a long time, to prefer SQL statement expressions over procedural cursor loops. So the DB can optimize, do the operation parallel, or whatever may be useful.
Utilize DB data integrity mechanisms
When it comes to RDBMS with Foreign Key and Check constraints, calculated columns, possibly triggers and views, this is the place to store the basic business logic in the database. Proper normalization helps to maintain data integrity, to ensure a unique and distinct instance of the data. Even if you have to duplicate it in code and DB, these basic mechanisms of data integrity should not be omitted!
Stored Procedures are rarely necessary nowadays, since databases keep compiled execution plans for SQL and reuse them when the same query comes again, only with different paramters. So the precompile argument for SPs is no longer valid. One can store or auto-generate SQL queries in the application or ORM, which will find precompiled query plans most of the time. SQL is an expression language, as long as you don't explicitly use procedural elements. So, in best case, you use code expressions which can be translated into SQL.
While application side, including ORM generated, SQL, is no longer inside the database, unlike Stored Procedures, I still count it as database code. Because it still requires SQL and database knowledge (except the most simple CRUD), and, if applied properly, works greatly different than the procedural code usually created with programming languages like C# or Java.