I am using tokio postgres in a Rust project where I have query parameters.
rows = client.query(QUERY, &[&input1, &input2.unwrap()]).await.expect("error");
where QUERY looks like this
QUERY: &str = "SELECT * FROM Table WHERE Name=$1 AND Address= COALESCE($2, Address);"
input2 is of type Rust option for which I will have to unwrap input2 before inserting it into the query method. Is there a way to make the query method handle "None" directly.
I can write conditional statements outside but that will make the source code unmanageable for the case where I have multiple optional queries.
You work with raw queries, tokio_postgres couldn't to manage None. In my experience best solution will write your own query builder.
You do not need to .unwrap() at all and can pass &input2 as-is. Option<T> implements ToSql where T: ToSql, if the value is None then it will pass NULL to the database:
let rows = client.query(
"SELECT * FROM Table WHERE Name=$1 AND Address=COALESCE($2, Address)",
&[&input1, &input2],
).await?;
Full working code that I tested on my local database is available here.
Related
Currently I have a PostgreSQL query which calculates expression:
SELECT sum(timestamp2 - timestamp1 [some other math]) from <...> WHERE <...>.
Is there a way to do it with Slick? I tried to fetch raw data (login and logout) from database and process it, but this method is too expensive, so I need to process data on the database side.
This is how you do calculated columns
https://github.com/slick/slick/issues/1314
So in your case it will be
def ts(row: YourTableClass[_]) = row.timestamp2 -- row.timestamp1
Next you can do aggregation like shown in nmat's link
Calling .ToString() to a IQueryable will return the generated SQL query with the values of the variables not plugged in yet. So there are these p__linq__n with n=0, 1, 2... in the query itself.
eg: SELECT * FROM foo WHERE x = p__linq__0
Question: Is it possible to get the final query? with the values of these variables already plugged into the query?
eg: SELECT * FROM foo WHERE x = 6
EF parametrizes queries to avoid Sql injections attacks and to be able to cache and re-use the same query even if some values change. To see parameters you can use the logging feature introduced in EF6. See this blogpost series for more details.
How does Slick handle a query that returns multiple result sets?
For example, if I wanted to retrieve information about a table using sp_help someTableName
Which would return a number of result sets. I can get the first result set, simply using scala.slick.jdbc.StaticQuery.queryNA[Tuple4[String, String, String,String]]("sp_help tblInbox_membership").first()
How do I get the second result set?
You must be using Sybase or maybe SqlServer.
I'm not familiar with Slick (yet), but the way to access subsequent ResultSets from a statement in JDBC is to call Statement.getMoreResults(), then if that succeeds Statement.getResultSet(). Slick gives you a Statement object with Session.withStatement, so you could at least use the JDBC api to get your resultsets, or feed the ResultSet to Slick if there is a way to do that.
I have no idea why any one would do this (include support for Lists in named queries but not native named queries (and believe me when I tell you I am steaming mad about this). How can one get around this flaw? I can't possibly put all the place values for the array into the native query, It could be up to several hundred units long!!!!! How would you handle this?
Can you pass a List as a parameter to a normal SQL statement? No.
/**
* Create an instance of Query for executing a native SQL statement, e.g., for update or delete.
* #param sqlString a native SQL query string
* #return the new query instance
*/
public Query createNativeQuery(String sqlString);
When you create a native query, the JPA provider will blindly pass that SQL to the database and it assumes the user has formatted the SQL appropriately.
If you want to pass a List as a query parameter, use JPQL.
I'm trying to build a strongly-typed dataset in ADO.Net and am having a little trouble with one aspect of the TableAdapters.
My query looks like
SELECT *
FROM testdict.ModuleVariable
WHERE Module = ?
My problem revolves around the testdict part. We use several different schemas to access our data (because of a multiplexed Sybase IQ instance). How can I parameterize the schema portion of this query?
I've tried:
SELECT *
FROM ?.ModuleVariable
WHERE Module = ?
but to no avail. My current mindset is that I may have to inherit the TableAdapter and parameterize the schema manually but I am hoping there is a nicer solution!
Thanks in advance
First of all you won't be able to achieve this in design-time by simply adding a select query. You cannot parametrize the schema.
However there's a solution for this.Here's how you can do that.
1.) Drag and drop the table into your typed-dataset designer which will create a typed-data-table for the table and the table-adapter to access database table. table adapter is aware of the schema of the data-table.
2.) Now create a stored-procedure in your database that takes two arguments. one is the schema of the table [?.ModuleVariable] and other would be your where clause or maybe anytihng you may want as criteria. You can create overloads of this as you wish. This stored-procedure will then construct the sql query based on the arguments and execute it on the database. This will return the result-set to calling table-adapter.
3.) From the design-view Add a method to table-adapter which will fetch results from the stored-procedure. Make sure that the schema of results exactly meets the schema of the associated data-table.
4.) Now from the code you can create an instance of the table adapter and call the method which in turn will call your stored-procedure and return you with the data-table filled in with results.
Have fun!
You can overload or add a new function to the table adapter, because they are defined as partial classes. This new function would have the schema name as a parameter. For example, Fill(table As (tableName), schemaName As String). Here's how I'd do it:
Create a new file and name it (dataSetName).(whatever_you_like).vb.
At the top put Namespace (dataSetName)TableAdapters.
Use an Import statement to easily access the tables in the data set. Imports (solutionName).(dataSetName).
Define the new function. This example function is a bit simplified, but I guess it will be enough for you to get the idea.
Partial Class (tableName)TableAdapter
Public Overloads Function Fill( _
table As (tableName), _
schemaName As String) As Integer
Dim args() As String = {schemaName, table.TableName}
Dim selectCmdText As String = "SELECT * FROM {0}.{1}"
selectCmdText = String.Format(selectCmdText, args)
Connection.Open()
Dim selectCmd As New MySqlCommand(selectCmdText, Connection)
Dim adapter As New MySqlDataAdapter(selectCmd)
Dim returnValue As Integer = 0
returnValue = adapter.Fill(table)
Connection.Close()
Return returnValue
End Function
End Class
Kind regards,
Carlos Mallen