DbContext.Database.SqlQuery<T>(query, parameters) parameter with value 0 sent as "default" to the database - entity-framework

I have a code like this:
const string query = "select count(*) from query with parameters"
+ "#param1, #param2..."
(Obvioulsy is pseudocode). When I run the query like this:
ctx.Database.SqlQuery<int>(query,
new SqlParameter("param1", idAsociacion),
new SqlParameter("param2", 0));
I get an exception stating that I didn't provide a value for param2.
If I use SQl Server Profiles I see that the generated query looks like this:
exec sp_executesql N'The query', #param1=N'P', #param2=default
If I try to run it directly in SQL Server I do also get the error that param2 is required and not provided (I don't know the exact error in English, because I have a localized SQL Server).
Why is EF converting the value 0 into default?

The problem was a silly one.
When I put the mouse pointer over this constructor invocation in VS:
new SqlParameter("param2", 0)
I see that the SqlParameter overload being invoked is not this one:
SqlParameter(string, object)
but this one
SqlParameter(string, SqlDbType)
So, the simple solution is to invoke the constructor casting the value to object, like this:
new SqlParameter("param2", (object)0)
so the correct overload is invoked, and it works as expected.

Related

How do you pass variables into Mirth Database Reader Channels for SQL expressions?

I can't find any documentation on how to manager parameters into Database Reader SQL statements?
-> this is a simplified example: I am not looking for scripting a variable to "yesterday" which is easy to express in SQL. That's not the point. I have have more complex variables in the actual SQL statement I'm trying to martial in. I just want to know how to get variables into the SQL form if possible.
-> "you can just do that in JavaScript": the actual queries I need to run are about a hundred lines long, I don't want to maintain and debug a query build by concatenating strings and then deal with escaping 'quoted' things everywhere in the SQL. I really prefer to maintain an actual SQL statement that copy/paste works in a SQL IDE.
How do we pass in parameters into the SQL block at the bottom of the Database Reader form?
SELECT patientsex, visitnumber, samplereceived_dt, sr_d, sr_t, orderpriority, orderrequestcode, orderrequestname
FROM mydata.somedata
WHERE sr_d = (${DateUtil.getCurrentDate('yyyyMMdd')})::integer;
JavaScript is the feasible way to achieve this, with SQL statements defined inside Mirth connect or have the SQL statements bundled in a stored procedure then use SQL server's Exec command within Mirth connect to call the stored procedure while passing the parameters (interestingly using JavaScript).
For example
var dbConn;
try {
dbConn = DatabaseConnectionFactory.createDatabaseConnection('','DB:Port\instance','user','pass');
var paramList = new java.util.ArrayList();
paramList.add($('patientId'));
paramList.add($('lastName'));
paramList.add($('firstName'));
var result = dbConn.executeCachedQuery("SELECT * FROM patients WHERE patientid = ? AND lastname = ? AND firstname = ?) ",paramList);
while (result.next()) {
//you can reference by column index like so...
//result.getString(1);
}
} finally {
if (dbConn) {
dbConn.close();
}
}
Should be noted that the parameters you add to the list MUST be in order.

Cannot use parametrization on "set variable = ?" statement but hardcoding works

I want to change the parameter statement_timeout after establishing a JDBC connection. Therefore I have the following code:
PreparedStatement statement = _connection.prepareStatement("set statement_timeout = ?");
statement.setInt(1, (int) _statementTimeout);
statement.execute();
But on execute() this results in a SQL exception clearly stating that I have an error in the syntax at my question mark.
org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
Position: 25
I tried searching for this problem but couldn't find any right answers. The pages thinks I refer to the SET of an UPDATE-clause.
My question is simple, why is parametrization not working? If I hardcode the value, e.g.
prepareStatement(String.format("set statement_timeout = %s", _statementTimeout))
everything works fine and as expected. Or is it simply wrong to use parametrization on setting variables?
Using the equivalent function call should work:
prepareStatement("select set_config('statement_timeout', ?, false)");
statement.setString(1, Integer.toString(_statementTimeout));
statement.execute();
Note that you need to pass the value as a String as the function's signature is (text, text, boolean)

operator does not exist: # timestamp without time zone

In a parameterized query issued from c# code to PostgreSQL 10.14 via dotConnect 7.7.832 .NET connector, I select either a parameter value or the local timestamp, if the parameter is NULL:
using (var cmd = new PgSqlCommand("select COALESCE(#eventTime, LOCALTIMESTAMP)", connection)
When executed, this statement throws the error in subject. If I comment out the corresponding parameter
cmd.Parameters.Add("#eventTime", PgSqlType.TimeStamp).Value = DateTime.Now;
and hardcode
using (var cmd = new PgSqlCommand("select COALESCE('11/6/2020 2:36:58 PM', LOCALTIMESTAMP)", connection)
or if I cast the parameter
using (var cmd = new PgSqlCommand("select COALESCE(cast(#eventTime as timestamp without time zone), LOCALTIMESTAMP)", connection)
then it works. Can anyone explain what # operator in the error is referring to and why the error?
In the case that doesn't work, your .Net connection library seems to be passing an SQL command containing a literal # to the database, rather than substituting it. The database assumes you are trying to use # as a user defined operator, as it doesn't know what else it could possibly be. But no such operator has been defined.
Why is it doing that? I have no idea. That is a question about your .Net connection library, not about PostgreSQL itself, so you might want to add tag.
The error message you get from the database should include the text of the query it received (as opposed to the text you think it was sent) and it is often useful to see that in situations like this. If that text is not present in the client's error message (some connection libraries do not faithfully pass this info along) you should be able to pull it directly from the PostgreSQL server's log file.

FakeItEasy & "params" arguments

I have a method with the following signature.
Foo GetFooById( int id, params string[] children )
This method is defined on an interface named IDal.
In my unit test I write the following:
IDal dal = A.Fake<IDal>();
Foo fooToReturn = new Foo();
fooToReturn.Id = 7;
A.CallTo(()=>dal.GetFooById(7, "SomeChild")).Returns(fooToReturn);
When the test runs, the signature isn't being matched on the second argument. I tried changing it to:
A.CallTo(()=>dal.GetFooById(7, new string[]{"SomeChild"})).Returns(fooToReturn);
But that was also unsuccessful. The only way I can get this to work is to use:
A.CallTo(()=>dal.GetFooById(7, A<string[]>.Ignored )).Returns(fooToReturn);
I'd prefer to be able to specify the value of the second argument so the unit test will break if someone changes it.
Update: I'm not sure when, but the issue has long since been resolved. FakeItEasy 2.0.0 supports the desired behaviour out of the box.
It might be possible to special case param-arrays in the parsing of the call-specification. Please submit an issue at: https://github.com/patrik-hagne/FakeItEasy/issues?sort=created&direction=desc&state=open
Until then, the best workaround is this:
A.CallTo(() => dal.GetFooById(7, A<string[]>.That.IsSameSequenceAs("SomeChild"))).Returns(fooToReturn);

Versant OQL Statement with an Arithmetic operator

I'm working on a c# project that use a Versant Object Database back end and I'm trying to build a query that contains an arithmetic operator. The documentation states that it is supported but lack any example.
I'm trying to build something like this:
SELECT * FROM _orderItemObject WHERE _qtyOrdered - _qtySent > 0
If I try this statement in the Object Inspector I get a synthax error near the '-'.
Anyone has an example of a working VQL with that kind of statement?
Thanks
I am not sure that the Object Inspector will know the syntax for the arithmtic expression. However, in your code you should be referring to the fully qualified class. Then the syntax you are using should be perfectly fine.
Query query = new Query( session,
"select * from com.yourCompany.yourClass where _qtyOrdered - _qtySent > 0 ");
QueryResult result = query.execute();
I just tried this out on one of my classes and it worked fine.
Cheers,
-Robert
With C# and OQL you have to make sure you select the proper class extent. This is done by adding the "Extent" suffix to the class name. For example, in my Pet class I would identify all the pets with "PetExtent" in the OQL string.
Class members are accessed in the predicate by defining a local moniker, p in the code below. Any arithmetic expressions will be evaluated by the query engine.
string query="SELECT * FROM PetExtent AS p WHERE p.Name = \"Ferris\" AND (p.age + 5) > 4";
IQueryResult result = scope.GetOqlQuery(query).Execute();
foreach (object o in result)
Out(o.ToString());
The best way to test OQL with Versant's C# binding is to use the OQL Query Browser integrated into Visual Studio. Look under the Versant Menu drop down in Visual Studio.
Best Regards,
Derek