Syntax error in MySql using subqueries - php

Below is MySql query:
$queryfilter = "SELECT * FROM tablename where sector = " .$_SESSION['idfilterdrop']. " AND
region IN (SELECT region from
tablename where sector = " . $_SESSION['sector'] ." OR region = " .
$_SESSION['r1'] ." OR theme = " . $_SESSION['theme'] .")";
Help me to find the syntax error. I am sure there is a problem of double quotes in the above query. When I run this query on MySql prompt it runs fine but when I replace the constant value with variables this query doesn't work.

Unfortunately, we don't know if your $_SESSION array contains integers or strings. if the elements sector, r1 or theme are strings, you need to quote them in your SQL, like this: WHERE sector = '". $_SESSION['sector'] . "' OR.
Also, your table being named database does not help. If I recall correctly, DATABASE is a reserved word, so you'll need to put backtics around that table name:
... FROM `database` ...

Related

I cannot figure out why I am getting this MySQL syntax error (PHP PDO) (MySQL)

I am trying to do a simple insert into my MySQL database, but I get this syntax error:
Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access
violation: 1064 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
'Combined Authority - ICT Service Desk Technician (WYCA 53) ' at line 2
Why?
Query:
$conn->exec("INSERT INTO jobs (jobname, category, contract, link)
SELECT * FROM (" . $name[$i] . "," . $category[$i] . "," . $contract[$i]
. "," . $link[$i] . ") AS tmp
WHERE NOT EXISTS (
SELECT link FROM jobs WHERE link = '" . " " . $link[$i] . ") LIMIT 1;");
$sql printed:
INSERT INTO jobs (jobname, category, contract, link) SELECT * FROM ( West
Yorkshire Combined Authority - ICT Service Desk Technician (WYCA 53)
Details ,' Other ',' Other
','https://bradford.engageats.co.uk/ViewVacancyV2.aspx?
enc=mEgrBL4XQK0+ld8aNkwYmF3VpPuSfX9mpz94c96U/BBgu1IZbwnQ0d+smFL6YrlPhdWkSGi559WmVou+xCXKsYHbHKP0EyHRCwf+vYTu8aYRJbtJgz78Wm2KQgu+LktushGT2Rg0PHjiRMA2Xyn4gw==') AS tmp WHERE NOT EXISTS ( SELECT link FROM jobs WHERE link ='https://bradford.engageats.co.uk/ViewVacancyV2.aspx?enc=mEgrBL4XQK0+ld8aNkwYmF3VpPuSfX9mpz94c96U/BBgu1IZbwnQ0d+smFL6YrlPhdWkSGi559WmVou+xCXKsYHbHKP0EyHRCwf+vYTu8aYRJbtJgz78Wm2KQgu+LktushGT2Rg0PHjiRMA2Xyn4gw==') LIMIT 1;
Apologies for the poor formatting above. Please copy and paste it into a text editor to view it better.
EDIT:
Strangely, this query works with dummy values, but it's still not working for arrays
INSERT INTO jobs (jobname, category, contract, link)
SELECT * FROM (SELECT 'Test', 'Test2',
'Test3','https://bradford.engageats.co.uk/ViewVacancyV2.aspx?
enc=mEgrBL4XQK0+ld8aNkwYmEUlxXraCLcDtY5P6rS92ks+pMDnlWa9QO6M/Df/HLticzgbgVWV
YayJj+zNDXalJnejkDY/4/gH0pIF9KyvMFXjn0u0quGSUzf4M/Gh0wF0MqIRgwLERFf+xXj6lw4s
tQ==') AS tmp
WHERE NOT EXISTS (
SELECT link FROM jobs WHERE link = 'https://bradford.engageats.co.uk/ViewVacancyV2.aspx?enc=mEgrBL4XQK0+ld8aNkwYmEUlxXraCLcDtY5P6rS92ks+pMDnlWa9QO6M/Df/HLticzgbgVWVYayJj+zNDXalJnejkDY/4/gH0pIF9KyvMFXjn0u0quGSUzf4M/Gh0wF0MqIRgwLERFf+xXj6lw4stQ=='
) LIMIT 1;
try this select query and do same with other variables :
SELECT * FROM ("'".$name[$i]."','".$category[$i]."', '".$contract[$i] ."', '". $link[$i] ."'") AS tmp
I can spot three different problems:
First of all, you are inventing your own SQL syntax and the server is not amused. You cannot SELECT * FROM (anything you want). You can only select from tables, views or subqueries.
Secondly, when you type e.g. foo in SQL the database engine needs a way to figure out if you mean a table or column or you mean literal word. The method used is single quotes:
SELECT foo AS this_is_a_column, 'foo' AS this_is_a_value
FROM bar
You can find more details at What is the difference between an identifier and a literal?
Last but not least, your overall use of the PDO extension is wrong. PDO provides a way to separate code and data but you are not using it. Rather than this:
$conn->exec("SELECT link FROM jobs WHERE link = '" . " " . $link[$i] . ") LIMIT 1;");
... you should be doing something like this:
$stmt = $conn->prepared("SELECT link FROM jobs WHERE link=? LIMIT 1");
$stmt->execute($stmt, array($link[$i]));
Use Quotes for string litterals
backticks for columns and tables names.
For more reference Check: http://php.net/manual/en/pdo.errorinfo.php

PHP MySQL Select * From Where Date < today

So I am building a function that prints out a league schedule. I've run into a little snag when trying to pull the last 5 matches. Here is my code:
$league ID, $direction and $limit are set by the functions parameters.
$matches = $wpdb->get_results('SELECT * FROM ' . $wpdb->prefix . 'leagueDesigner_season_matches WHERE leagueID = ' . $leagueID . ' and date < CURRENT_DATE() ORDER BY date ' . $direction . ' LIMIT 0, ' . $limit);
Appologies, I forgot to finish the post. The code is returning all dates and not just the dates before today.
The most likely explanation for the behavior you observe is that the column named date is defined as a datatype other than DATE, DATETIME, or TIMESTAMP. (Likely, you've defined it as an integer or varchar), and MySQL is not doing a "date" comparison, it's comparing strings or integers.
But absent the definition of the date column, that's just conjecture.
If the "snag" you've hit is an error being returned from MySQL, my recommendation for debugging issues with SQL statements is to you build your SQL text into a string variable, as a separate step, and then echo (or printf or vardump) the contents of the variable containing the SQL text, before you try to execute it.
$sql = "SELECT foo FROM bar WHERE fee = " . $val . " ORDER BY foo DESC LIMIT 1 ";
echo $sql;
And verify that the string echoed out is the SQL text you intend to send to the database; taking that string and attempting to execute it through another MySQL client is an effective way of verifying the statement executes and returns the resultset you expect.
If you use any reserved words as column names, you may need to qualify those column names with a tablename, rowsource alias, etc., or enclose it in backticks. (EDIT: DATE is not a reserved word in MySQL 5.5)
... FROM mytable t WHERE t.date = ...
or
... FROM mytable t WHERE `date` = ...
Also note that including "unsafe" variables in SQL text can lead to SQL injection vulnerabilities.
For example,
$val = '1 OR 1=1';
$sql = "SELECT * FROM mytable WHERE id = ' . $val ;

Print out num rows only selecting user2_id's

I'm trying to print out only the number of rows containing user2_ids within my streamdata_feedback table and it seems to be printing out both the user2_id and the user1_id. How can I rectify this issue with the below code?
$user1_id=$_SESSION['id'];
$user2_id=$data['id'];
$likesqltwo = "SELECT *
FROM streamdata_feedback
WHERE feedback_rating = 1
AND feedback_userid = " . $user2_id .
"AND feedback_streamid = " . $streamid;
$likequerytwo = mysql_query($likesqltwo);
$num3 = mysql_num_rows($likequerytwo);
if ($num3 > 0)
{
echo "And <a title = 'See who likes " .
$poster_name['fullusersname'] .
"s status' href='include/likes.php?streamitem_id=" .
$streamitem_data['streamitem_id']."' />" .
$num3 . " ";
}
Do you have a client for your MySQL database? I'd recommend picking up SqlYog Community Edition. You can then execute your query against it and see how many rows are returned outside of PHP code. Once you have a satisfactory query, then incorporate it into your PHP project.
Next tip: You can include variables from PHP directly in strings with double quotes. PHP will parse the variable, and you needn't concatenate. For example:
$likesqltwo =
"SELECT *
FROM streamdata_feedback
WHERE feedback_rating = 1
AND feedback_userid = $user2_id
AND feedback_streamid = $streamid;";
However this code still has a potential flaw, and that's SQL injection attacks. So ensure that the variables you include are not coming from users, or follow the link to learn more about preventing such things. That's not what you asked for help on, but I thought it was worth a mention.
To find out how many times the feedback_userid equals $user2_id for a particular feedback_streamid and for only feedback_rating values of 1, you could try the following query:
SELECT COUNT(id)
FROM streamdata_feedback
WHERE feedback_rating = 1
AND feedback_userid = 123
AND feedback_streamid = 456;
Substitute your primary key for id, and the correct user id and stream id for 123 and 456 respectively. If you get an unexpected number of results, I recommend removing COUNT(id) and selecting the columns of interest so you can inspect and see why you're getting more rows than you thought.

(MySQL)Need to get match scores from multiple tables and sort by the sum of their scores

I need to get the MATCH AGAINST scores from multiple tables with a common key and combine their sums. The goal in the end is to create a search algorithm that will return rows with matching group_IDs. I have built a mysql query that has yet to run without error.
In case you want to know, this is the specific error:
Warning: mysql_fetch_array(): supplied argument is not a valid MySQL
result resource
These are the tables I wish to search:
table: jn_groups
group_ID, name
table: jn_chat
chat_ID, group_ID, name
table: jn_events
event_ID, group_ID, title, description
My current query looks like this:
SELECT
g.group_ID AS group_ID,
g.name AS name,
SUM(gscore + cscore + escore) AS score,
MATCH(g.name) AGAINST (" . $query . "') AS gscore,
MATCH(c.name) AGAINST (" . $query . "') AS cscore,
MATCH(e.title,e.description) AGAINST (" . $query . "') AS escore
FROM jn_groups g
LEFT JOIN jn_chat c ON g.group_ID = c.group_ID
LEFT JOIN jn_events e ON g.group_ID = e.group_ID
WHERE
MATCH(g.name) AGAINST (" . $query . "')
OR MATCH(c.name) AGAINST (" . $query . "')
OR MATCH(e.title,e.description) AGAINST (" . $query . "')
ORDER BY score
Any help making a query similar to that run would be greatly appreciated!
Two things which could be the reason for breaking this query:
variable $query
All your AGAINST-operators end with "', but start only with ". Make sure $query contains
valid data and
start with an '.
Summate the partial results
Your SUM won't work, because it doesn't know gscore, cscore and escore. It will look for field names instead. You can change this part of your statement like this (ofc replace hello world with your desired search term):
....
SUM(
(MATCH(g.name) AGAINST ('hello world'))
+ (MATCH(c.name) AGAINST ('hello world'))
+ (MATCH(e.title,e.description) AGAINST ('hello world'))
) AS score,
....
Two advices:
Try running the query against your database with a SQL
tool first (p.e. SQLyog, MySQL Workbench, phpMyAdmin or similar), to see if it is working like you want it to. There are a few other possibilities how to break this (p.e. no or wrong fulltext index definition, wrong field names and such), so you have better control about whats going wrong.
Be careful when using reserved variables like NAME in field names. Either escape them properly or - in my eyes better - avoid them.

WHERE IN SQL condition problem

I have this query:
"SELECT * FROM informations WHERE ". $id ." IN (ids)"
It only works if $id is the first value from ids... in ids values are "1,2,3,4,5".
Is there a way for it to work with the rest of the ids?
Would this work for you?
"SELECT *
FROM Informations
WHERE ids LIKE \"" . $id . ", %\" -- try to match against the first value in ids
OR ids LIKE \"%," . $id . ",%\" -- try to match against a value in ids that is neither the first nor the last value
OR ids LIKE \"%," .$id . "\" -- try to match against the last value found in ids"
If ids is a field containing comma-delimited values, then your query is like:
SELECT * FROM `informations` WHERE 3 IN ("1,2,3,4,5")
Instead of what it should be:
SELECT * FROM `informations` WHERE 3 IN (1,2,3,4,5)
There is no automatic tokenisation (splitting on ,) performed; the one value of ids is not automatically converted into a list for you such that IN can work.
Unfortunately your table design has been your undoing here. Can you split the IDs into a separate table using the principle of database normalisation?
Then your query might look like:
SELECT * FROM `informations` WHERE 3 IN (
SELECT `id`
FROM `ids`
WHERE `informations`.`id` = `ids`.`information_id`
)
BTW, "information" is a non-countable noun and, as such, "informations" is wrong.
Update (thanks for the idea, a1ex07!)
Although this is hackery and I still suggest fixing your table layout, I'll be kind and suggest a quick fix.
Willempie was close with:
$query = 'SELECT *
FROM `informations`
WHERE `ids` LIKE "%' . $id . '%"';
Unfortunately, a wildcard match isn't quite powerful enough. Consider if ids is like "1,6,9,12,35,4" and $id is like 3. You get a false positive. The LIKE statement needs to be aware of the commas.
You can add multiple cases:
$query = 'SELECT *
FROM `informations`
WHERE `ids` LIKE "%,' . $id . ',%"
OR `ids` LIKE "%,' . $id . '"
OR `ids` LIKE "' . $id . ',%"';
Or, for brevity, you can work around this with regular expressions:
$query = 'SELECT *
FROM `informations`
WHERE `ids` REGEXP "(^|,)' . $id . '(,|$)"';
For any $id you wish to find, before it must be the start of ids (^) or a comma; after it must be a comma or the end of ids ($). This ensures that $id must be found as a whole, comma-delimited token.
It's a little like "Whole Word Only" in word processor searches, but with commas separating "words" instead of spaces.
Update 2
Another way uses FIND_IN_SET, which performs a search within a comma-delimited string:
$query = 'SELECT *
FROM `informations`
WHERE FIND_IN_SET("' . $id . '", `ids`)';
Your query is technically correct but the values for 'ids' are not.
You should enclose the values of ids within single quotes. If I were to write the code without using ids, it would be like this:
"SELECT * FROM informations WHERE ". $id ." IN ('1','2','3','4','5')"
More info on this rule here: http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html#function_in
I'm not sure what you are trying to achieve. If ids is a column in informations your code is just a weird way to express "SELECT * FROM informations WHERE ids = ". $id "; If it is a string, I don't see why you need WHERE at all : expression $id in (1,2,3,4,5) is constant, it doesn't require interaction with database; in any case you either grab all rows from informations or none.
UPDATE
Another suggestion :maybe ids is a string field in informations that contains "1,2,3,4,5". In this case you cannot get expected results by using WHERE ... IN. You need to use REGEXP to check if string contains your number.
It has to be column name then IN (comma separated values here).
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...)
You did an error in sql syntax.
This is the correct syntax
"SELECT * FROM informations WHERE ids IN (". $id .")";

Categories