Note: This is posted as an answer to a StackOverflow question. Keeping it here for my own convenience.
I wanted a safer, more robust solution that didn't involve fully tokenizing query. Based on my experience writing SQL parsers (here, and here), I can say this solution is pretty bulletproof without having to use a full-featured query parser.
This is the best answer because:
- It does not require a new SQL user with limited permissions
- It does not require a new DB connection with limited permissions
- It does not break if the query contains a string or a comment with the word "delete"
- It allows complex queries with nested queries