Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] Support named bind parameters #199

Open
mehcode opened this issue Mar 30, 2020 · 7 comments
Open

[Proposal] Support named bind parameters #199

mehcode opened this issue Mar 30, 2020 · 7 comments
Labels
db:mysql Related to MySQL db:sqlite Related to SQLite proposal

Comments

@mehcode
Copy link
Member

mehcode commented Mar 30, 2020

struct Query {
  fn bind_as<T>(name: &'static str, value: T) -> Self;
}
query!("SELECT ?name", name = 320);
@mehcode mehcode added db:mysql Related to MySQL db:sqlite Related to SQLite proposal labels Mar 30, 2020
@abonander
Copy link
Collaborator

With call-site hygiene stabilized in 1.45, the explicit binding could actually be omitted:

let name = 320;
query!("select ?name");

@jplatte
Copy link
Contributor

jplatte commented Aug 21, 2021

Should this be closed in favor of #875? That one has a bunch more comments.

@abonander
Copy link
Collaborator

abonander commented Aug 30, 2021

This is a related issue of supporting named parameters in general. Implementing #875 would close both issues.

@CMeldgaard
Copy link

Is there any update on named bindings?

@CommanderStorm
Copy link
Contributor

Not really, otherwise this issue would be closed, or that progress would be linked to this issue.
You can however help make this happen.. In rust, most people are volunteers ^^
The contribution guide is here: https://github.com/launchbadge/sqlx/blob/main/CONTRIBUTING.md

In case your company needs this, you could also consider sponsoring @abonander (I don't speak for launchbadge or Austin => have no inside intel if that is an option, but that should likely be taken offline anyway..)

@Flamenco
Copy link

Flamenco commented Oct 5, 2024

I have come up with a solution to this issue. I wrote a procedural macro to wrap the sqlx command, the SQL string, and the parameters.

        let aString = "hello";
        let aNumber = 12;
        let aBoolean = true;

        let res = bind_by_name!(
            sqlx::query
            "select :aString as aString, :aNumber as aNumber, :aBoolean as aBoolean"
            [aString aNumber aBoolean]
        ).fetch_one(&db.pool).await?

This expands to:

sqlx::query("select ? as aString, ? as aNumber, ? as aBoolean")
  .bind(aString).bind(aNumber).bind(aBoolean)
  .fetch_one(&db.pool).await?

You can also map values directly:

        let res = bind_by_name!(
            sqlx::query
            "select :aString as aString, :aNumber as aNumber, :aBoolean as aBoolean"
            [aString:"hello" aNumber:12 aBoolean:true]
        ).fetch_one(&db.pool).await?

Whitespace and brackets are flexable

        let res = bind_by_name!(
            sqlx::query "select :aString as foo" {aString:"hello"}
       ).fetch_one(&db.pool).await?

This will work on any sqlx command that accepts a string and has a bind function.

There is also a postgres version that uses a$ prefix and has numbered placeholders.

        let res = bind_by_name_pg!(
            sqlx::query
            "select $aString as aString, $aNumber as aNumber, $aBoolean as aBoolean"
            [aString:"hello" aNumber:12 aBoolean:true]
        )

That expands to:

sqlx::query("select $1 as aString, $2 as aNumber, $3 as aBoolean")
  .bind("hello").bind(12).bind(true)

The macro shows edit-time errors if you use a parameter name in your SQL that is not in the map.

Screenshot 2024-10-04 at 10 40 01 PM Screenshot 2024-10-04 at 10 40 08 PM

As you can see, I am not a big fan of "noisy" syntax. 😎

I will post this crate after some feedback and if there is interest.

Working Screenshots

Screenshot 2024-10-04 at 10 50 43 PM Screenshot 2024-10-04 at 10 50 48 PM

@CMeldgaard
Copy link

@Flamenco, i would love to see this as a crate :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
db:mysql Related to MySQL db:sqlite Related to SQLite proposal
Projects
None yet
Development

No branches or pull requests

6 participants