There are a couple myths related to this topic that you should disabuse yourself of:
Myth 1: Stored procedures are pre-compiled
http://scarydba.wordpress.com/2009/09/30/pre-compiled-stored-procedures-fact-or-myth/
Myth 2: Ad Hoc SQL queries do not reuse execution plans:
http://scarydba.wordpress.com/2009/10/05/ad-hoc-queries-dont-reuse-execution-plans-myth-or-fact/
IMHO procs have the edge when you absolutely need to lock down the database. In these situations, you can use an account that only has rights to execute stored procedures. Additionally, they can provide a layer of abstraction between your app and the database from the DBA perspective.
Likewise, dynamic SQL is better in situations where the query may need to change some and be... well... dynamic. Or if you know you have to port to multiple databases.
Both are just as safe in regards to SQL injection as long as all user inputted values are parameterized.