I have the following code in a controller. The query given runs on a MediaWiki database:
// Grab the connection to the replica database (which is separate from the above)
$conn = $this->get('doctrine')->getManager("replicas")->getConnection();
// Prepare the query and execute
$resultQuery = $conn->prepare( "
SELECT 'id' as source, user_id as value FROM $dbName.user WHERE user_name = :username
UNION
SELECT 'arch' as source, COUNT(*) AS value FROM $dbName.archive_userindex WHERE ar_user_text = :username
UNION
SELECT 'rev' as source, COUNT(*) AS value FROM $dbName.revision_userindex WHERE rev_user_text = :username
UNION
SELECT 'groups' as source, ug_group as value FROM $dbName.user_groups JOIN user on user_id = ug_user WHERE user_name = :username
");
$resultQuery->bindParam("username", $username);
$resultQuery->execute();
(I know my SQL isn't efficient, it's legacy code that I'm working on cleaning up)
The fourth query is the focus of this question. When the query is run in PHPMyAdmin or MySQLWorkbench it returns the correct results. However, when run in Symfony sometimes it returns the improper results. How can I ensure that it returns the correct results?
(Full full code: https://github.com/Matthewrbowker/xtools-rebirth/blob/master/src/AppBundle/Controller/SimpleEditCounterController.php#L95)
Figured out my question. One thing that wasn't noted was the fact that I wound up selecting the right database name out of a table. This was stored in the variable $dbName. However, it is possible for $dbName to be different than the database that I connected to from paramaters.yml.
Note:
JOIN user on user_id
This portion of the query was missing $dbName. To fix, just add the variable. Like so:
JOIN $dbName.user on user_id
Related
So i'm trying to fetch all of the user_id's from the users-events table where the event_id is equal to the passed in variable (let's say it's 2 for now.)
In the database there are currently 2 ID's registered to that event_id which are 1 and 2.
This code however only returns the first of these values. I feel like i need to incorporate the first query into the while loop but i dont know how to go about it.
Any help would be greatly appriciated!
function showregisteredplayers($id){
$eventq = mysql_fetch_assoc(mysql_query("SELECT user_id FROM `users-events` WHERE event_id = '".$id."'"));
$rosterq = mysql_query("SELECT username FROM `users` WHERE `user_id` = '".$eventq['user_id']."'");
while($player = mysql_fetch_assoc($rosterq)){
echo("
<tr>
<td>".$player['username']."</td>
</tr>
");
}
}
Use a sub query then kill your first one.
SELECT username FROM `users` WHERE `user_id` IN
(
SELECT user_id FROM `users-events` WHERE event_id = 5
)
Rest is fine, you already are looping over the second result set so this should do. Unless you have a large number of records, there should not be any considerable performance degradation with the use of IN otherwise you can optimize the query.
5 is obviously just an example, use $id there correctly.
Why not use a JOIN?
SELECT username
FROM `users` AS u
INNER JOIN `users-events` AS ue ON u.user_id = ue.user_id
WHERE event_id = ?
Several advices:
Don't use mysql_ functions because are deprecated
Use prepared queries, then you only need to loop through execute method, take a look to Example 3 in this link (example from php.net using mysqli)
First of all, I am absolute beginner with PHP and SQL.
I have two tables: users(userID, fullname, username, email, pass, userlevel) and games(gameID, userID, club, result, created_time).
In table games I have userID, same as in table users, but it's not foreign key. When I do this query in MySQL it works fine:
DELETE FROM games
WHERE EXISTS
(SELECT * FROM users
WHERE userlevel=2
AND users.userID=games.userID)
It removes anything that users.userID matches with games.userID and if that user is userlevel 2.
I need this in PHP, but only difference would be that userID will match user's ID that is logged,and user will be able to delete only the data that is input with its userID.
Also, how to allow everyone else, with userlevel 1 to be able to delete everything in table games no matter who entered on the same submit?
I have this, but its not working....it keeps givin' me the same error:
Fatal error: Call to a member function bind_param() on a non-object in
C(...)
require ('db_con.php');
session_start();
$userID=$_SESSION["UserID"];
if (isset($_POST['delete'])){
$stmt=$con->prepare("DELETE FROM games WHERE EXISTS (SELECT FROM users AS u WHERE u.userID = ? AND u.userlevel = 2 "));
$stmt->bind_param("s",$_POST['userID']));
$stmt->execute();
}
Even if I put $userlevel=2 and replace in query u.userlevel = '$userlevel', it gives the same error...
Any suggestions would be greatly appreciated.
thanx!
userID is an integer value. Change bind_param line to
$stmt->bind_param('i', $user_id);
One reason prepare() can fail is -
if the sql statement sent to it is not valid in the current DB.
prepare() will then return false.
Eg - if the table name is not correct or one or more field in the query does not exist.
You got a bracket mismatch:
$stmt=$con->prepare("DELETE FROM games WHERE EXISTS (SELECT FROM users AS u WHERE u.userID = ? AND u.userlevel = 2 "));
should really be
$stmt=$con->prepare("DELETE FROM games WHERE EXISTS (SELECT * FROM users AS u WHERE u.userID = ? AND u.userlevel = 2 )");
Anyway, the error you received means that $con->prepare did not return an object. Most likely it returned false. I assume you are using PDO, so according to the docs:
If the database server cannot successfully prepare the statement, PDO::prepare() returns FALSE or emits PDOException (depending on error handling).
So that's the case here. Your MySQL-server was unable to bind the statement. In order to debug this better (e.g. see more helpful error messages) set PDO to throw exceptions on errors.
You could probably do it like this:
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Just add that line right after you connect to the database.
i found the error, here is the wright code:
$stmt=$con->prepare("DELETE FROM games WHERE EXISTS (SELECT * FROM users WHERE users.userID = ? AND users.userlevel = 2 )");
but its not working what i wanted, it deleted all from my games table :D
i guess, SELECT * FROM has to be specific!
I have two different databases and I have to run a query where I am going to join tables from both databases in a single query. My query goes like this:
SELECT mm.* FROM tbl1 mm INNER JOIN tbl2 t ON mm.module_id=t.module_id WHERE mm.module_name NOT IN(SELECT module_name FROM tbl3)"
Here tbl1 and tbl2 are in one database and tbl3 is in the second database. Is it possible to run this query without HARD CODING the database names before the table names? I created common files global_config1.php and global_config2.php which have the database constants and other php database connection constants and am using require_once(global_config1.php) and require_once(global_config2.php) but the query fails.
Try this:
SELECT Database1.TableA.ColumnA1, Database1.TableA.ColumnA2,
Database2.TableB.ColumnB1, Database2.TableB.ColumnB2
FROM Database1.TableA
INNER JOIN
Database2.TableB ON
Database1.TableA.ColumnA3 = Database2.TableB.ColumnB3
Now, you will see the complete result in a single row. In case, the column names are same in both databases, you will see the column names same in the result and it will be impossible to get the value in PHP because 2 or more column name is same. To accomplish this, lets write another query
you can use two different database to fetch a record, for this you have two database object.
try this,
<?php
$con = mysqli_connect("localhost","root","","test");
$con1 = mysqli_connect("localhost","root","","test1");
$query = "SELECT mm.* FROM test.tbl1 mm INNER JOIN test.tbl2 t ON mm.module_id=t.module_id WHERE mm.module_name NOT IN(SELECT module_name FROM test1.tbl3)"
?>
For CI
$query = $this ->db->query("SELECT * FROM Table-1 WHERE id = (SELECT qid FROM Table-2 where post_status ='active' AND post_type= 'quick') ");
return $query->result_array();
My purpose was resolved by separating the queries and the database connection string variables. So to run a query on one database, I entered separate connection string variables in mysql_query(). This helped fetch the data from both databases.
Would it be possible to store a "link" to another record inside a record? For example:
table USERS
id name link
-------------------------------------------------------
1 user1 [link to record with id=4 in table info]
So, in PHP, I could do something like this:
// connect to the database etc....
$query = "select * from users where id=1";
$result = mysql_query($query);
$another_result = mysql_result($result, 0, 'link');
So that $another_result stores the result of another query, in the same raw format as if it was called using mysql_query().
Is this possible?
$query = "select info.* from info
inner join users on users.link = info.id
where users.id=1";
$result = mysql_query($query);
Using JOIN is a fundamental part of SQL, like using for loops in PHP.
Read A Visual Explanation of SQL Joins by fearless leader.
Maybe you mean a key that point to a another key in another table, so for example you can have something like this :
table USERS
id name info_id
-------------------------------------------------------
1 user1 4
table INFO
id info
--------------
4 someinfo
With a JOIN you can get for example a resultset with the "linked" fields :
SELECT u.name AS name, i.info AS info
FROM USERS u
JOIN INFO i ON u.info_id = i.id
MySql is a so called relational database and having relations (links) between tables is one of the key concepts. In your specific case the "link" you want is called a Foreign Key. You might want to have a read here (there are many more articles around if you have a look on google).
You can retrieve linked records via a JOIN operation as the other answerers have already told you.
suppose i have 1 current user id and another user id to which current user is visiting.....than i want to fetch mysql data only if both have same options.....
for example user1 has uploaded a picture and user2 has also uploaded picture.......than how can i matchd user1 to user2 and query should be like this........
select * from users where id='user1id' or id='user2id' and imguploaded='1'
is this query is correct or not but it is not working for me..........!!
i want a working query same as above not as
select * from users where imguploaded=1
try ecapsultating your where with brackets, because of the precedence...
select * from users where (id='user1id' or id='user2id') and imguploaded='1'
if you don't mysql will presume default precedence and interpret the query like this:
select * from users where id='user1id' or (id='user2id' and imguploaded='1')
which will not give the desired result.
To check if both users have actually have a picture uploaded you could make it:
select COUNT(*) as count from users where (id='user1id' or id='user2id') and imguploaded='1'
and then check if count==2
Why would you want such a thing like this?
Anyway... create some sort of actions table where you have a structure like id, action, desc Then create a user_action table like id, user_id, action_id. Then fetch your results.
This way you store data in therefore meant tables and don't mess up userdata with their action data. This way you can also easily extend actions and compare users of their made actions.
select * from users where (id='user1id' and imguploaded='1') and (id='user2id'and imguploaded='1')
How about with a join?
query = "SELECT * FROM users AS first JOIN users AS second
ON first.imguploaded = second.imguploaded
WHERE first.userid = $user1 AND second.userid = $user2"
This query would take the two users, and if they have the same attribute (imguploaded is the same for both), return both rows, you can then select what you need. You can add more attributes to the ON clause, for example:
ON first.imguploaded = second.imguploaded OR ( first.imgdloaded = second.imgdloaded AND first.somethingelseuploaded = second.somethingelseuploaded).
This way (with the ON clause of the mysql statement) you can combine all the attributes in the AND/ON but you have to place the brackets - ( and ) - in the right places. Of course, if you don't put them, the MySQL server will just read them serially.
Is that what you need?