Once you're there, if you're doing SQL directly, now you're manipulating strings in your code, instead of being able to build some kind of object that then generates a query for you.
I use a set of 3-4 functions that I reuse pretty much in all my programs for this. It's no ORM, as it doesn't map classes to tables/data in the database. It's just a shortcut to generate and execute INSERT/UPDATE commands on arbitrary tables with arbitrary columns.
Also it has zero bugs, because you can hardly create bugs in something so simple.
You may have underestimated how bad things are in some of the unicorns..
1. Creating your own query builder before understanding the purpose of bind param: https://medium.com/tokopedia-engineering/dynamic-sql-query-b...
2. ???
3. Profit from SQL injection: https://www.youtube.com/watch?v=PKkNjOweWTE
They make a simple crud operation so easy, you don't even have to think about them.
Every remotely competent developer will however tell you that there are always cases where the orm is a bad fit. And that's exactly why basically all orms let you write your own queries.
There is really no reason not to use an orm. Just don't ever frown on people doing anything more advanced than a middle join without it.