I have a social networking site which I am in the process of constructing. Users can follow each other and it adds their name to a list of followers. I need to scan that list for the session username cookie to choose which statuses (posts) to display. In my sql recordset, I have the code:
SELECT *
FROM statuses
WHERE followedby CONTAINS '". $_SESSION['MM_Username']."'
But this just brings up 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 'CONTAINS 'Usernamecookie'' at line 1
Try this:
SELECT *
FROM statuses
WHERE followedby LIKE '%". $_SESSION['MM_Username']."%'
LIKE clause is used for string matching.
Others have correctly answered this question already, but I just want to add the meaning of contains in MySQL:
MySQL only recognizes the CONTAINS SQL function when dealing with
spatial data. It requires two graphics objects as arguments, and
returns a 1 or 0 depending on if the first object completely contains
the second. Designed as an implementation of the OpenGIS framework,
the MySQL CONTAINS function does not work on ordinary strings, and
will produce an error if you try it. MySQL only recognizes the LIKE
and STRCMP functions when dealing with string of information.
So in your case, you want to use like.
References:
https://blog.udemy.com/sql-contains/
https://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_like
Instead of Contains use LIKE.
Try this:
mysql_query("
SELECT *
FROM statuses
WHERE followedby LIKE '%{$MM_Username}%'
");
Put the MM_Username in its own var. Nicer code ;)
Remember to enable index for FollowedBy if your table grows.
Read more about how to enable fulltext indexes here
Related
I'm trying to select both the total number and the limited number of products from the database.
Example:
$result = $database->query("SELECT* FROM products WHERE type = $category limit $start,$per_page");
$all_data = $database->query("SELECT* FROM products WHERE type = $category");
However, when I run this I'm getting mysql error.
Is it possible to get the data I need without using multiple queries.
This is mysql error I'm getting;
Database failed...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 '-2,2' at line 1
If I understand you correctly, you're fetching the entire set of products in your category in the second query, but fetching just one page's worth in the first query (e.g., items 10 through 19). I would just fetch all the items with the second query, then load the rows into a PHP array and use array_slice() to grab the segment of the array you need for the current page.
EDIT: As others have said, the actual MySQL error may be the lack of the space between SELECT and *, but you can also do what you're trying to do without hitting the database twice.
If you just need the counts, then use:
SELECT count(*)
FROM products
WHERE type = '$category' limit $start,$per_page");
SELECT count(*)
FROM products
WHERE type = '$category';
The error is due to the use of negative numbers in limit clause. Snippet from MySQL documentation on Select syntax :
The LIMIT clause can be used to constrain the number of rows returned
by the SELECT statement. LIMIT takes one or two numeric arguments,
which must both be nonnegative integer constants (except when using
prepared statements).
So the resolution to that error would be to use prepared statements if you really need negative limits as also asked by #James in one of his comments on your question.
Note that select* does not produce any errors but certainly does confuse!
You create a procedure then you call this procedure. I hope it work for you.
CREATE PROCEDURE `test_proc`()
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
declare name1 TEXT;
declare id1 TEXT;
select name,id into name1,id1 from my_tbl WHERE name='sam';
select * from my_tbl;
select name1,id1;
END
You can call this single call store procedure.
This question already has answers here:
Get table column names in MySQL?
(19 answers)
Closed 9 years ago.
As I am still learning PHP and MySQL, I would like to know if it is possible to query a table without knowing it's name. Knowing the table I am querying and the column I would like to retrieve, I can write something like
$book_title=$row['book_title'];
Then I can use the resulting variable later in the script. In each case, each book category table will have a column of interest with a different name. I have several tables on which I am running queries. I am able to query any table by using a variable that always evaluates to the correct table name, because all the input from users corresponds to the tables in the database, so the $_POST super global will always carry a correct table name. The problem is for me to have a
$variable=$row['column'];
in cases where I do not know a column name before hand even though I know the table name.
My queries are simple, and look like
query="select * FROM $book_categories WHERE id=$id";
$row = mysqli_fetch_array ($result);
$variable=$row['?'];
The question mark say, I do not know what column to expect, as it's name could be anything from the tables in the database!
Since I have several tables, the query will zero on a table, but the column names in each table varies so I would like to be able to use one query that can give me an entry from such a column.
I hope my question is clear and that I am not asking for the impossible. If it's ambiguous, I care to elucidate (hope so).
I'm not sure what you mean, but it is possible to reference specifc columns by typing index (starting with 0) something like this: $row[0], $row[1] where 0 indicates the first column, and 1 indicates the second column from the returned recordset.
Example:
If you have a select-statement like this:
SELECT title, author FROM books
You could reference these two columns with $row[0], $row[1]
If you try to get the value of $row[2] you will get an unassigned value because there are only two columns (0 and 1) from the recordset.
If you have a select-statement like this:
SELECT * FROM book_categories
and the recordset returns three columns, then you could access these with $row[0], $row[1] and $row[2]. $row[3] does not exist because there are only three columns (0,1 and 2)
Since you are learning maybe we could take some time to explain why this is possible but many people (including myself) would say this is bad -- or at least dangerous
Why you can
Your SQL query is basically a text string you send to the DB server, which decode that string trying to interpret it as SQL in order to execute the query.
Since all you send to the DB server is text string, you could build that string however you want. Such as using string interpolation as you did:
select * FROM $book_categories WHERE id=$id
That way, you could replace any part of your query by the content of a variable. You could even go further:
$query FROM $book_categories WHERE id=$id
Where $query could by SELECT * or DELETE.
And, why not initializing all those variables from a form:
$book_categories = $_POST['book_categories'];
$id = $_POST['id'];
$query = $_POST['query'];
Great, no? Well, no...
Why you shouldn't
The problem here is "could you trust those variables to only contain acceptable values?". That is, what would append if $book_categories somehow resolve to one table you didn't want to (say myTableContainigSecretData)? And what if $id resolve to some specially crafted value like 1; DELETE * FROM myImportantTable;?
In these conditions, your query:
select * FROM $book_categories WHERE id=$id
Will become as received by the DB server:
select * FROM myTableContainigSecretData WHERE id=1; DELETE * FROM myImportantTable;
Probably not what you want.
What I've tried to demonstrate here is called SQL injection. This is a very common bug in web application.
How to prevent that?
The best way to prevent SQL injection is to use prepared statement to replace some placeholders in your query by values properly shielded against SQL injection. There was an example posted a few minutes ago as a response to an other question: https://stackoverflow.com/a/18035404/2363712
The "problem" regarding your initial question is that will replace values not table or columns identifiers.
If you really want to replace table/columns identifiers (or other non-value part of your query) by variables contents, you will have to check yourself the content of each of these variables in order to prevent SQL injection. This is quite feasible. But that's some work...
I try to query a mysql column which has the name "5". This outputs the wrong column which has the name "22".
This is my php code, $pid is the variable I am getting from the android app and is always a number. When I search with $pid = 5, instead of getting the column "5" with artist1, it is getting the column "22" with eternal1.
Basically it confuses the Column Name with # in the first print screen. If the # doesn't exist, then it searches correctly; so if I search with 16 I get the column 16. How do I fix this?
$pid = $_GET["pid"];
$result=mysql_query("SELECT * FROM TableComments WHERE `$pid` IS NOT NULL ");
http://imgur.com/WFsfEtB
http://imgur.com/rZA27XC
This is by design in the SQL dialects I can think of offhand. I know several people who, out of habit, add order by 0 desc or order by 1 to ad hoc queries, the first to pick what typically is the ID column and the second what is often a "Name" column or similar. They're querying based on the ordinal position of the field in the query (or the schema, in the case of *)
In order to get a column named 5, you need to use the appropriate SQL quoting mechanism for your dialect and configuration. As an example, Microsoft Sql and Access would typically use select * from tablecomments where [5]=5; in Postgres and Oracle you'd use select * from tablecomments where "5"=5, and in Mysql, Quoted Identifiers are quoted with a backtick select * from tablecomments where `5`=5. In Microsoft SQL you can also make things more like Oracle and Postgres if your session has SET QUOTED_IDENTIFIER ON, in which case you'd use quotes instead of square brackets.
As an aside, but a very important one, you should not take user input and directly embed it in SQL. If someone were to intercept the HTTP transmission between your Android app and your PHP app (trivial with a proxy like Charles or Fiddler), they'd be able to replay the http request with arbitrary SQL injected. As other commenters have noted, please use a parameterized query instead.
Since you're trying to modify the query itself rather than the parameters, you may need to consider whitelisting the allowed field names (or compare the string you're sent against the fields represented in the schema).
Wrap the column-name into backticks:
SELECT * FROM TableComments WHERE `$pid` IS NOT NULL
Start using PDO instead of old, unsafe and deprecated mysql_*
I'm using a PHP webservice where I have performed a simple SELECT query, and stored it
$result = run_query($get_query);
I now need to perform further querying on the data based on different parameters, which I know is possible via MySQL in the form:
SELECT *
FROM (SELECT *
FROM customers
WHERE CompanyName > 'g')
WHERE ContactName < 'g'
I do know that this performs two Select queries on the table. However, what I would like to know is if I can simply use my previously saved query in the FROM section of the second section, such as this, and if my belief that it helps performance by not querying the entire database again is true:
SELECT *
FROM ($result)
WHERE ContactName < 'g'
You can make a temp table to put the initial results and then use it to select the data and in the second query. This will work faster only if your 1-st query is slow.
PHP and SQL are different languages and very different platforms. They often don't even run in the same computer. Your PHP variables won't interact at all with the MySQL server. You use PHP to create a string that happens to contain SQL code but that's all. In the end, the only thing that counts is the SQL code you sent to the server—how you manage to generate it is irrelevant.
Additionally, you can't really say how MySQL will run a query unless you obtain an explain plan:
EXPLAIN EXTENDED
SELECT *
FROM (SELECT *
FROM customers
WHERE CompanyName > 'g')
WHERE ContactName < 'g'
... but I doubt it'll read the table twice for your query. Memory is much faster than disk.
Thanks for the responses, everyone. Turns out what I was looking for was a "query of query", which isn't supported directly by PHP but I found a function over here which provides the functionality: http://www.tom-muck.com/blog/index.cfm?newsid=37
That was found from this other SO question: Can php query the results from a previous query?
I still need to do comparisons to determine whether it improves speed.
If I understand your question correctly you want to know whether saving the "from" part of your SQL query in a php variable improves the performance of you querying your SQL server, then the answer is NO. Simply because the variable keeping the value is inserted into the query.
Whether performance is gained in PHP, the answer is most probable yes; but depends on the length of the variable value (and how often you repeat using the variable instead of building a new complete query) whether the performance will be notable.
Why not just get this data in a single query like this?
SELECT *
FROM customers
WHERE CompanyName > 'g'
AND ContactName < 'g'
G'day,
I'm not familiar with MySQL and this will probably be an easy question!
I am trying to mod a Joomla plugin and am working with this code that works well for a similar function:
$q="SELECT `".$naming."` AS naming FROM `#__users` WHERE `id`='".$jomsocial_event->creator."' ";
$db->setQuery($q);
$eventcreatorname = $db->loadResult();
$eventcreator = ''.addslashes($eventcreatorname).'';
What I need to do is lookup the field id in the table community_groups and return the matching field name. What I have is (note that $jomsocial_event->contentid contains the group ID):
$q="SELECT `".$naming."` AS naming FROM `#__community_groups` WHERE `id`='".$jomsocial_event->contentid."' ";
$db->setQuery($q);
$eventgroupname = $db->loadResult();
$eventgroup = ''.addslashes($eventcreatorname).'';
It returns nothing as the query is wrong; what should it be for my usage?
I'd work backwards from the database.
i.e. turn on SQL logging and look at what's actually arriving in the database. Tweak as necessary by playing with the resulting SQL until you get what you want (and expect) and then implement that in your code.
Take a look at your generated query in the debugging from Joomla.
Run it against mysql directly and see where it goes wrong.
Also, I'd use the JDatabaseQuery API because you are much less likely to get errors with quoting etc. It looks to me like you are treating id as a string not an integer.