So I have DB query
ageVariable = 36
Actor.where("age > ?", ageVariable)
is that possible to avoid ? syntax?
I'm looking for :key based solution that would look something like this:
Actor.where(age: greater_than(age_variable) or ...where(age: > age_variable)
Edit:
In response to #bounty answer:
Range doesn't solve problem.
Actor.where(:created_at => (1000000.years.ago..2.days.ago) sounds terrible
You can use Arel to get it done without using raw SQL:
Actor.where(Actor.arel_table[:age].gt(36)).all
You can use range condition for this.
ageVariable = (36..1000)
Actor.where(:age => ageVariable)
This will give all actor which are in between 36-1001
ageVariable = 36
Actor.where("age > :target_age", target_age: ageVariable)
I avoided ? and made it look like the latter one ...where(age: > age_variable)...And I'm not even using between but greater than. Did I get closer to what you have in your mind?
Related
in a project with 2.2.7 there is code like this:
$select->where->expression('CXORDERNUMBER = "' . $orderNumber . '"', null);
When trying to update this for 2.4.9 I get the following error:
*Zend\Db\Sql\Exception\RuntimeException
The number of replacements in the expression does not match the number of parameters*
I had to change it to the following, which is also more familiar to me:
$select->where(array("CXORDERNUMBER" => $orderNumber));
There are many of these expressions in the code. Sometimes it is not possible for me to change it in the way above. Can someone explain me, why this happens in the newer version of ZF?
Thanks!
Update:
The expression must be used like this:
$select->where->expression('CXORDERNUMBER = ?', array($orderNumber));
In 2.4.9 there is always a parameter set and not ignored as in 2.2.7 with a null-Value
After checking, you can write :
$where = new Where();
$where->equalTo('CXORDERNUMBER', $orderNumber);
$select->where($where);
Don't forget
use Zend\Db\Sql\Where;
Best
I want to create a SQL using the keywork 'between' in Elixir Ecto.
I know how to create a sql using like
where: like(t.descript, ^some_description)
But when I try to do it in the same way as like
where: between(t.start_date, ^start_date, ^end_date),
I got the "not valid" error msg
** (Ecto.Query.CompileError) `between(t.start_date(), ^start_date, ^end_date)` is not a valid query expression.**
How can I do it the right way?
Thanks in advance!!
I don't think Ecto provides a between clause. You could achieve your task by using
where: t.start_date >= ^start_date,
where: t.start_date <= ^end_date
You can use fragment to do this.
where: fragment("? BETWEEN ? AND ?", t.date, ^start_date, ^end_date)
https://hexdocs.pm/ecto/3.1.4/Ecto.Query.API.html#fragment/1
You can also make your own between macro using the fragment answer #Horvo gave:
#doc """
Checks if the first value is between the second and third value.
"""
defmacro between(value, left, right) do
quote do
fragment("? BETWEEN ? AND ?", unquote(value), unquote(left), unquote(right))
end
end
and use it like you wish you could:
where: between(t.start_date, ^start_date, ^end_date)
I'm having an issue with the Where clause not pulling out the values and putting them as parameters.
return
startingNode
.StartCypher("startNode")
.Match(matchQuery)
.Where<TSourceNode>(otherStartNodes => otherStartNodes.Id != startingNode.Data.Id)
.Return<TSourceNode>("otherStartNodes").Results;
The Query string comes out looking like "WHERE (Id <> Id)". I can fix the problem easily by not using lambdas and just using the code below but I'm interested to see why it didn't work
.Where("startNode.Id <> otherStartNodes.Id")
I've also tried the below line but that didn't work either.
.Where<TSourceNode, TSourceNode>((otherStartNodes, startNode) => otherStartNodes.Id != startNode.Id)
Edit
Tatham - I've created an issue in Bitbucket for this.
You are correct the right way for the Where clause should be.
.Where<TSourceNode, TSourceNode>((otherStartNodes, startNode) => otherStartNodes.Id != startNode.Id))
Update: This is issue 73, fixed in 1.0.0.525 and above.
From what I understand of your rather dynamic query, the third option you mentioned (.Where<TSourceNode, TSourceNode>((otherStartNodes, startNode) => otherStartNodes.Id != startNode.Id)) is the correct one.
This should work. I even added more unit tests in Neo4jClient to assert that it does: https://bitbucket.org/Readify/neo4jclient/commits/cc73ce253ddce89e69785caa68f5e4660a622b96
Can you explain why you think it didn't work? What was the resulting query text?
The value you're getting for .Where<TSourceNode>(otherStartNodes => otherStartNodes.Id != startingNode.Data.Id) is wrong. It should evaluate startingNode.Data.Id once in .NET, then send something like WHERE otherStartNodes.Id <> {p1} over the wire. I'll test this separately.
With this code:
candidates = Challenge.joins(:projectmilestone).where("challenges.id in (?) and projectmilestones.user_id = ?", c.subtree_ids, assignee.id)
logger.debug "candidates: #{candidates.count}"
I get this into my logs:
SELECT COUNT(*) FROM "challenges" INNER JOIN "projectmilestones" ON "projectmilestones"."id" = "challenges"."projectmilestone_id" WHERE (challenges.id in (1122) and projectmilestones.user_id = 123)
Candidate projectmilestones: 0
When I run the query straight in the database, the result is 1
Why does Activerecord tells me that the result = 0?
Please note that when I remove "and projectmilestones.user_id" from the code, then it performs right.
This has been driving me crazy for a couple of hours...
Wrong SQL statement: challenges.id in (1122)
If c.subtree_ids returns array, then:
c.subtree_ids.join(", ")
I've got it: I changed the user_id before triggering the above query but I saved it afterwards...
This is why, when running the code, it was incorrect but when cross-checking, it was ok...
Nothing was wrong with rails, it was with wrong with me... Sorry and thanks for your help!
I have a file with the following structure
<admin>
<sampleName>Willow oak leaf</sampleName>
<sampleDescription comment="Total genes">
<cvParam cvLabel="Bob" accession="123" name="Oak" />
</sampleDescription>
</admin>
I'm trying to get out the text "Total genes" after the sampleDescription comment, and I have used the following code:
sampleDescription = doc.xpath( "/admin/Description/#comment" )
sampleDescription = doc.xpath( "/admin/Description" ).text
But neither work. What am I missing?
might be a typo... have you tried doc.xpath("/admin/sampleDescription/#comment").text?
It's not working because there's no Description element. As mentioned by Iwe, you need to do something like sampleDescription = doc.xpath("/admin/sampleDescription/#comment").to_s
Also, if it were me, I would just do sampleDescription = doc.xpath("//sampleDescription/#comment").to_s. It's a simpler xpath, but it might be slower.
And as a note, something that trips up a lot of people are namespaces. If your xml document uses namespaces, do sampleDescription = doc.xpath("/xmlns:admin/sampleDescription/#comment").to_s. If your doc uses namespaces and you don't specify it with xmlns:, then Nokogiri won't return anything.
Try this:
doc.xpath("//admin/sampleDescription/#comment").to_s
doc.xpath returns a NodeSet which acts a bit like an array. So you need to grab the first element
doc.xpath("//admin/sampleDescription").first['comment']
You could also use at_xpath which is equivalent to xpath(foo).first
doc.at_xpath("//admin/sampleDescription")['comment']
Another thing to note is that attributes on nodes are accessed like hash elements--with [<key>]