I'd like for one of my relationships to return ordering by a certain value as follows:
return $this->hasMany('Photo', 'owner_id')->where('active', '=', '1')->where('visible', '=', '1')->orderByRaw("(`id` = ?) DESC", array($showphoto));
But the above code returns this :
select * from `photos` where `photos`.`owner_id` = '4' and `active` = '1' and `visible` = '1' order by (`id` = '') DESC
How do I get the $showphoto variable to be in the order by?
It won't show you that it was injected since you are not currently triggering the query.
When you will chain the get() method to it, it will "inject" the $showphoto and execute the query.
I am not aware of a way you can see the full query including the values of the parameters before actually executing the query.
Related
i have this query :
SELECT *
FROM news
WHERE STATE LIKE 'SI'
AND data<'".time()."'
ORDER
BY data DESC
limit 0,1
and i would like to know if the function time it's correct because there is an error on synthase.
thank's you !
There are reserved words in MySQL which you cannot use as column names without clearly indicating they are names. See:
https://dev.mysql.com/doc/refman/5.7/en/keywords.html
Both 'data' and 'date' are reserved words. Use back ticks to indicate they are used as names:
$query = "SELECT *
FROM `news`
WHERE `STATE` LIKE 'SI'
AND `data` < '".time()."'
ORDER
BY `data` DESC
LIMIT 0,1
or better, in my opinion, use better column names:
$query = "SELECT *
FROM newsItems
WHERE itemState LIKE 'SI'
AND creationDate < '".time()."'
ORDER
BY creationDate DESC
LIMIT 0,1";
As you can see I had to guess what the columns really stand for, because it's not directly clear from the names. It should be, because that's what they are there for.
TIME() is a function in which you also need to pass your parameter.
So, instead of using it blank like:
select TIME();
you need to use it in this way:
select TIME(now());
Note: In your query, you need to pass like (only if you have datetime field in your table):
AND time(data) < time(now())
If i have employee_id with integer (like 1001) alone, am getting the answer
example the code like this ,
$claimprocess = Employee::find()
->where("employee_id = '1004' and importcompany_id = 1")
->andwhere(" status != 'Deleted' and relationship = 'Self'")
->all();
if i have a employee_id with combination interger and character, am not able get a answer(like E1004),
example code like below,
$claimprocess = Employee::find()
->where("employee_id = 'E1004' and importcompany_id = 1")
->andwhere(" status != 'Deleted' and relationship = 'Self'")
->all();
When I execute this code, am getting error like below
Exception (Database Exception) 'yii\db\Exception' with
message 'SQLSTATE[42S22]: Column not found: 1054 Champ
'E1004' inconnu dans where clause The SQL being executed
was: SELECT * FROM employee WHERE (employee_id = E1004 and
importcompany_id = 1) AND ( status != 'Deleted' )'
UPDATED:
actually am getting that value(E1004) from another variable, I use the variable instead of value, for understanding purpose I have used a value there in my question
You need to enclose your employee_id value i.e. E1004 within quotes its because it contains string literals. So your query looks like a
->where("employee_id = 'E1004' and importcompany_id = 1")
String literals in SQL are denoted with single quotes ('). Without them, the database would interpret E1004 as a column name, and fail the query, since your table doesn't have such a query.
$claimprocess = Employee::find()
->where("employee_id = 'E1004' and importcompany_id = 1")
->andwhere(" status != 'Deleted' and relationship = 'Self'")
->all();
You need to pass the value correctly , as if now you are not passing the value correctly , hence Yii is not generating Sql query correctly. You can pass second parameter to to where clause
$claimprocess = Employee::find()
->where("employee_id = ':employee_id' and importcompany_id = 1" , array(':employee_id'=>'E1004'))
->andwhere(" status != 'Deleted' and relationship = 'Self'")
->all();
I'm having a little problem getting a sql query with prepare on PDO, I have this code:
$portfolio = $db->prepare("SELECT * FROM `news`, `:sub` WHERE `news`.`id` = `:sub`.`id_news` AND `page` = `:under` ORDER BY `date` DESC LIMIT :start, :limit");
$portfolio->bindParam(':under', $_GET['under'], PDO::PARAM_STR);
$portfolio->bindParam(':sub', $_GET['sub'], PDO::PARAM_STR);
$portfolio->bindParam(':start', $start, PDO::PARAM_INT);
$portfolio->bindParam(':limit', $limit, PDO::PARAM_INT);
$portfolio->execute();
But this doesn't give any value and my DB has the values correct, any one knows why this doesn't work?
PS: var $start and $limit are fine, no problem with it cuz it's pagination script, that work very fine in all the pages.
For exemple i'm in the url: mysite.com/index.php?sub=vid&under=info
so the query should be like this:
"SELECT * FROM `news`, `vid` WHERE `news`.`id` = `vid`.`id_news` AND `page` = `info` ORDER BY `date` DESC LIMIT 0, 10"
So for what i understood having this code before should work and still be safe right?
switch($_GET['sub']){
case "vid":
$table = "vid";
break;
case "img":
$table = "img";
break;
}
$portfolio = $db->prepare("SELECT * FROM `news`, `$table` WHERE `news`.`id` = `$table`.`id_news` AND `page` = :under ORDER BY `date` DESC LIMIT :start, :limit");
You can't use query parameter placeholders for table names or column names.
Use query parameters only to substitute for a literal value in an expression. I.e. a quoted string, quoted date, or numeric value.
Also, even if you are using a parameter for a string or date, the parameter doesn't go inside quotes.
To make table names or column names dynamic, you have to interpolate application variables into your SQL string before you submit the string to prepare().
But be careful to validate user input (e.g. $_GET variables) so you avoid SQL injection. For instance, test the input against a list of known legitimate table names.
Example:
$subtables = array(
"DEFAULT" => "text",
"text" => "text",
"vid" => "vid",
"pic" => "pic"
);
// if the key exists, use the table name, else use the default table name
$subtable = $subtables[ $_GET["sub"] ] ?: $subtables[ "DEFAULT" ];
// now $subtable is effectively whitelisted, and it is safe to use
// without risk of SQL injection
$portfolio = $db->prepare("SELECT *
FROM news, `$subtable` AS sub
WHERE news.id = sub.id_news
AND page = :under
ORDER BY date DESC LIMIT :start, :limit");
You can't use parameters for the names of tables and table object (i.e fields). See this question where this is covered.
Can PHP PDO Statements accept the table or column name as parameter?
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
are two magical lines that will solve all your minor problems after you fix the BIGGEST one - a dynamically linked table.
What it have to be is a single table where "sub" is a field name to distinguish a category
SELECT * FROM news n, subnews s
WHERE n.id = id_news AND s.sub =:sub AND `page` = :under
ORDER BY `date` DESC LIMIT :start, :limit
Also you have to quit that habit of wrapping in backticks everything that moves.
I am running an mysql query and I am trying to order the results by there auto incrementing index value. I am running my query with this code.
$query = mysql_query("SELECT * FROM chanels WHERE videolocation != '' ORDER BY index DESC ");
This worked before I added the ORDER BY function and now when I run a mysql_num_rows test it is returning 0 rows. If you have any ideas thank you I appreciate it.
Are you sure that the column is called index? That is not an ideal choice for a column name because it is a reserved word. Normally the auto-increment column should be called id or similar.
If you really have called your column index then you need to quote it using backticks in your SQL queries:
SELECT * FROM chanels
WHERE videolocation != ''
ORDER BY `index` DESC
Edit yoru code like this
$query = mysqli_query("SELECT * FROM chanels
WHERE videolocation != ''
ORDER BY 'index' desc");
may it helps you
look at this table please
table
|id| |name| |order|
i must get the rows, where name = something and order = somevalue
so i write
select `id` from `table` where `name` = 'something' and `order` = 'somevalue'
but depend on php logic, sometimes i need to get all rows, where name = something, independently of order value. i don't want to change the query structure, because in practise there are many number of fields, and possible count of queries will become very big. so i want to save the structure of query, and when i need to select just by name, i want to write something like this:
select `id` from `table` where `name` = 'something' and `order` = any value
is it possible?
thanks
Well, it's kind of a hack, but if you really need to do this, it'll work like this:
select `id` from `table` where `name` = 'something' and `order` = `order`
Then you're just saying "wherever order is the same as itself", so it's always true.
No, this is not possible. You need to change the structure (optionally to a LIKE so you can use '%', but that's very ugly).
However, you don't need to write a different query to handle every possible combination. You can simply create the query dynamically:
//create base query
$query = "select `id` from `table` where `name` = 'something' ";
//add order if we need it
if ($use_order)
$query .= "and `order` = 'somevalue' ";
//repeat for any other optional part
Note that you should of course still take proper measures to avoid SQL injection and other security issues - I have not included this here in order to keep things simple.
If you are using bound parameters, it would be impossible.
If you just substitute the values, you can do the following:
select `id` from `table` where `name` = 'something' and `order` = `order`
This is a common theme with database queries - you need a variable query depending on how much filtering you wish to apply to the data it queries. You could go the route of having your query repeated as a string throughout your code, but that is bad practice as it increases the complexity of the code needlessly. Chances for errors occur if you need to change the query for some reason, and have to change it in multiple places as a result.
The better solution is to create a function which builds the query for you execute:
function buildMyQuery($name, $order = null) {
$sql = "SELECT `id` FROM `table` WHERE `name`='$name'";
if ($order != null) {
$sql .= " AND `order`='$order'";
}
return $sql;
}
You could then run this for just using the 'name' field:
$query = buildMyQuery("somename");
Or this for using both fields:
$query = buildMyQuery("somename", "someorder");
As someone mentioned above, this code is deliberately simplified and contains no contingency for possibly dangerous data passed in via $name or $order. You would need to use mysql_real_escape_string or something similar to clean the data first, at the beginning of the function before either piece of data is used.
Dynamic query generation is a fact of life as Byron says, so I would become accustomed to it now rather than using hack-ish workarounds.
I don't think you have any choice... Once you do a selection you can't "unfilter" and get more rows.
You should just use two queries-- either two independent queries, or one that selects on the name into a temp table, and then (optionally) one that further selects on the order attribute.
Like Chad said above, just set the column equal to itself. But be careful, on some platforms / install configurations, NULL != NULL:
select `id` from `table` where `name` = 'something' and coalesce(`order`,'') = coalesce(`order`,'')
On reflection, I have a better answer. My colleague showed me a way this can be done.
My example...
Select rentals.* From rentals Where ((? = '') OR (user_id = ?))
The variables must be the same.
If they are both 5 for example, the first boolean will be false, but the second will be true, for the rows where the users id is 5.
If you require "all", setting as an empty string will result in all rows being seen to meet the where clause condition.
Can't you just use a not null query here?
select `id` from `table` where `name` = 'something' and `order` is not null;
You should be able to do it like this:
select `id` from `table` where `name` <>'' and `order` <>''
That will select anywhere that the value is not equal to blank.
$sql = "SELECT * FROM auctions WHERE id = id ";
if ($category !== "ANY") {
$sql .= "AND category = $category "; }
if ($subcategory !== "ANY") {
$sql .= "AND subcategory = $subcategory "; }
if ($country !== "ANY") {
$sql .= "AND country = $country "; }
$sql .= "ORDER BY $order $sort LIMIT $limit OFFSET $offset";