I am trying to filter data from a table using sql as follows:
$select= new \Zend\Db\Sql\Select ;
$select->from('questions');
$select->where(array('questions.id'=>$value));
$select->columns(array('user_id','description'));
$select->join('users', "users.id = questions.user_id", array('username','password'), 'left');
echo $select->getSqlString();
$resultSet = $this->tableGateway->selectWith($select);
return $resultSet;
Without the $select->where(array('questions.id'=>$value)); the query executes okay and i can get all database values. Otherwise if i add the statement i get this error:
Attempting to quote a value without specific driver level support
can introduce security vulnerabilities in a production environment.
How can i rectify this for the where clause to work?
You'll probably find that it's echoing the SQL string which is generating that error. Assuming you only did that for debugging, removing that line should fix it. Alternatively you can pass the platform object to the function with something like:
echo $select->getSqlString($this->tableGateway->getAdapter()->getPlatform());
Related
executing the following code:
Query query = QueryFactory.create(queryString);
QueryExecution qexec = QueryExecutionFactory.create(query, model);
Model m = qexec.execConstruct(model);
System.out.println(m.toString());
model.close();
sometimes arises the java.util.ConcurrentModificationException exeception, depending on the type of query I'm executing. There is a way to build an always-safe snippet of code? Thank you.
Use Model m = qexec.execConstruct() (no model argument) then call model.add(m).
If you query and insert statements on the same model, via execConstruct(model)) there is a risk of CCME. Using a different model for the results avoids that.
Does this mean we can not call some thing like this via Java API?
I get error - "Caused by: org.neo4j.graphdb.QueryExecutionException: Cannot perform schema updates in a transaction that has performed data updates."
This happens when I call schema update from a procedure call via neo4j console.
try (Transaction tx = db.beginTx()) {
String query = "CREATE INDEX ON :" + lbl + "(" + name + ")";
db.execute(query);
tx.success();
}
The Cypher query calling the procedure is already executed in a transaction, and there are no nested transactions in Neo4j: when you call db.beginTx(), you're getting the existing transaction, and it's not actually necessary unless you need the Transaction object (e.g. to create locks).
Anyway, even though it's not explicitly documented, it's apparently not possible to manipulate the schema from Neo4j procedures. You could say that it fails the use case of
To provide access to functionality that is not available in Cypher, such as manual indexes and schema introspection.
I created a test procedure similar to yours:
public class IndexProcedure {
#Context
public GraphDatabaseService db;
#Procedure
#PerformsWrites
public void index(#Name("label") String label, #Name("property") String property) {
db.schema().indexFor(Label.label(label)).on(property).create();
}
}
and ran it from the shell in the simplest Cypher query:
CALL my.package.index('Node', 'name');
Without the #PerformsWrite annotation, I get the following (expected) exception:
WARNING: Failed to invoke procedure my.package.index: Caused by: org.neo4j.graphdb.security.AuthorizationViolationException: Schema operations are not allowed for READ transactions.
With the annotation, I get the same exception as you:
WARNING: Failed to invoke procedure my.package.index: Caused by: org.neo4j.graphdb.QueryExecutionException: Cannot perform schema updates in a transaction that has performed data updates.
I guess the rationale is that setting up the schema is mostly a one-time operation that doesn't really need a procedure: if you're going to execute some Cypher query to call the procedure, you might as well run the script which creates the constraints and indices.
There could also be technical constraints: index creation is asynchronous and probably doesn't participate in the transaction (can you rollback the creation of an index?).
Or maybe it's just a bug? We should get someone from Neo to confirm.
Update: it will supposedly be fixed in Neo4j 3.1 when it's released, per a discussion on SlackHQ.
I am trying to bind a parameter to a SQL query in my repository but having an error
public IList<Movie> FindMovieById(int movieId)
{
return Database.Connection().QuerySql<Movie>("select * from myDB.movies where ID=?", new { movieId });
}
I get an OleDb exception.
SQL0313: Number of host variables not valid.
Cause . . . . . : The number of host variables or entries in an SQLDA or descriptor area specified in either an EXECUTE or OPEN statement is not the same as the number of parameter markers specified in the prepared SQL statement S000001. If the statement name is *N, the number of host variables or entries in a SQLDA or descriptor area was specified in an OPEN statement and is not the same as the number of host variables specified in the DECLARE CURSOR statement for cursor C000001. Recovery . . . : Change the number of host variables specified in the USING clause or the number of entries in the SQLDA or descriptor area to equal the number of parameter markers in the prepared SQL statement or the number of host variables in the DECLARE CURSOR statement. Precompile the program again.
I have used ? for parameter binding as OleDb has positional parameters which are denoted by '?' rather the '#parameterName'.
Any help is appreciated.
Using Insight.Database can you try this?
return Database.Connection().QuerySql<Movie>(
"select * from myDB.movies where ID=#movieId",
new { movieId = movieId });
In order for Insight to map queries to objects, it binds parameters by name, not by position.
Your parameter object can be an anonymous type. If you specify:
new { movieId }
I believe the compiler will generate a property with the name "MovieID"
In that case, your parameter should be called #movieId.
If your database doesn't support named parameters, please open an issue up on github and I can take a look at it.
https://github.com/jonwagner/Insight.Database/issues
I am trying to get the following Cypher query written out in GraphClient:
START agency=node(12345)
MATCH agency
-[:AGENCY_HAS_PEOPLE]-()
-[:AGENCY_HAS_PERSON]-person
,person-[?:PERSON_IS_CARER]-carer
,person-[?:PERSON_IS_CLIENT]-client
WHERE (person.UniqueId! = 18989)
RETURN person, carer is not null as IsCarer, client is not null as IsClient
The query works fine in the console and returns the results I expect:
person IsCarer IsClient
Node(1545421) True False
When I try to write that query using Neo4jClient, it throws the following exception.
Expression of type System.Linq.Expressions.LogicalBinaryExpression is not supported.
It is mainly due to the expression in the return statement:
.Start(...)
.Match(...)
.Where(...)
.Return((person, client, carer) => new
{
Person = person.As<Person>(),
IsClient = client != null
IsCarer = carer != null
});
Is anyone already working on a solution for this?
Is there a workaround for it?
Is there any other way to write this query to get the same result?
If I were to implement a solution for this, is there anything related to the internals of Neo4jClient (limitation, pitfalls) that I should know before I begin?
Thanks..
It's a bug in https://github.com/Readify/Neo4jClient/blob/master/Neo4jClient/Cypher/CypherReturnExpressionBuilder.cs
Fork the project
Clone it locally
Write a failing test that demonstrates the problem, in https://github.com/Readify/Neo4jClient/blob/master/Test/Cypher/CypherFluentQueryReturnTests.cs
Fix the issue
Commit and push your fix
Open a pull request
When I'm happy with the quality of the solution, I'll accept and merge the pull request. The fix will then be published to NuGet within a few minutes.
I am using VS2010, Entity Framework 4.0, and Advantage v. 10 in my application. I am trying to make a UDF I have defined in my Advantage DB available to my application code. The designer does not show the UDF under stored procs in the "Update Model from Database" wizard as I would expect it to. So I manually added the UDF to the SSDL as follows:
<Function Name="Test" ReturnType="numeric" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion">
<Parameter Name="PartID" Type="integer" Mode="In"/>
</Function>
I also added a CLR method stub:
[EdmFunction("namespace.Store", "Test")]
public static decimal Test(int partID)
{
throw new InvalidOperationException("Call from within an L2E query");
}
I can see the function in my Linq-to-Entities statement; however, the generated SQL is not valid. Using ToTraceString, the UDF call looks something like this:
"namespace.Store"."Test"("Project3"."PartID") AS "C4"
This gives me the following error:
System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> Advantage.Data.Provider.AdsException: Error 7200: AQE Error: State = 42000; NativeError = 2117; [iAnywhere Solutions][Advantage SQL Engine]Unexpected token: Scalar function name should not be delimited.
It works fine if I run the generated SQL in Advantage Data Architect and correct the function name like so:
Test("Project3"."PartID") AS "C4"
Is there anyway to tell Entity Framework to generate the correct SQL? Am I doing something wrong in the definition of the function in the SSDL?
Thanks in advance.
You need to change your function element to have BuiltIn="true". User Defined Functions are not quoted in the Advantage SQL grammar.
It looks good. Only thing i would recommend is to change the decimal to be nullable but i doubt that would fix the problem because then you would see a different exception. its worth a try. I do covered the function a while back.
http://weblogs.asp.net/zeeshanhirani/archive/2010/04/08/calling-user-defined-database-function-from-linq.aspx