I try to make an exception for my function where is address is null, it did not have to print out the null value.
Here is my function:
if (UserAddress::where('address_2', '=', 'null')) {
$a = UserAddress::select("*", DB::raw("CONCAT(user_addresses.address_1,' ',user_addresses.address_2,' ',user_addresses.city,' ' ,user_addresses.postcode,' ',user_addresses.state) as full_address"))->pluck('full_address');
}else{
$a = UserAddress::select("*", DB::raw("CONCAT(user_addresses.address_1,' ',user_addresses.address_2,' ',user_addresses.city,' ' ,user_addresses.postcode,' ',user_addresses.state) as full_address"))->pluck('full_address');
}
When I die dump $a, the first produce null query.
You cannot use arithmetic comparison operators such as =, <, or <> to test for NULL.
Instead of where('address_2', '=', 'null'), try using the whereNull() function like so:
if (UserAddress::whereNull('address_2')) {
$a = UserAddress::select("*", DB::raw("CONCAT(user_addresses.address_1,' ',user_addresses.address_2,' ',user_addresses.city,' ' ,user_addresses.postcode,' ',user_addresses.state) as full_address"))->pluck('full_address');
}else{
$a = UserAddress::select("*", DB::raw("CONCAT(user_addresses.address_1,' ',user_addresses.address_2,' ',user_addresses.city,' ' ,user_addresses.postcode,' ',user_addresses.state) as full_address"))->pluck('full_address');
}
It can help to enable the query log to see what exactly you are querying on the database, then you can run it directly via phpmyadmin (or whatever you are using). Place DB::enableQueryLog(); before you query, and //dd(DB::getQueryLog()) after the query is executed for troubleshooting.
I solve it. Use empty string with CONCAT_WS
DB::raw("CONCAT_WS('',user_addresses.address_1,...
Related
I am running into some errors when trying to run a stored procedure through Perl.
The following statements work fine in sqlDeveloper and return expected results
EXEC alpha.beta.do_something()
This does not generate any output, as expected
Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName
This generates output which is given to us from the DBA guys. It has this format in DB terms: Output Type:Ref Cursor. The cursor has two columns, a and b
When running through Perl, I get errors when running the second statement.
This is the Perl code that I am using:
sub execute_procedure {
my $dbh = shift;
my $procedure = shift;
my $statement = "BEGIN $procedure; END;"
my $sth;
eval {$sth = $dbh->prepare($statement);};
eval {$sth->execute();};
if ($#) {
print "failed";
} else {
print "passed";
}
}
# Call 1
execute_procedure($dbh, "alpha.beta.do_something()")
# Call 2
execute_procedure($dbh, "Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from tableName")
Call 1 works as expected, does not generate any errors
Call 2 results in this error
"Select alpha.beta.get_something(alpha.STRING_ARRAY('xyz')) from
tableName" results in :PLS-00428: an INTO clause is expected in this
SELECT statement (DBD ERROR: error possibly near <> indicator at char
6 in 'BEGIN <>Select alpha.beta.get_result(alpha.STRING_ARRAY('xyz'))
from tableName; END;')
if I remove BEGIN and END from the statement in the execute_procedure function like this:
# my $statement = "BEGIN $procedure; END;";
my $statement = "$procedure";
then it does not generate any error, but it returns a result which I don't know how to parse
my $result = $sth->fetchrow_hashref;
print Dumper($result)
results in:
$VAR1 = {
'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))' => bless( {}, 'DBI::st' )
};
so, my questions are
What is the right way to execute a stored procedure which uses the SELECT statement? Should it be called with BEGIN $procedure; END; or without the BEGIN/END?
How can I get the actual data from bless( {}, 'DBI::st' )? I have tried to use different fetch options: fetchrow, fetchrow_hashref etc. but I am not able to get the actual data from the object
$VAR1 = { 'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))' => bless( {}, 'DBI::st' ) };
The value here is a DBI statement handle. It's the same thing you get when you do my $sth = $dbh->prepare(...). It's probably been executed already, so you can just call any of the fetch methods on it.
my $result = $sth->fetchrow_hashref;
while (
my $res = $result->{'alpha.beta.get_result(alpha.STRING_ARRAY(\'xyz\'))'}
->fetchrow_hashref
) {
# ...
}
But that looks horrible, and you might not know what the keys are. So you might want to just iterate over all of them.
my $result = $sth->fetchrow_hashref;
foreach my $key ( keys %${ $result } ) {
print "Processing results of $key\n";
while ( my $res = $result->{$key}->fetchrow_hashref ) {
# do things with the $res
}
}
You just need to figure out a good way to deal with the results. The above loop also works if there is just one key in the hash ref, so you could just use it anyway and hope that there is always just one.
I have a query to search keywords using like, but I also want to search full text so I changed it to full text search query, but it doesn't work.
The old query that's working fine:
$data = $this->db
->select('content.title,content.id,content.category,content.body,path')
->from('content')
->join('categories','content.category = categories.id')
->like('content.title', $searchterm)
->like('content.body', $searchterm)
->order_by("content.id","DESC")
->get();
and this is my new query for full text search:
$data = $this->db
->select('content.title,content.id,content.category,content.body,path')
->from('content')
->join('categories','content.category = categories.id')
->where('MATCH (content.body, content.title) AGAINST ("'. $searchterm .'")')
->order_by("content.id","DESC")
->get();
if you are using mysql version 5.5 or lower, make sure all the tables involved have the engine MyISAM.
make sure the your column has the FULLTEXT INDEX.
where() takes 3 arguments, example:
$this->db->where('MATCH (field) AGAINST ("value")', NULL, FALSE);
$this->db->get('table');
more than one columns in match() triggers Error Number: 1191, so separate them:
->where('MATCH (content.title) AGAINST ("'. $searchterm .'")')
->where('MATCH (content.body) AGAINST ("'. $searchterm .'")')
Try by changing the where clause in your query, see if it helps:
->where('MATCH (content.body, content.title) AGAINST ("'. $searchterm .'")', NULL, false)
This sets the value to NULL and tells CI not to escape the string.
you did not use the correct syntax of mathch .... against
try this:
->where MATCH (content.body, content.title) AGAINST ("'. $searchterm .'") > 0
if you have multiple column you can use them in single line like this:
->where("MATCH(title, model) AGAINST('$text')", null, false);
or just one column:
->where("MATCH(title) AGAINST('$text')", null, false);
don't forget to escape your inputs. because we disabled escaping with that false over there. use this for escaping:
$text = $this->db->escape_str($text);
I have been working on this for like more than 4 hours. I have select query using active record I am doing: $this->db->like ('items.name',$search);
everything works fine but whenever there is single quote (') in the $search string it gives this error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's%' OR default_items.short LIKE 'faith\'s%' LIMIT 5' at line 5
I have just checked now that it is adding double back slashes \\ instead of single in my active record for LIKE query. I tried in MySQL bt removing one slash and it is working.
My code:
$q = "faith's";
$query = $this->db->select('items_categories.slug as category_slug, items_categories.name as cat_name, items.name, items.price_value, items.cover_photo, items.slug');
$query->select('default_items.short as short',false);
$query->select('date(default_items.date_created) as date_created',false);
$query->join('items_categories','items_categories.id=items.root_id','inner');
$query->join('users','items.company_id=users.id','inner');
$query->like('items.name',$q);
$query->or_like('items.short',$q);
$query->limit(5);
$result = $query->get($this->_table);
$both_prod_results = $result->result();
I am using pyrocms 2.x.
You can try the following code maybe it can help you, but you have to add \ before every' in your requests :
$value = "faith\'s";
$sql_request = "`short` LIKE '%". $value ."%'";
$query = $this->db
->select('*')
->where($sql_request, null, false)
->get('default_items');
$result = $query->result();
dump($result);
i think i need to answer my own question.
Well this is a hack(don't think if it is secure)
I have patched my MYSQLI Driver:
i have replaced this:
return str_replace(array($this->_like_escape_chr, '%', '_'),
array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
$str);
with this:
return str_replace(array($this->_like_escape_chr, '%', '_'),
array($this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
$str);
it was adding extra slash. and also don't think it will allow sql injections etc anything.
if anyone knows this is right then please comment.
Thanks
Umair
I have 2 queries:
$genres = $this->db->select('Group_Concat(intGenreId) strDJGenres')
->from('tblDJGenres')
->where('intDJId', $this->session->userdata('non_admin_userid'))
->get()
->row();
$results = $this->db->select('tblTracks.*, tblGenres.strName as strGenreName')
->from('tblTracks')
->join('tblGenres', 'tblTracks.intGenreId = tblGenres.intGenreId', 'left')
->where_in('tblTracks.intGenreId', $genres->strDJGenres)
->get()
->result();
The first query is returning a string such as
'1,2,3,4,8,6,5,7,45,66'
which I am using in my where_in clause on the second query. The issue is that with this string, it is writing the SQL like:
SELECT `tblTracks`.*, `tblGenres`.`strName` as strGenreName FROM (`tblTracks`) LEFT JOIN `tblGenres` ON `tblTracks`.`intGenreId` = `tblGenres`.`intGenreId` WHERE `tblTracks`.`intGenreId` IN ('1,2,3,4,8,6,5,7,45,66')
With the quote around it, it is treated as a single value. How can I get the second query to perform how I want it? ie
.... where `tblTracks`.`intGenreId` IN (1,2,3,4,8,6,5,7,45,66)
Multiple values can be passed to the where_in clause as an array.
The quotes from the start and end of the string can be removed using trim():
$dj_genres = trim($genres->strDJGenres, "'");
This string can then be converted into an array of strings, to pass to the where_in clause of the second query.
$dj_genres_array = explode(",", $dj_genres);
Or, if you need an array of integers:
$dj_genres_int_array = array_map('intval', $dj_genres_array);
You can just add the resultant array into the second query:
// ...
->where_in('tblTracks.intGenreId', $dj_genres_array)
// ...
Or:
// ...
->where_in('tblTracks.intGenreId', $dj_genres_int_array)
// ...
Answer given by the JLeft :
The quotes from the start and end of the string can be removed using the following function:
$dj_genres = trim($genres->strDJGenres, "'");
This string can then be converted into a array of strings, to pass to the where_in clause of the second query.
$dj_genres_array = explode(",", $dj_genres);
If you need an array on integers, it can be generated as so:
$dj_genres_int_array = array_map('intval', $dj_genres_array);
was working absolutely fine...Thanks JLeft
I'm trying to group my entity by a field (year) and do a count of it.
Code:
public function countYear()
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('b.year, COUNT(b.id)')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->addOrderBy('sclr1', 'DESC')
->addGroupBy('b.year');
$query = $qb->getQuery();
die($query->getSQL());
$result = $query->execute();
//die(print_r($result));
return $result;
}
I can't seem to say COUNT(b.id) AS count as it gives an error, and
I do not know what to use as the addOrderby(???, 'DESC') value?
There are many bugs and workarounds required to achieve order by expressions as of v2.3.0 or below:
The order by clause does not support expressions, but you can add a field with the expression to the select and order by it. So it's worth repeating that Tjorriemorrie's own solution actually works:
$qb->select('b.year, COUNT(b.id) AS mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
Doctrine chokes on equality (e.g. =, LIKE, IS NULL) in the select expression. For those cases the only solution I have found is to use a subselect or self-join:
$qb->select('b, (SELECT count(t.id) FROM \My\Entity\Album AS t '.
'WHERE t.id=b.id AND b.title LIKE :search) AS isTitleMatch')
->from('\My\Entity\Album', 'b')
->where('b.title LIKE :search')
->andWhere('b.description LIKE :search')
->orderBy('isTitleMatch', 'DESC');
To suppress the additional field from the result, you can declare it AS HIDDEN. This way you can use it in the order by without having it in the result.
$qb->select('b.year, COUNT(b.id) AS HIDDEN mycount')
->from('\My\Entity\Album', 'b')
->where('b.year IS NOT NULL')
->orderBy('mycount', 'DESC')
->groupBy('b.year');
what is the error you get when using COUNT(b.id) AS count? it might be because count is a reserved word. try COUNT(b.id) AS idCount, or similar.
alternatively, try $qb->addOrderby('COUNT(b.id)', 'DESC');.
what is your database system (mysql, postgresql, ...)?
If you want your Repository method to return an Entity you cannot use ->select(), but you can use ->addSelect() with a hidden select.
$qb = $this->createQueryBuilder('q')
->addSelect('COUNT(q.id) AS HIDDEN counter')
->orderBy('counter');
$result = $qb->getQuery()->getResult();
$result will be an entity class object.
Please try this code for ci 2 + doctrine 2
$where = " ";
$order_by = " ";
$row = $this->doctrine->em->createQuery("select a from company_group\models\Post a "
.$where." ".$order_by."")
->setMaxResults($data['limit'])
->setFirstResult($data['offset'])
->getResult();`