WHERE clause in MySql statement breaking page - mysql

I have selected all the appropriate columns for this statement. When I change WHERE user_id = $user, and the $user is a number, that works. However it doesn't seem to like the username letters. User is a valid column in my table and 'john' does exist. What am I doing wrong?
$user = 'john';
// Set the timestamp from the current system time
$time = time();
// Put our query together:
$query = "UPDATE table set
`time` = {$time}
WHERE user = {$user}";

In your query, here:
`user_id` = {$user},
`time` = {$time}
WHERE user = {$user}";
You're pointing twice to the same value $user, one for id, one for user, Are you sure you haven't defined that value twice in your JS scripts? Try giving different names to each value and that could help

do you miss a "," after "{$time}"?

Check the data in the user column, I have a feeling it's numeric. If you insist on using the username the look in MySQL documentation of a function to convert username to user-number and use it in your WHERE clause.

Related

MySQL Get "id" from select

I have a select statement:
SELECT id, content, name
FROM records
WHERE type = '1'
AND name = 'test';
Here's the output:
id content name
99708 10.6.252.41 server01.example.org
What I'd like to do is be able to get the id that is returned from the previous statement and USE the id as input into another statement (an UPDATE statement) that will increment the value of a single column in the same table.
An example UPDATE statement that I am wanting is:
update records SET hits = hits + 1 WHERE id = ID_FROM_SELECT;
Thanks in advance.
You can use user defined session variables for this if the SELECT is returning just one result:
SELECT #id:=id AS id, content, name
FROM records
WHERE type = '1'
AND name = 'test';
Then, on the same database session (connection), do the following:
UPDATE records
SET hits = hits + 1
WHERE id = #id;
I'm assuming you're doing something with the selected records in your app, and you're trying to save on performance by avoiding having to search for the record again in the UPDATE. Though, in that case, why not set the 'id' value as a parameter in code?
Obviously, if the SELECT is returning multiple records, this would best be done in code as I mentioned above, otherwise you're left with running the SELECT query again as a subquery:
UPDATE records
SET hits = hits + 1
WHERE id IN
(SELECT id
FROM records
WHERE type = '1'
AND name = 'test');
So, then, it makes more sense just to apply the same filter to the UPDATE instead:
UPDATE records
SET hits = hits + 1
WHERE type = '1'
AND name = 'test'
Probably this is not what you want to do.
First of all...If the query only returns 1 line, the solution provided by Marcus Adams works fine. But, if the query only returns one line, you dont need to preset the id in order to update. Just update it:
update records
set hits = hits + 1
where type = '1'
and name = 'test'
Second...If the query will not return only one record and you want to update all records returned with same values or calculations, the same code above will do what you need.
Third, if the query does not return just one record and you need to update each record returned with different value then you need to have a different approach.
I think you are not designing your system very well. If the request for update come from outside, you should have the id to be updated as a parameter of your request. For example something like:
<html>
<body>
Test
</body>
</html>
And in your update.php you have something like:
<?php
$id = $_GET['id'];
$sql = "update records set hits = hits + 1 where type = '1' and name = 'test' and id = $id";
?>
Of course, the picture I have is to small. Probably you have a reason to do this way or this is just an example. If you fill us up with more info we might be more helpful.

How can I check if the values were changed after an update?

Assuming I do something like the following:
my $rows = $dbh->do("UPDATE MYTABLE SET amount=1200 WHERE id =123");
The $rows returns 1 even with the amount is already 1200. So it is considered an updated row.
My question is: Is there a way to check if an update actually changed the values in a row besides doing a query before the update?
Change the SQL query to:
UPDATE MYTABLE SET amount=1200 WHERE id = 123 AND amount <> 1200
The table will be identical, but it returns the number of rows that actually changed.
By default, DBD::mysql returns the number of rows matched in an UPDATE, not the number of rows physically changed. You can change this behavior by disabling mysql_client_found_rows in your call to connect:
my $dsn = "DBI:mysql:;mysql_client_found_rows=0";
my $dbh = DBI->connect($dsn, $user, $password);
Twinkles answer is correct, but you should create a statement handle using prepare and then execute most of your database queries.
In this case you would write
my $update_if_changed = $dbh->prepare('UPDATE mytable SET amount = ? WHERE id = ? AND amount != ?')
and subsequently
$update_if_changed->execute($amount, $id, $amount)

Mysql like search with more than one column

