question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Dynamic where clauses bind to long parameter

See original GitHub issue

Maybe there is a completely other / better way to do “dynamic where clause” in SqlDelight but if I would like to write a SELECT or DELETE / UPDATE statement like this:

SELECT * FROM Person WHERE ?

or

DELETE FROM Person WHERE ?

with a WHERE clause that is computed at runtime like this:

void getAllWhereName(List<String> personNames) {
   StringBuilder builder = new StringBuilder();
   for (int i = 0 ; i< personNames.size(); i++){
    String personName = personNames.get(i);
    if ( i > 0 )
       builder.append(", ");

    builder.append("name ='")
               .append(personName)
               .append("'");
   }

  String whereClause = builder.toString();
  ...
}

However, the argument to bind the where clause generated by SqlDelight is of type long

 public SqlDelightStatement getAllPersonsWithName(long arg1) {  // <--- long type
      List<String> args = new ArrayList<String>();
      int currentIndex = 1;
      StringBuilder query = new StringBuilder();
      query.append("SELECT * FROM Persons WHERE ");
      query.append(arg1);
      return new SqlDelightStatement(query.toString(), args.toArray(new String[args.size()]), Collections.<String>singleton("Person"));
    }

Same for generated Delete / Update statements. For example

 final class DeletePersons extends SqlDelightCompiledStatement.Delete {
    public DeleteChannels(SQLiteDatabase database) {
      super("Subscription", database.compileStatement(""
              + "DELETE FROM Person WHERE ?"));
    }

    public void bind(long arg1) { // <-- long as parameter type
      program.bindLong(1, arg1);
    }
  }

Is there already a better way to do “dynamic where clauses”?

Otherwise, I think the correct behavior would be to generate code that uses string as default type (not long) if type could not be determined from column.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:3
  • Comments:16 (2 by maintainers)

github_iconTop GitHub Comments

5reactions
dev-lcccommented, Apr 17, 2020
-- Fetch Result in ASCENDING ORDER
fetchAllAscending:
SELECT * FROM Person
WHERE
    CASE WHEN :name IS NOT NULL THEN name LIKE :name ELSE 1 END
    AND CASE WHEN :age IS NOT NULL THEN age = :age ELSE 1 END
ORDER BY CASE
    WHEN :sortField = 'name' THEN name
    WHEN :sortField = 'age' THEN age
    ELSE name END ASC
LIMIT :page, :docsPerPage
;

-- Fetch Result in DESCENDING ORDER
fetchAllDescending:
SELECT * FROM Person
WHERE
    CASE WHEN :name IS NOT NULL THEN name LIKE :name ELSE 1 END
    AND CASE WHEN :age IS NOT NULL THEN age = :age ELSE 1 END
ORDER BY CASE
    WHEN :sortField = 'name' THEN name
    WHEN :sortField = 'age' THEN age
    ELSE name END DESC
LIMIT :page, :docsPerPage
;

You get the idea, WHERE clauses are optional and will ONLY be considered if parameter is NOT NULL.

1reaction
darkycommented, Aug 12, 2022

https://github.com/cashapp/sqldelight/issues/626#issuecomment-1213078500

If define boolean variable directly in when, it works for me!

SELECT CAST(count(id) AS INTEGER)
FROM patient_actions
WHERE action_date < :actionDate AND
    is_archived IN :isArchived AND
    is_from_dm IN :isFromDm AND
    CASE WHEN :languageExists
        THEN language IN :language
        ELSE TRUE
    END;
Read more comments on GitHub >

github_iconTop Results From Across the Web

Dynamic where clauses bind to long parameter · Issue #626
I think that the simplest solution for the "dynamic where clause" problem is to change the default type from long to string for...
Read more >
Use Bind Variables with Dynamic SQL
You can use bind arguments in the WHERE clause, the VALUES clause, or the SET clause of any SQL statement, as long as...
Read more >
Conditional WHERE clauses in SQL - Avoid Smart Logic
Use dynamic SQL if you need dynamic where clauses. Still use bind parameters when generating dynamic SQL—otherwise the “dynamic SQL is slow” myth...
Read more >
JDBI How can I dynamically create a WHERE clause while ...
You can dynamically create the where statement, but leave parameter names instead of values, they will be bound later, in a safe way....
Read more >
When Using Bind Variables is not Enough: Dynamic IN Lists
USING clause does not take dynamically sized bind value lists, so we have to generate that as well, in a nested EXECUTE IMMEDIATE...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found