medoo select term doesn't work correct - mysql

I have the debug modus on and get this
mySQL string:
SELECT "dmd_key","id"
FROM "keys"
WHERE "dmd_key" = '140ec37b981042c8549b07d6d4589295'
AND "website" = 'test.de'
But that string doesn't work for me. I get a database error message. (the standard message..)
If I change my string into this:
SELECT `id`,`dmd_key`
FROM `keys`
WHERE `dmd_key` = '140ec37b981042c8549b07d6d4589295'
AND `website` = 'test.de'
I get results.
I think I have to change something in my settings but I don't know what.
It is my first time with medoo and I think medoo doesn't love me...
Thanks for your help.

This appears to be a problem within Medoo. You're not the only person seeing the issue (1,2). According to this bug report, Medoo creates mySQL code that escapes table names with double quotes, and then changes a mySQL option to cater for it:
case 'mysql':
// Make MySQL using standard quoted identifier
$commands[] = 'SET SQL_MODE=ANSI_QUOTES';
This option seems to be disabled on your web host, rendering Medoo unusable in your environment.
It's tough to put in words how insane this is. A framework should generate SQL that is compatible with the database it runs on. I would switch to a different framework.

SET SQL_MODE=ANSI_QUOTES becomes invalid if MySQL restarts and needs to execute it again.
Or you can goto your medoo.php and update functions to use backticks as below:
protected function table_quote($table)
{
return '`' . $this->prefix . $table . '`';
}
protected function column_quote($string)
{
preg_match('/(\(JSON\)\s*|^#)?([a-zA-Z0-9_]*)\.([a-zA-Z0-9_]*)/', $string, $column_match);
if (isset($column_match[ 2 ], $column_match[ 3 ]))
{
return '`' . $this->prefix . $column_match[ 2 ] . '`.`' . $column_match[ 3 ] . '`';
}
return '`' . $string . '`';
}

Related

Updating user profile efficiently

Something just came to mind and I'd like to bounce it off:
Say you have a user profile, with 10 fields that the user can edit, and not all of them are required. When issuing update commands, is it more efficient to either:
A) Collect all of the fields, filled in or not, and issue one all encompassing update statement to the server's DB
or
B) Use client side validation to check to see which fields have been filled out or changed, and have a selection of SQL methods that only send and update these fields
or
C) Create groupings, like "updateRequiredFields(...) and updateExtraFields(...)", which would issue one smaller transfer if the changes only belong in one group, however two transfers if both are edited
General consensus? Clearly option B is the far more verbose approach, I'm just wondering if it's worth coding it all out or if it'll actually make a noticeable impact on the server (think "scaled for big data").
You could do something like this on your DB update function:
public function updateFields(array $fields) {
$updateQuery = array();
foreach($fields as $fieldKey => $fieldValue) {
//if $fieldValue is false, leave it unchanged
if ($fieldValue !== false) {
//NOTE: make sure you escape this or use PDO
$updateQuery[] = $fieldKey . '=' . $fieldValue;
}
}
$query = 'UPDATE UserInfo SET ' . implode(",", $updateQuery) . ' WHERE ...';
}
You just need to build $fields array based on what was modified on client side and then pass in with either new value or with false if no change.

Resource Link Indetifier using PDO?

