In a worker shift monitoring/accounting system I've built, there is an option to delete Staff Members. This works fine but I would like to archive shifts for staff members who are deleted.
I looked into it and it seemed the best way to do this would be to update my shift table, before the delete, into another table. I looked up how to do this via another Stack Overflow post however I'm getting an error: fatal error call to member function on a non-object.
Based on what I can find, this error is caused when you try to pass a null value, which has left me confused as the value I'm trying to pass is a GET and is working fine when I test it.
$sql = "
UPDATE table_archive
SET table_shift.shift_date = table_archive.shift_date,
table_shift.start_time = table_archive.start_time,
table_shift.end_time = table_archive.end_time,
table_shift.total_hours = table_archive.total_hours,
table_shift.rate_of_pay = table_archive.rate_of_pay,
table_shift.uniqueid = table_archive.uniqueid,
table_shift.addedBy = table_archive.addedBy,
table_shift.paidRate = table_archive.paidRate,
table_shift.totalPaid = table_archive.totalPaid
FROM table_shift, table_archive
WHERE table_shift.uniqueid = ?
";
$stmt = $connection->prepare($sql);
$deleteid = htmlentities($_GET['id']);
$stmt->bind_param('s', $deleteid);
$stmt->execute();
I'm stuck as to why this wont pass, the GET cant be a null value as the test delete I'm using at the moment passes the same variable and works fine. mysqli_query($connection,"DELETE FROM table_staff WHERE uniqueid='$deleteid'")
It may be that I'm using the SQL code wrongly or there is some silly thing I've forgotten but this has me stumped. Failing to fix this code, any other suggestions as to how to achieve the intended function are welcome.
You can't UPDATE FROM. Your syntax is wrong.
Instead, use this:
INSERT INTO table_archive
SELECT * FROM table_shift WHERE table_shift.uniqueid = ?
Is the use of bindParam correct?
If you use a ? it should look like this:
SELECT ...
WHERE column_name = ?
$sth->bindParam(1, $value_in_php, PDO::PARAM_INT);
If it's not ? but :param_name use this:
SELECT ...
WHERE column_name = :param
$sth->bindParam(':param', $value_in_php, PDO::PARAM_INT);
Your error sounds not like an SQL error, but a PHP error.
And if you want to update the table_archive table the SQL doesn't look correct. It should imho be like this:
UPDATE table_archive
SET table_archive.shift_date = table_shift.shift_date
, to_table_that_should_be_updated = from_table_with_value_to_update
FROM table_shift
WHERE table_shift.uniqueid = ?
Related
The last time I have posted a question about searching JSON data using PHP. After testing the script I wanted to try something else. Using MySQL to search through the data. Since it is faster than looping everything using a PHP script.
I was writing the script in PhpMyAdmin and that has generated the next PHP script for me. But somewhere there is a bug (sad)
"SELECT *
FROM `bigtree_pages`
WHERE `resources` like \'%\"XNCatDesc\": \"%?%\' and `resources` like \'%\"Brand\": \"%?%\' and `resources` like \'%\"ItemDesc\": \"%?%\'"
I want to give three values. The Categorie, the brand, and the ItemDesc (the name). But this throws an error.
You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near '\'%"XNCatDesc": "%'41'%\' and resources like \'%"Brand":
"%'none'%\' and `reso'
To be honest, I don't really know where I have to put my % sign.
For example. I have this in my JSON "Brand": "Bullet",
The value needs to be Brand (since we are searching on the Brand) and the brand is Bullet. What is the best way to write this query?
To use a parameter inside a LIKE expression in a prepared query, you need to form the entire expression and use that as the parameter. Otherwise you run into issues as you have with the insertion of quotes into your value. If you are using mysqli, try something like this (assuming your connection is called $conn and the values you want to search for are called $categorie, $brand and $itemdesc):
$stmt = $conn->prepare("SELECT *
FROM `bigtree_pages`
WHERE `resources` like ? and `resources` like ? and `resources` like ?");
$search_categorie = "%\"XNCatDesc\": \"%$categorie%\"";
$search_brand = "%\"Brand\": \"%$brand%\"";
$search_itemdesc = "%\"ItemDesc\": \"%$itemdesc%\"";
$stmt->bind_param("sss", $search_categorie, $search_brand, $search_itemdesc);
$stmt->execute();
However the problem you will run into is that because of the % surrounding the search values (e.g. $brand) in the query, when searching for brand = X you could match for example
"Brand": "Y", "Other Value": "contains an X"
So instead you should use regular expressions e.g.
$stmt = $conn->prepare("SELECT *
FROM `bigtree_pages`
WHERE `resources` rlike ? AND `resources` rlike ? AND `resources` rlike ?");
$search_categorie = '"XNCatDesc":[[:space:]]+"[^"]*' . $categorie;
$search_brand = '"Brand":[[:space:]]+"[^"]*' . $brand;
$search_itemdesc = '"ItemDesc":[[:space:]]+"[^"]*' . $itemdesc;
$stmt->bind_param("sss", $search_categorie, $search_brand, $search_itemdesc);
$stmt->execute();
If you are running MySQL 5.7 or later, this is better done using the inbuilt JSON_EXTRACT function:
$stmt = $conn->prepare("SELECT *
FROM `bigtree_pages`
WHERE JSON_EXTRACT(`resources`, '$.XNCatDesc') LIKE ? and
JSON_EXTRACT(`resources`, '$.Brand') LIKE ? and
JSON_EXTRACT(`resources`, '$.ItemDesc') LIKE ?");
$search_categorie = "%$categorie%";
$search_brand = "%$brand%";
$search_itemdesc = "%$itemdesc%";
$stmt->bind_param("sss", $search_categorie, $search_brand, $search_itemdesc);
$stmt->execute();
I'm using CakePHP 3, I need to run a raw SQL query on multiple tables. In CakePHP 2, this could be done by using the query() method on any model ( $this->Messages->query("select..") ).
I need the method that allows me to run a SQL query in CakePHP 3. Following is the code snippet I'm using:
$aumTable = TableRegistry::get('Messages');
$sql = "SELECT (SELECT COUNT(*) FROM `messages`) AS `Total_Count`,
(SELECT COUNT(*) FROM `messages_output`) AS `Total_Output_Count`,
(SELECT COUNT(*) FROM `messages_output` WHERE `is_success`=1) AS `Total_Successful_Output_Count`,
(SELECT COUNT(*) FROM `messages_output` WHERE `is_success`=0) AS `Total_Error_Output_Count`,
(SELECT COUNT(*) FROM `users`) AS `Total_User_Count`;";
// to run this raw SQL query what method should i use? query() doesn't work..
// $result = $aumTable->query($sql); ??
// $result = $aumTable->sql($sql); ??
If you can provide links to CakePHP 3 model documentation where I can find this info, that would be helpful too. I tried searching on google but could only find questions related to CakePHP 2.
First you need to add the ConnectionManager:
use Cake\Datasource\ConnectionManager;
Then you need to get your connection like so:
// my_connection is defined in your database config
$conn = ConnectionManager::get('my_connection');
More info: http://book.cakephp.org/3.0/en/orm/database-basics.html#creating-connections-at-runtime
After that you can run a custom query like this:
$stmt = $conn->execute('UPDATE posts SET published = ? WHERE id = ?', [1, 2]);
More info: http://book.cakephp.org/3.0/en/orm/database-basics.html#executing-queries
And then you are ready to fetch the row(s) like this:
// Read one row.
$row = $stmt->fetch('assoc');
// Read all rows.
$rows = $stmt->fetchAll('assoc');
// Read rows through iteration.
foreach ($rows as $row) {
// Do work
}
More info: http://book.cakephp.org/3.0/en/orm/database-basics.html#executing-fetching-rows
The documentation for this is here: http://book.cakephp.org/3.0/en/orm/database-basics.html#executing-queries
But what's not written there is how to execute it. Because it cost me a while, here is the solution for that:
1.You need to add
use Cake\Datasource\ConnectionManager;
2.init the ConnectionManager (as mentioned above)
$conn = ConnectionManager::get('my_connection');
3.Execute your SQL with something like this
$firstName = $conn->execute('SELECT firstname FROM users WHERE id = 1');
The question is already very old, but I still find it frequently.
Here is a solution for CAKEPHP 3.6 and (short) for newer PHP Versions.
It is not necessary to use the ConnectionManager get function and often it does not make sense, as the connection name may not be known at all. Every table has its / a connection which one can get with getConnection ().
If you are already in the Messages Table (src/Model/Table/MessagesTable.php), you can simply use the Connection
$con = $this->Messages->getConnection();
If you are not there (what your code would suggest with TableRegistry::get(), you can do that with this table as well
// $aumTable is declared in question
$con = $aumTable->getConnection();
then you can execute a RAW query as shown above:
$result = $con->execute ();
// short
$result = $this->Messages->getConnection()->execute ('Select * from ...')
// or ($aumTable is declared in question)
$result = $aumTable->getConnection()->execute ('Select * from ...');
I try to update a row in a database, but I can't do that. Here is my sql:
$sql = "UPDATE `voting_nomination_counter`
SET `quantity`=quantity+1
WHERE `nid` = '$nid'
AND nominee = '$nominee'";
I suspect the problem is here - AND nominee = '$nominee'"; because when I remove this from the query all works and updates fine. Help, please.
Try this:
$sql = "UPDATE voting_nomination_counter SET quantity=quantity+1 WHERE nid = '$nid' AND nominee = '$nominee'";
I solve this problem, if I want to update WHERE string = string I just need to use this statement UPDATE table SET field = REPLACE(field, 'string', 'anothervalue') WHERE field LIKE '%string%';, thanks guys!)
#excluded_once Looks like you were able to solve your issue. So in future do not ever use variable names directly into SQL string. Always use db_query or db_select and then always bind the variables into SQL, it will help you prevent from SQL injections and other attacks.
How would i get the rowID for an update query (i am of course not updating by rowID)
The below code is what i am using (as a public function within a Class), but of course using "lastInsertId()" is not working for me (i didnt really expect it to work and it returns 0)
$query = "UPDATE tSecurityDepositPaymentAddresses
SET
tGuardians_GuardianID = ?
WHERE tGuardians_GuardianID = 0
LIMIT 1";
$stmt = $db->prepare($query);
$stmt->execute(array($GuardianID));
return $db->lastInsertId();
Could i combine the update query within a nested select? or is there a simpler way?
sorry if my question sounds bumb, but im still learning...
Thanks
Thanks for previous replies
I am execution "select Name from table_name where id=1"; . i saw some tutorials for getting data from the database, they mentioned $DB = new Zend_Db_Adapter_Pdo_Mysql($params);
DB->setFetchMode(Zend_Db::FETCH_OBJ); and the result will getting through $result = $DB->fetchAssoc($sql); This $result is an array format, i want to get only name instead of getting all the data from the database. I am new to this topic. if i made any mistake pls do correct.
try this:
$result = $DB->fetchOne("SELECT name FROM table_name WHERE id=1");
This code will execute your query through doctrine getServiceLocator(). With the help of createQueryBuilder(), you can write your query directly into zend-framework2, and with setParameter, any desired condition would be set easily.
$entityManager = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
$qb = $entityManager->createQueryBuilder();
$qb->select(array(
'TableName.columnName as columnName '
))
->from('ProjectName\Entity\TableName', 'TableName')
->where('TableName.TableId = :Info')
->setParameter('Info', $id);
$var= $qb->getQuery()->getScalarResult();
The $var variable holds the value for which, you wanted the comparison to be made with, and holds only the single values of your interest.