I have a drupal site with the search option. If user enters the search keyword, i need to compare that with more than one columns and display the records.
I have tried the following query
$search = 'test';
$sql_query = db_select('logoinfo', 'l')->fields('l');
$or = db_or();
$or->condition('search_field', '%'.db_like($search).'%','LIKE');
$or->condition('companyname', '%'.db_like($search).'%','LIKE');
$sql_query->condition($or);
$selectlogos = $sql_query->execute();
It displays all the records matching the search keyword with the order of auto increment Id asc.
But i want to display the records first which is having both search_field and companyname matches with the keyword, after that other records which is matches with either companyname or search_field. Please advise to achieve this.
Since orderBy requires a field name and can't order by an expression, you'll need to use addExpression to get an alias and then order by that alias. The expression in my example will return 0 if the value is not in both fields and 1 if it is in both fields. As far as I know this should be standard SQL, but it may vary on different database backends; so the expression may need to be adjusted depending on the database you are using.
<?php
$search = 'test';
$sql_query = db_select('logoinfo', 'l')->fields('l');
$or = db_or();
$or->condition('search_field', '%'.db_like($search).'%','LIKE');
$or->condition('companyname', '%'.db_like($search).'%','LIKE');
$sql_query->condition($or);
$safe_search = db_like($search);
$ex_alias = $sql_query->addExpression("l.search_field LIKE '%$safe_search%' AND l.companyname LIKE '%$safe_search%'");
$sql_query->orderBy($ex_alias, 'DESC');
$selectlogos = $sql_query->execute();
?>

Selecting a MySql table

I have a situation where I am able to choose from multiple tables in a MYSQL database. At any given time I only need to access one table.
Can I put the name of the table inside a variable and then set that within the query? Such that when I want to change the table, I only need to update a variable?
I am thinking kind of like this:
Instead of:
$order = "SELECT * FROM 2FieldForm ORDER BY ID";
do this:
$table = mysql_select_table("2FieldForm");
$order = "SELECT * FROM $table ORDER BY ID";
Now I am not sure if mysql_select_table is even valid, but I hope it gets the idea across!
Thanks in advance!
The SQL is simply a string, so have the table name inside a variable and execute the query using mysql_query()
$table_name = "users";
$order = "SELECT * FROM `".$table_name."` ORDER BY `ID`;";
mysql_query($order) OR DIE(mysql_error());
Be sure to add quotes to your table name and field in order to make sure it's properly interpreted by the database. The semi-colon at the end isn't necessary, but helps.
$table = "2FieldForm";
$order = "SELECT * FROM `$table` ORDER BY ID";

Perl and MySQL - Return a field from last row of a table using DBI possibly with last_insert_id?

I am trying to return a members firstname field from the table users from the last row of users.
my $dbh = DBI->connect($dsn, $db_user_name, $db_password) or die "$DBI::errstr";
my $LastID = $dbh->last_insert_id(`firstname`); ##but I want from table users
print qq~$LastID~;
This error is returned from above:
DBI last_insert_id: invalid number of arguments: got handle + 0, expected handle + between 4 and 5
Usage: $h->last_insert_id($catalog, $schema, $table_name, $field_name [, \%attr ])
So, what would be the "best" way (best being best for server, fastest, least memory, load, least amount of overhead.. whatever) to get the field firstname from the last row in the table users?
Realize my example above is not to be taken seriously as I have no idea how to do this without just doing something like my crude, but functional:
(p.s. UserID is NOT assigned by auto increment but, is in numeric order and a new user gets a higher UserID. Just the way this was when I tackled the pre existing problem.)
my $dbh = DBI->connect($dsn, $db_user_name, $db_password) or die "$DBI::errstr";
my $dsn = $dbh->prepare(qq{SELECT `firstname` FROM `users` ORDER BY ABS(UserID) DESC LIMIT ?,?});
$dsn->execute('1','1') or die "$DBI::errstr";
while(#nrow = $dsn->fetchrow_array()) {
$firstname = $nrow[0];
}
I assumed since I was using DBI that may provide the best solution but, I am inexperienced obviously and need some advice and guidance to learn the proper way to do this. Thanks for any assistance.
You mention that UserID is not auto incrementing, so I'm not sure if last_insert_id will work in this situation. It may, but I'm just not sure. The document states:
Typically this would be a value assigned by the database server to a
column with an auto_increment or serial type.
I would look to solve this by just using a SQL statement:
SELECT
u.firstname
FROM
users u
JOIN
(
SELECT
MAX(UserID) AS UserID
FROM
users
) t ON u.UserID = t.UserID
The code with DBI would then look like this:
my $stmt = 'SELECT u.firstname FROM users u JOIN(SELECT MAX(UserID) AS UserID FROM users) t ON u.UserID = t.UserID';
my $first_name = ($dbh->selectrow_array($stmt))[0];
last_insert_id method takes 4 args. Use like this:
my $id = $connection->last_insert_id(undef, 'myschemaname', 'mytablename', 'mycolumnname');
See the DBI pod.