Laravel: toSql function not displaying query correctly - sql

I am trying to diedump the query on my index screen using this line of code:
dd(DB::table('members')->where('name', '=', 'Tycho')->toSql());
Now the problem is that when I am displaying the query on my screen I get this:
"select * from `members` where `name` = ?"
My final goal of these lines of code is that I can save offline queries and execute them when the application is online. Unless someone has a solution for this, I'll have to save the queries in a database.

You are seeing the ? placeholders as Laravel uses Prepared Statements.
See Ijas Ameenudeen's answer on another SO question which details how to add a toRawSql() macro on the Eloquent builder which will replace the placeholders with the bindings that you supplied to the original query.

This is because you are using the toSql method, you can use the getBindings method to get the values / bindings.
oneliner:
$query = DB::table('members')->where('name', '=', 'Tycho')->toSql();
// will give the raw query with bindings.
$sqlWithBindings = str_replace_array('?', $query->getBindings(), $query->toSql());

You can try this:
DB::enableQueryLog();
DB::table('members')->where('name', '=', 'Tycho')->get();
echo "<pre>";
print_r(DB::getQueryLog());

Related

Drupal 7 - db_select: SQL function in where condition

I need to use this condition in my select statement:
WHERE YEAR(date) = YEAR(CURDATE())
but if I do, like this:
$query = db_select('table', 't');
$query->fields('t');
$query->condition('YEAR\(date\)', 'YEAR(CURDATE())', '=');
Drupal won't have it (even if I do not escape those parenthesis - it simply ignores them) because I get an error:
Column not found: 1054 Unknown column 'YEARdate' in 'where clause':
How to overcome this error?
Hmm.. just like this, it seems:
$query->where('YEAR(date) = YEAR(CURDATE())');
The where allows for the arbitrary SQL:
The where() method allows for the addition of arbitrary SQL as a conditional fragment. $snippet may contain any legal SQL fragment, and if it has variable content it must be added using a named placeholder. The $args array is an array of placeholders and values that will be substituted into the snippet. It is up to the developer to ensure that the snippet is valid SQL. No database-specific modifications are made to the snippet.
Hm, you could also use db_query, it allow you to write SQL queries "without Drupal".
I mean, you'll be able to add custom WHERE statements or any SQL-proper functions, like custom functions ;)
Eg.
$result = db_query('SELECT title FROM {node} WHERE type = "%s" AND title LIKE "%%%s%%"', 'type', 'title');
Use addExpression method :
https://api.drupal.org/api/drupal/includes!database!select.inc/function/SelectQuery%3A%3AaddExpression/7.x
$query = db_select('table', 't');
$query->fields('t');
$query->addExpression('YEAR(t.date) = YEAR(CURDATE())');
$result = $query->execute()->fetchAll();
var_dump($result);

How to Fix WHERE Clause in Laravel

I have an issue with Laravel Eloquent when using a WHERE clause.
Code
<?php
$locale = Session::get('locale');
$categories = Category::whereHas('translations', function ($query) use ($locale) {
$query->where('locale', $locale);
})->get();
Generated SQL
select * from `categories`
where exists (select * from `category_translations`
where `category_translations`.`category_id` = `categories`.`id`
and **`locale` = ?**)
It does not register the given value for locale.
I'm also getting the same issue if I put ->where('locale', 'en'), and even if I try a raw query instead of using Eloquent model.
Any help would be much appreciated, thanks.
Like SR_ wrote in the comment toSql() function doesn't return variable binding. If you would like to see how the real queries looks like you can install tools like Laravel Debugar: https://github.com/barryvdh/laravel-debugbar

Returning one cell from Codeigniter Query

I want to query a table and only need one cell returned. Right now the only way I can think to do it is:
$query = $this->db->query('SELECT id FROM crops WHERE name = "wheat"');
if ($query->num_rows() > 0) {
$row = $query->row();
$crop_id = $row->id;
}
What I want is, since I'm select 'id' anyway, for that to be the result. IE: $query = 'cropId'.
Any ideas? Is this even possible?
Of course it's possible. Just use AND in your query:
$query = $this->db->query('SELECT id FROM crops WHERE name = "wheat" AND id = {$cropId}');
Or you could use the raw power of the provided Active Record class:
$this->db->select('id');
$this->db->from('crops');
$this->db->where('name','wheat');
$this->db->where('id',$cropId);
$query = $this->db->get();
If you just want the cropId from the whole column:
foreach ($query->result()->id as $cropId)
{
echo $cropId;
}
Try this out, I'm not sure if it will work:
$cropId = $query->first_row()->id;
Note that you want to swap your quotes around: use " for your PHP strings, and ' for your SQL strings. First of all, it would not be compatible with PostgreSQL and other database systems that check such things.
Otherwise, as Christopher told you, you can test the crop identifier in your query. Only if you define a string between '...' in PHP, the variables are not going to be replaced in the strings. So he showed the wrong PHP code.
"SELECT ... $somevar ..."
will work better.
Yet, there is a security issue in writing such strings: it is very dangerous because $somevar could represent some additional SQL and completely transform your SELECT in something that you do not even want to think about. Therefore, the Active Record as mentioned by Christopher is a lot safer.

How to load objects from sql queries in Joomla 2.5?

Using the Andrew Eddie's tutorials here I am working on building some custom code for menus. Here we go:
$query ->select('id, menutype, title')
->from('#__menu_types')
->where('menutype='.$somemenu);
$db->setQuery($query);
I don't know how to load one object value like I used to do it with Joomla 1.5:
$result = $db->loadObject();
$thetitle = $result->title; // I need this value and I always get error "Notice: Trying to get property of non-object" at this line
How can I SUCCESSFULLY get the value of $thetitle please?
That should work. I see no problem with your code.
The error you are getting is consistent with not having found a match in the database.
Since you do not appear to have any error handling it might even be an SQL error.
Try and add this:
if ($error = $db->getErrorMsg()) {
throw new Exception($error);
}
The correct query is
$query ->select('id, menutype, title')
->from('#__menu_types')
->where('menutype='.$db->quote($somemenu));
$db->setQuery($query);
Now I can get the values of the query correctly.

Does CDbcommand method queryAll() in yii return indexed entries only?

I am trying to retrieve data from a simple mySql table tbl_u_type which has just two columns, 'tid' and 'type'.
I want to use a direct SQL query instead of the Model logic. I used:
$command = Yii::app()->db->createCommand();
$userArray = $command->select('type')->from('tbl_u_type')->queryAll();
return $userArray;
But in the dropdown list it automatically shows an index number along with the required entry. Is there any way I can avoid the index number?
To make an array of data usable in a dropdown, use the CHtml::listData() method. If I understand the question right, this should get you going. Something like this:
$command = Yii::app()->db->createCommand();
$userArray = $command->select('tid, type')->from('tbl_u_type')->queryAll();
echo CHtml::dropdownlist('my_dropdown','',CHtml::listData($userArray,'tid','type'));
You can also do this with the Model if you have one set up for the tbl_u_type table:
$users = UType::model()->findall();
echo CHtml::dropdownlist('my_dropdown','',CHtml::listData($users ,'tid','type'));
I hope that gets you on the right track. I didn't test my code here, as usual, so watch out for that. ;) Good luck!