(new to PDO and limited experience with DB's in general) :)
I'm switching over to use PDO in a project..
and even though the data was getting dumped to the DB..there was a strange 'Warning'.. that displayed merging of table I was trying to use..(and another I wasnt)... SELECT()..etc even though I was trying to INSERT()..etc..
using the NON-PDO approach worked fine however (which seems a bit odd)..
example:
include("../_include/db_forms.php");
mysql_query("INSERT INTO $tablename (timestamp, fullname, email, formcode, ipaddress, alldata) VALUES ('" . date("YmdHis") . "','" . mysql_real_escape_string($_POST['name']) . "','" . mysql_real_escape_string($_POST['email']) . "','" . $formcode . "','" . $_SERVER['REMOTE_ADDR'] . "','" . mysql_real_escape_string($allData) . "')");
^ no warning/data dumps to DB just fine
after searching/asking around a bit... it looked like another open database connection for the CMS (for other aspects of the page/header/footer include files..etc) is being used for the other queries, (or vice versa).. and this is causing the warning/problem.
I was told adding a resource link identifier would solve this...
now I understand what it is.., and why it is used (multiple DB's.. this is a reference to what one should be used/opened..etc.)
However.. I'm not exactly sure HOW to implement one.. especially using PDO approach.
here is my PDO approach/code:
require_once("../_include/db_pdo_fulllog.php"); //just a .php file with DEFINE()'s for DB connection details
// new DB routine PDO approach //
$sql = "INSERT INTO $tablename (timestamp, fullname, email, formcode, ipaddress, alldata) VALUES (?,?,?,?,?,?)";
try {
$conn = new PDO("mysql:host=" . DBSERVER . ";dbname=" . DBNAME, DBLOGIN, DBPASSWORD);
$stmt = $conn->prepare($sql);
//$stmt = $conn->prepare("INSERT INTO fulllog(timestamp, fullname, email, formcode, ipaddress, alldata) VALUES (?,?,?,?,?,?)");
//timestamp
$ts = date('Y-m-d H:i:s');
$stmt->bindParam(1, $ts);
//name
$stmt->bindParam(2, $_POST['name']);
//email
$stmt->bindParam(3, $_POST['email']);
//formcode
$stmt->bindParam(4, $formcode);
//ip address
$stmt->bindParam(5, $_SERVER['REMOTE_ADDR']);
//all data
$allData = $_POST['session_title'] .' '. $_POST['session_type'] .' '. $_POST['description'] .' '. $_POST['goals'] .' ' . $_POST['faculty'] .' '. $_POST['chapter'];
$stmt->bindParam(6, $allData);
//execute built statement
$stmt->execute();
}
catch(PDOException $e) {
echo $e->getMessage();
die;
}
How can I add a resource link identifier to this...to stop the warning/error of having the multiple databases in use?
Thanks.
edit:
(since its been requested)
the error/warning message:
Warning: mysql_fetch_row() expects parameter 1 to be resource, boolean given in /usr/www/users/xxxxorg/xxxx.org/admincms/_includes/class.now_cms.php on line 126
Err (Table 'xxxx_forms.fulllogContent' doesn't exist) in query: SELECT n.NodeName, n.ContentId, n.ParentId, n.NodeOrder, n.ParentNode, n.ContentTitle, n.ContentType, n.Status, n.ShowOnNav, n.ShowNav, n.ShowOnSitemap, n.ForceSSL, n.TargetWindow, n.ResourceUrl, n.ShortTitle, n.Keywords, n.Description, n.CCount, n.COrderField, n.COrder, COALESCE(t.TemplateBody, dt.TemplateBody) as Template, COALESCE(ct.TemplateBody, dt.TemplateBody) as ChildTemplate, n.UserGroups, n.Comments, n.Sticky, IF(md.MetaId IS NULL, 0, 1) as HasMetaData FROM fulllogContent n LEFT JOIN fulllogTemplate t ON n.Template=t.TemplateId LEFT JOIN fulllogTemplate ct ON n.ChildTemplate=ct.TemplateId LEFT JOIN fulllogTemplate dt ON dt.TemplateId=dt.TemplateId AND dt.Status=2 LEFT JOIN fulllogSection s ON n.SectionId=s.SectionId LEFT JOIN fulllogMetaDefine md ON s.SectionId=md.SectionId WHERE n.Status=1 AND n.PubDate <= NOW() AND (n.ExpDate >= NOW() OR n.ExpDate = '0000-00-00 00:00:00') ORDER BY CONCAT(IF(n.ParentId=0, '', '/'), n.ParentNode), n.NodeOrder
Again.. my table is -not- 'xxxx_forms.fulllogContent' but in fact: 'xxxx_forms.fulllog'
and most of the other stuff doesnt even apply to my table/DB either.. (nor am I doing a SELECT.. I'm doing an INSERT)..
SO it (somehow) still has the CMS database open/in use.. and is getting merged/mixed up with the one I want.
To re-iterate.. the data IS being dumped to the DB... but the page doesnt refresh/resolve and shows this warning/error..
PDO object IS such a "link identifier" itself - so, you don't need anything else.
Therefore, your problem is not connected to PDO.
To get help on a particular error message you have to post this particular message whole and exact, instead of describing it in vague terms.
Solution to fix this seemed to be changing the define() constant names to be unique/different from the constant names the other connection was using. Thanks for the feedback

Mysql delete query won't work on lamp stack

I am doing a project work on php. During my work every single query work smoothly. But when I want to delete any object using it won't delete ...
Here's my php code
<?php
//delete item
if(isset($_GET['deletecat'])){
$id_to_delete = $_GET['deletecat'];
$sql = mysql_query("DELETE FROM `category` WHERE `Category_id`=$id_to_delete LIMIT 1") or die('Error: Could not delete.');
}
else{
header('location: category.php');
exit();
}
?>
and after that I only get the error message.
GET value is OK. And on my phpmyadmin this SQL running OK. But there's a pop up message appear when I want to delete any object. what can I do now?
there's a few layers where you could be having issues: with the db connection, the query, or the data which you are sending.
also, you are not filtering for " and ' marks so you could be in trouble there, and you're not ensuring that your id is a number so your sql could also be failing there.
but, you can figure that out with a few adjustments to your code.... you can insert some diagnostics into your code to see what mysql is reporting the error as and get a better idea of how to fix it.
note that it is [generally recommended][1] to use mysqli extension instead of mysql extension, but irregardless, here's sample code with the extension you are currently using
hope this helps!
<?php
if ( isset($_GET['deletecat'])) {
#dbh -> database resource.
$dbh = mysql_connect()
#mysql_connect returns false if it fails. capture error and echo to output.
if (!$dbh) {
die("Could not connect to database server: ".mysql_error()."\n");
#if using mysqli use mysql_connect_error() instead
}
#never trust input. use an escape function.
$id_to_delete = mysql_real_escape_string($_GET['deletecat'],$dbh);
#force $id_to_delete to be treated as a number, or make it safer in your sql.
#i used the latter method below.
$sql = "DELETE FROM `category` WHERE `Category_id` = '$id_to_delete' LIMIT 1");
#mysql_query returns false on failure
$result = mysql_query($sql,$dbh);
#on failure catch the error and display the exact contents of 'deletecat' in a web-friendly way.
if (!$result) {
$error=mysql_error($dbh);
die ("Error: Could not delete '"
.htmlentities(print_r($_GET['deletecat'],true)).". Error: $error\n"
);
}
#if we did not trigger die() above we are ok.
header('location: category.php');
exit();
}
?>
:
[1]: see warning at http://php.net/manual/en/function.mysql-connect.php
You should escape the GET variable first to avoid any SQl injection attacks as already said by deceze. Then, you should understand that the message given by phpmyadmin is a confirmation if you need to execute the delete query. you can use mysql_real_escape_string($value) to escape but as php vendor says, this function will be removed very soon and is currently deprecated.
bye..

"Unknown column in 'field list'", but column does exist

DROP TABLE IF EXISTS `transactions`;
CREATE TABLE `transactions` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`purchase_date` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `transactions` (`purchase_date`) VALUES (NULL)
I've isolated my problem in this code. When I run it, I get the error:
[ERROR in query 3] Unknown column 'purchase_date' in 'field list'
Anyone an idea?
There is an unprintable character 30 (RecordSeparator) inserted between purchase_date and the ' in the INSERT statement. Just remove the text ('purchase_date') and rewrite it by hand it should be fine.
Nery niche solution when I got this error.
I had a BEFORE INSERT trigger on my table that did something with
NEW.`field_mysql_doesnt_think_exists`
and if I didn't pass that field to an insert statement then I would get
[ERROR in query 3] Unknown column 'field_mysql_doesnt_think_exists' in 'field list'
I just spent the better part of a day figuring this out. My problem was the same: invisible characters kiboshing the query and returning the "unknown column" error.
I solved it by wading back into Windows and removing the garbage using NotePad++.
How did the garbage get in there in the first place? I think it was because I made the mistake of copying some long complex queries into LibreOffice Writer (my functional specs document) instead of just bookmarking them in phpMyAdmin or saving them in a text editor. Pasting them from LibreOffice into the query window is where (I think) the garbage originated.
Once there, it persisted like Malaria. I couldn't even get rid of it by hand-retyping the whole query -- I had to put it into NotePad++ (Encoding menu) and show ANSI and the UTF8 combos and then remove the garbage by hand.
Once that was done, the query worked.
This can also happen if you paste a column name when building the table structure. Same error - but the unprintable/invisible characters are in the table structure, not the query.
I have had the same issue this morning and I didn't find my answer.
But I found my problem when I changed the single quotes around my query to double quotes. Something so small and an oversight can cause a real headache.
Unknown column x in "field list" - Code below wrapped in single quotes - Non working.
$likepost='INSERT INTO reaction(reaction_num,userreaction_id,timereacted,
streamitem_id,comment_posted_on)
VALUES ($reaction,$target,NOW(),$streamid,$comment_id)';
Code below wrapped in double quotes. working
$likepost="INSERT INTO reaction(reaction_num,userreaction_id,timereacted,
streamitem_id,comment_posted_on)
VALUES ($reaction,$target,NOW(),$streamid,$comment_id)";
This might not help anyone else, but adding this "just in case" it helps someone.
I receive large datasets as Excel CSV files and use a (WIL) script to convert the .csv file into an importable .sql file.
I had an error in my conversion script whereby these two lines did not reference the same table name (I had hard-coded the first location and forgot to update it):
* "INSERT INTO `old_table_name` (`cid`, `date`, etc etc"
* "CREATE TABLE IF NOT EXISTS `":_dbName:"` (etc etc "
I just changed the first line to also get the table name from the variable, and voila!
* "INSERT INTO `":_dbName:"` (`cid`, `date`, etc etc"
So check those two lines in your import SQL file.
Same error in a different scenario:
This also happens when you miss # symbol for a variable.
SET #myVar1=1; SELECT #myVar1; -- GOOD, correctly prints: 1
SET #myVar1=1; SELECT myVar1; -- BAD, prints: Unknown column 'myVar1' in 'field list'
when you want to work with mysql using a function like this:
function insert($table, $info_array){
// implode keys as columns by [`,`] glue string
$columns = implode("`,`", array_keys($info_array));
// implode values as sql ready values by [','] glue string
$values = implode("','", array_values($info_array));
// make query(careful about [`] for columns name and ['] for values)
$sql = "INSERT INTO ".$table." (`".$columns."`) VALUES ('".$values."');";
return $sql;
}
you should be careful about [ ` ] for table columns names and [ ' ] or [ " ] for values.
for example, I used above function this way:
try{
$db_insert_sample_user = $connection->query(insert(TABLE_PREFIX."users", [
"username" => "my_name_2",
"password" => md5("how457fty")
]));
echo '<pre>';
print_r($db_insert_sample_user);
echo '</pre>';
}catch (PDOException $exc){
echo '<pre>';
print_r($exc);
echo '</pre>';
}
the query string is this:
INSERT INTO php_pdo_users (`username`,`password`) VALUES ('my_name_2','ee04708d313adf4ff8ba321acf3eb568');
and the result was like : (for two users)
PHPMyAdmin Result
if you want functions based on prepared statements, test this : (placeholders, params and values, don't need [ ' ] or [ " ] at all!!!)
function insert_prepared(PDO $connection, $table, $info_array){
// columns
$columns = implode("`,`", array_keys($info_array));
// placeholders
$place_holders = [];
for ( $i = 0; count(array_keys($info_array)) > $i; $i++){
$place_holders[] = '?';
}
// convert placeholders to query string
$place_holders_str = implode(",", $place_holders);
$prepared_stmt = "INSERT INTO ".$table." (`".$columns."`) VALUES (".$place_holders_str.");";
// prepare statement
$stmt = $connection->prepare($prepared_stmt);
// values
$values = array_values($info_array);
// bind all params to values
for($i = 0; count($values) > $i; $i++){
$stmt->bindParam($i + 1, $values[$i]);
}
// execute and return results
return $stmt->execute();
}
after code execution this way :
try {
$db_insert_sample_user = insert_prepared(
$connection,
TABLE_PREFIX . "users",
[
"username" => "my_name_4",
"password" => md5( "HelloDolly#__3" )
]
);
} catch ( PDOException $exc ) {
echo "Failed : " . $exc->getMessage();
}
results is :
Results with insert_prepared function
I was using a mysql procedure and in the procedure parameter I used phone with an extra space instead of phone with no extra space, due to this when ever I called the function. It just throw error no such column as phone . Until I miraculously spotted it and corrected it using phpMyAdmin, Error went off.
I had this same PYMYSQL error in my Python program when I found this answer.
I probably violated a Pandas rule when I created a new dataframe ...
This created same the error above: A phantom column
inddata = dat[['ind_id','iso3c','date','data']]
dat.to_sql(name='inddata', con=engine, if_exists='append', index=False, chunksize=200)
This fixed the error:
dat2 = dat[['ind_id','iso3c','date','data']]
inddata = dat2.copy()
dat.to_sql(name='inddata', con=engine, if_exists='append', index=False, chunksize=200)
Look at the name of the table you are handling

Iterate through MYSQL database and replace data in every record in one column

I have this VERY inefficient way of updating the phone numbers in my database after cleaning them of all non-digits.
$san_phone = mysql_query('SELECT * FROM table');
while ($row = mysql_fetch_array($san_phone)) {
$row['phone_clean'] = preg_replace('#[^\d]#', '', $row['phone']);
echo $row['id'] . ' - ' . $row['phone_clean'] . '<br>';
mysql_query("UPDATE table SET phone = " . $row['phone_clean'] . " WHERE id = " . $row['id']);
}
That update part of the loop is causing me to timeout after only about 400 of my 2,400 records. It's obvious I'm doing something wrong so be gentle when schooling me. ;)
First off, stop using mysql_ functions as they are being deprecated. Use mysqli_ or PDO functions instead.
The method you are using to UPDATE your records is inefficient. You should instead create a temporary table, INSERT the new records in a single query, and finally run an UPDATE query to replace the data.
You can start out with this:
$san_phone = mysql_query('SELECT id, phone FROM table');
$insertArray = array();
while ($row = mysql_fetch_array($san_phone)) {
$phone_clean = preg_replace('#[^\d]#', '', $row['phone']);
echo $row['id'] . ' - ' . $row['phone_clean'] . '<br>';
$insertArray[] = "(" . $row[id] . ", '" . $phone_clean . "')";
}
$insertQuery = "INSERT INTO tempTable (id, phone) VALUES ";
$insertQuery = implode(", ", $insertArray);
mysql_query($insertQuery);
I've made a quick demo to illustrate this process. t1 is your original table, and t2 is the temporary table that contains the data to replace.
See it in action
You could use something like this user-defined function:
http://www.mysqludf.org/lib_mysqludf_preg/index.php#PREG_REPLACE_SECTION
or https://launchpad.net/mysql-udf-regexp
And rewrite your query to:
UPDATE table
SET phone = PREG_REPLACE('#[^\d]#', '', phone);
Well, multiple calls to your database incurs a speed hit, and (in my experience), it's a painful one. Even two trips to the database can lead to a noticeable delay over one.
To get around this, you want to minimize the calls to your database, which means doing as much in one call as possible. To this end, try rewriting this as a single SQL update where your replacement logic is in SQL itself. That would mean only one trip to the database and a massive speed improvement.
That's easier said than done, since last I checked, MySQL didn't have a regular expression string replacement function. You could try a work-around, or see about some of the UDF's. Another answer provided a link for one. I recommend looking into that.