I am going to assume you mean writing a DAL that is accessing SQL, because this is the most common part today. ONe if the biggest problems in writing a DAL against SQL is the ORM part. That is, there is a fundamental impedance mismatch between OO programming and relational database schemas. There have been many great, succesful even, attempts at writing ORMs. But they all suffer from the same problem that is their benefit: they abstract you away from the underlying SQL being generated. Why this is a problem, is that the performance of your database is a critical compponent of how well your system functions overall. Many ORMs (perhaps most) not only have less-than-stellar performance for many standard queries, but actually encourage patterns of usage that will degrade performance considerably (traversing relationships repeatedly within loops when querying collections being one common example, making resolving deadlocks difficult being another). Of course, after learning the ORM API in detail, you can usually find ways around these performance potholes.
My current take on the state of ORMs is that I want it to do as little as possible, while still giving me the efficiencies of a solid library that takes care of all of the nuts and bolts of data access. In other words, because I don't think they are "good enough" yet, and may never be with SQL as the back end, I want to retain control at the bare-metal level, and I will drop down to writing SQL by hand without hesitation in many cases, regardless of the ORM, because I know the specific way I want the data to be queried for my given needs.
This is obviously a more brittle approach to coding than if you religiously use the ORM as it was intended, so as a result, you have to be extra diligent in terms of unit testing, SQL injection, and proper separation of concerns. So, to sum up, I agree with Ash, although that does not imply he/she agrees with me :)