-
Notifications
You must be signed in to change notification settings - Fork 344
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
[requesting assistance] Can the same parameter be used in multiple places in the same prepared statement? #571
Comments
Admittedly, I was not aware that your query is legal SQL and I am a bit confused by the update. That said, there is support for sub-queries. Here is an example from test code:
In Hope this helps? Cheers, |
Thanks for the quick reply, I really appreciate it. Unfortunately it is not a sub-query I am after - and even a sub-query would not solve the problem. So let me illustrate the issue with concrete code.
Now the above code will not compile. It will not compile because the Just to reflect on the sub-query suggestion as well - I tried it. I made first a select query including my Right now my working solution is using 4 parameters for the same actual argument:
Note: I am not using the same expression in the where clause because I do not think that SQLite is clever enough to figure out that it should use the indexes on the name fields if they are used within this cascaded case-when structure. So is there a way to make this work somehow with only one parameter instead of needing 4? Related question;: is there a way to access parameters in a sub-query? Cheers, |
Thanks for the detailed explanation. If that query is working for you, I think you could reduce the number of parameters:
If both ideas work for you, then you're down to using the parameter once. WDYT? Roland |
What a great idea using this "reversed" This reduces the number of parameters required by one. However, 'matchCalc_exp' does have different values based on whether the match is on the 'name' or the 'schematicName' field. (Yes, together with the where clause it will never get the value of the embedded From your response (or rather, from what you did not respond to) I suspect that Am I correct? Marcell |
Ah, right, the As for your "suspicions" from my missing answers (sorry for that), yeah, that is correct. You question "B" triggered another idea, though. How about something like this:
This would require a small change in the library:
If this works for you, I would make a change to the library allowing
I guess that change will be as short, but I need to think about how to do this :-) WDYT? Cheers, |
Hi Roland, Do I understand correctly that what your suggestion does is that it basically converts a parameter to a table having one single field with one single row which then is practically concatenated with all rows of the original table? If yes, then absolutely, this could really work as long as the resulting query does not add lots of overhead to the query (it probably does not). Again, if I understand this correctly, at the heart of this solution is the newly added possibility to alias a parameter. But if that is becoming possible, why cannot we use an alias in the query directly? In general it is a bit limiting that while aliases can be defined and translate into a nice SQL statement, they cannot be referenced afterwards anywhere else in the query, only as a result field. If this could be allowed that would really make a good solution because that way all parameters then could be treated as fields of the queried table. (I just hope that this is not insanely complex or impossible to implement. :)) Cheers, |
Hi Marcell, As for the first part: Yes, that is my proposal. I will make no predictions regarding performance. You need to test this yourself :-) As for the second part, the answer is simple: Sub-queries are implemented. Repeated use of a parameter or referencing an alias in the way you want is not. I have not thought about this in detail, but I suspect this will be non-trivial (for instance, the serialization of the aliased expression needs to be different depending on the context, SELECT vs. WHERE). I am also not sure if all database backends support those features. That said, both features are certainly interesting to consider. Best, |
Hi Roland, Yes, even if it is a bit of a workaround (for my particular problem), it is probably worth implementing this change to Please excuse my ignorant question, but when serializing the parameter, isn't it only a parameter name that is required to be serialized? When I think about a query like And another question that is potentially related to the above discussion. I am trying to use a parameter (which might also contain an sqlpp::null) in the In SQLite at least it is possible to use the
Of course I realize now that in the long version I am proposing above there is again the problem of parameter duplication so the change to Thanks, Update
The problem seems to be what I mentioned in my first post, that the parameter in |
I made an attempt to hack my way through with
This compiles beautifully and produces a nice prepared statement, the only problem being is that it introduces two placeholders - I added a commented out part that does work with SQLite, but I guess sqlpp11 being a generic tool this will not fly with every database, In any case I am sharing this as it might give you some idea that could lead to a functional generic solution. Actually I really hope so. :) Cheers, |
To express this query, you would say
In order to reproduce your query you would have to serialize
That does not work since paramname is a class representing a name, The expression Regarding All that said: It seems to me that this thread is covering a lot of questions and requests. I am certainly losing track. I suggest to close this one and I would ask to open a new thread for a new topic, if needed beyond the answers above. Just to summarize the answer for the orginal question: No, you cannot use the same parameter in multiple places in the same prepared statement. |
Hi Roland, Thank you for your help and insights. As a last post in this thread let me share an improved version of
I realize that adding Cheers, |
Thanks for sharing! I might get back to you on that. Agreed that support for optional will not solve the issue with two parameters. But I expect the code to be more concise, making it easier to think about options. I'll leave this open for now while I am moving forward with the optional branch. |
Just for completeness:
I'll add this to the |
In an SQLite database I am using a prepared statement to look up a record in a table storing component data. Each component has two names, a
schematicName
and aname
(which can be null), When I search the table I need to find records that match thename
orschematicName
. So far this could be easily done with something like this:But I also need to know what the match was made on, the
name
or theschematicName
. To this I would ideally use a calculated column with an alias, e.g.:In an ideal world I could use this alias
matchQualifier
in the where clause instead of doing the equality checks again. If it worked, it could translate into the following SQL:But I just could not find any way to make this work.
searchName
instead of needing to assign the same string value to bothmyQuery.params.name
andmyQuery.params.schematicName
, but this results in duplication as well, so does not compile.matchQualifier != 3
but could not make it work. All it gave me was a static_assert: Invalid operand(s)SELECT * FROM (SELECT *, CASE WHEN ... AS matchQualifier) WHERE ...) WHERE matchQualifier != 3
) which is not too healthy.Update
I found how I can use the expression in the WHERE clause. Removing the
.as(matchQualifier)
part does the trick. Then the expression can be directly compared with another sqlpp value, e.g.:.where(matchCalc_exp != sqlpp::value(3))
.However, I now realize that my initial query design is less than optimal, To be able to utilize indexes on the name fields I have to have the names in the where clause. In this case if I wanted to have my calculated
matchQualifier
field I would need to use the same expression there, but it would then require me to use different parameter aliases.So all my above questions really boil down to:
Can the same parameter be used in multiple places in the same prepared statement?
The text was updated successfully, but these errors were encountered: