# What exactly does "?" do in MYSQL queries?

**URL:** <https://forum.crystal-lang.org/t/what-exactly-does-do-in-mysql-queries/1344>\
**Category:** Help & Support\
**Created:** [November 10, 2019, 1:04am UTC](https://forum.crystal-lang.org/t/what-exactly-does-do-in-mysql-queries/1344 "2019-11-10T01:04:43Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![girng\_github](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/girng_github/32/571_2.png) [@girng\_github](https://forum.crystal-lang.org/u/girng_github)\
**Post date:** [November 10, 2019, 1:04am UTC](https://forum.crystal-lang.org/t/what-exactly-does-do-in-mysql-queries/1344/1 "2019-11-10T01:04:43Z")

</div>

```auto
db.exec "update rpg_user_items set in_stash = ?", tabid

```

I am curious how the question mark (`?`) cleans the user input. I’ve been trying to find the source of its magic in [https://github.com/crystal-lang/crystal-mysql](https://github.com/crystal-lang/crystal-mysql), but with no luck.

- What kind of Crystal methods does it utilize to clean (escape single quotes, etc) the user input?
- Is it similar to PHP’s mysqli::real\_escape\_string?

The reason I ask is because I created a Hash to query update method, and ran into some problems where single quotes were not being escaped (possible sql injection). However, when I switched to using `?`, it fixed it.

---

<div class="post-metadata">

**Author:** ![bcardiff](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bcardiff/32/3_2.png) [@bcardiff](https://forum.crystal-lang.org/u/bcardiff)\
**Post date:** [November 10, 2019, 2:11am UTC](https://forum.crystal-lang.org/t/what-exactly-does-do-in-mysql-queries/1344/2 "2019-11-10T02:11:43Z")

</div>

There is no escaping. The command and arguments are sent separately in the protocol. That is the mechanism that help you avoid sql injections and deal with manual escaping.

So `?` Or `$1` in pg are handled directly in the protocol itself.

---

<div class="post-metadata">

**Author:** ![girng\_github](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/girng_github/32/571_2.png) [@girng\_github](https://forum.crystal-lang.org/u/girng_github)\
**Post date:** [November 10, 2019, 2:21am UTC](https://forum.crystal-lang.org/t/what-exactly-does-do-in-mysql-queries/1344/3 "2019-11-10T02:21:59Z")

</div>

Ohhhh!! So MYSQL handles the sql injection protection internally if `?` is used? If `?` is **not used** , it must be escaped manually?

I am so used to `mysqli_real_escape_string` / manually escaping input, this `?` is all new to me!!

---

<div class="post-metadata">

**Author:** ![bcardiff](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/bcardiff/32/3_2.png) [@bcardiff](https://forum.crystal-lang.org/u/bcardiff)\
**Post date:** [November 10, 2019, 2:46am UTC](https://forum.crystal-lang.org/t/what-exactly-does-do-in-mysql-queries/1344/4 "2019-11-10T02:46:39Z")

</div>

All drivers support commands and arguments. I suggest to use them. You should definitely have less problems.

---

<div class="post-metadata">

**Author:** ![girng\_github](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/girng_github/32/571_2.png) [@girng\_github](https://forum.crystal-lang.org/u/girng_github)\
**Post date:** [November 10, 2019, 2:59am UTC](https://forum.crystal-lang.org/t/what-exactly-does-do-in-mysql-queries/1344/5 "2019-11-10T02:59:15Z")

</div>

Yeah I use `?` a lot, I just didn’t know what they were doing internally. It makes sense now though, thank you

---

<div class="post-metadata">

**Author:** ![pynixwang](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/pynixwang/32/310_2.png) [@pynixwang](https://forum.crystal-lang.org/u/pynixwang)\
**Post date:** [November 12, 2019, 5:17am UTC](https://forum.crystal-lang.org/t/what-exactly-does-do-in-mysql-queries/1344/6 "2019-11-12T05:17:01Z")

</div>

with `?`  
select \* from user where id = ?  
id= `'1 or 1=1'`

`'1 or 1=1'` always will be a part, and sql structure will never be changed.

if you do not use `?`

it will add a `or` condition and will always be true.

---

<div class="post-metadata">

**Author:** ![andraantariksa](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/andraantariksa/32/629_2.png) [@andraantariksa](https://forum.crystal-lang.org/u/andraantariksa)\
**Post date:** [November 15, 2019, 11:02am UTC](https://forum.crystal-lang.org/t/what-exactly-does-do-in-mysql-queries/1344/7 "2019-11-15T11:02:51Z")

</div>

Found this interesting answer

> A parameterized query doesn’t actually do string replacement. If you use string substitution, then the SQL engine actually sees a query that looks like
> 
> ```auto
> SELECT * FROM mytable WHERE user='wayne'
> 
> ```
> 
> If you use a `?` parameter, then the SQL engine sees a query that looks like
> 
> ```auto
> SELECT * FROM mytable WHERE user=<some value>
> 
> ```
> 
> Which means that before it even sees the string “wayne”, it can fully parse the query and understand, generally, what the query does. It sticks “wayne” into its own representation of the query, not the SQL string that describes the query. Thus, SQL injection is impossible, since we’ve already passed the SQL stage of the process.
> 
> (The above is generalized, but it more or less conveys the idea.)

> <https://stackoverflow.com/questions/1263125/how-does-sql-query-parameterisation-work>

You can take a look for another example in another language: [SQL Bind Variables/Parameters in Databases](https://use-the-index-luke.com/sql/where-clause/bind-parameters)

Also, you might want to take a look crystal-lang/crystal-db in GitHub (I can’t post the link) since it’s the base for most of Crystal database library
