PDO inserting and updating - mysql

So after my recent topic i learned about PDO. I'm trying my best to understand it and thats working to. But now the problem is that my new pdo script wont insert and update if exists in database. Now i'm asking it here because i'm a starter in PDO and i'm trying my best on it.
Now this is the code i'm using.
$db->prepare(
'INSERT INTO track (`rsname`, `overallranknow`, `overalllevelnow`, `overallxpnow` )' .
'VALUES (' .$name. '. ' .$Overalln. ', ' .$Overall[1]. ', ' .$Overall2. ') '.
'ON DUPLICATE KEY UPDATE ' .
"rsname = ' .$name. '" .
"overallranknow = ' .$Overalln. ' " .
"overalllevelnow = ' .$Overall[1].' " .
"overallxpnow = ' .$Overall2. ' "
);
The code is like doing nothing now
-it is not inserting into the database.
-it is not updating into the database.
Also my database connect file is this
<?php
$config['db'] = array(
'host' => 'localhost',
'username' => '',
'password' => '',
'dbname' => ''
);
$db = new PDO('mysql:host=' . $config['db'] ['host'] . ';dbname=' . $config['db'] ['dbname'], $config['db'] ['username'], $config['db'] ['password'] );
Maybe i'm posting mutch question's here and i know but i want to learn it.
~Kev (bad english = sorry)

A prepared statement needs to be executed in order to actually hit the database.
You should adjust it to look more like this:
$sth = $db->prepare(
'INSERT INTO track (`rsname`, `overallranknow`, `overalllevelnow`, `overallxpnow` )' .
'VALUES (:name, :Overalln, :Overall1, :Overall2) '.
'ON DUPLICATE KEY UPDATE ' .
"rsname = :name" .
"overallranknow = :Overalln" .
"overalllevelnow = :Overall1" .
"overallxpnow = :Overall2"
);
$sth->execute(array('name' => $name, 'Overalln' => $Overalln, 'Overall1' => $Overall[1], 'Overall2' => $Overall[2]));

Related

How use between cakephp

it does not return any error but neither any row but if there are fields but it does not collect them, which may be failing the query
$tarea = $this->Signs
->find('all', [
'conditions'=> array(
'date_inicio BETWEEN "' .
$horaInicio->format('Y-m-d H:i:s') .
'" and "' .
$horaFin->format('Y-m-d H:i:s') .
'"'
)
])
->where([
'user_id' => $horario->user_id,
'date_fin IS NOT' => null
]);
This works if I remove the condition between, but if I put it it doesn't give an error but it doesn't return anything.

Spaces in text stored as underscore in MySQL

I am storing text in MySQL by sending a request to a url with a function.
The url is encoded with %20 as spaces which is all very well but when it is stored in MySQL the spaces are replaced with underscore _ .
This is a sentence -> This_is_a_sentence.
Is there a way of avoiding this issue?
This is the code:
function new_experiment_reply($thread_title = '', $raven_thread_id = '', $text = '', $forum_url = '', $raven_forum_id = '')
{
$email = $this->session->userdata('email');
$query = $this->db->query("SELECT id FROM fn_users WHERE email='" . $email . "'");
$fn_user_id = $query->first_row()->id;
$query = $this->db->query("SELECT username FROM forum_users WHERE fn_user_id='" . $fn_user_id . "' AND raven_forum_id='" . $raven_forum_id . "'");
$username = $query->first_row()->username;
$date = date("Y-m-d H:i");
$query = $this->db->query('INSERT INTO promo_replies(thread_title, raven_thread_id, text, forum_url, raven_forum_id, date, fn_user_id, username) VALUES("'. $thread_title .'", "'. $raven_thread_id .'", "'. $text .'", "'. $forum_url . '", "'. $raven_forum_id . '", "'. $date . '", "'. $fn_user_id . '", "'. $username . '") ');
}
The inserted value of variables (as they are seen in Fiddler and as they should be):
$thread_title= Facebook%20vs%20Google
$raven_thread_id = 123441
$text = This%20is%20a%20sentence
$forum_url = domain.com
$raven_forum_id = 32
After echoing the query I got the following results:
INSERT INTO promo_replies
(thread_title, raven_thread_id, text, forum_url, raven_forum_id, date, fn_user_id, username)
VALUES
("Facebook_vs_Google", "123441", "This_is_a_sentence", "domain_com", "32", "2012-09-06 06:04", "8", "usssaa")
I am prepared to get bashed regarding the code so no worries there.

mySQL breaks when adding a var

I'm attempting to modify a mySQL query (that works) to return a more specific result. I've added a variable to the statement so that it looks for jobID AND UserName. Adding the $userName to the statement breaks it.
I've included the code below with the three variations of the SQL statement for comparison. I'm sure it's something obvious - to everyone but me...
Thanks in advance!
DB
// get all applicants from a User
public function GetAllMyApplications($from=false, $to=false, $user_name)
{
global $db;
$applicants = array();
if ($from >= 0 && $to > 0)
{
$sql_limit = ' LIMIT ' . $from .', ' . $to;
}
else
{
$sql_limit = '';
}
$user_name = "Bob Bobberton"; // reset this var for testing
$sql = 'SELECT * FROM '.DB_PREFIX.'job_applications WHERE job_id = '. $this->mJobId . ' ORDER BY name ASC ' . $sql_limit; // This was the original SQL that worked
$sql = 'SELECT * FROM '.DB_PREFIX.'job_applications WHERE job_id = '. $this->mJobId . ' AND name = ' . $user_name . ' ORDER BY name ASC ' . $sql_limit; // Added "and" $user_name - it breaks
$sql = 'SELECT * FROM '.DB_PREFIX.'job_applications WHERE job_id = '. $this->mJobId . ' AND name = "Bob Bobberton" ORDER BY name ASC ' . $sql_limit; // Replace var with value "Bob Bobberton" and it works
$result = $db->query($sql);
while ($row = $result->fetch_assoc())
{
$applicants[] = array('id' => $row['id'],
'job_id' => $row['job_id'],
'name' => $row['name'],
'email_address' => $row['email_address'],
'message' => str_replace(array("\r\n", "\r", "\n"), "<br />", $row['message']),
'resume_path' => base64_encode($row['resume_path']),
'created_on' => $row['created_on'],
'ip' => $row['ip']);
}
if (isset($applicants))
{
return $applicants;
}else{
return("");
}
}
change this
' AND name = ' . $user_name . ' ORDER BY name ASC '
to
" AND name = '" . $user_name . "' ORDER BY name ASC "
and it will work
The solution provided by Satya is not enough. You should escape your inputs properly.
Assume your $username contains a " character. That will break your SQL statement. So you should use prepared statements or, at least, use the function mysql_real_string_escape().

Is there a way to find / replace a string across all tables in a mysql database?

I'm thinking this isn't possible without doing a dump, searching / replacing within the .sql file, and then reimporting it, but figured I'd ask anyway...
Basically, is there a way to search for "samplestring" within all of the fields, within all of the tables, within one database and replace it with "examplestring"?
I don't know of one. There especially isn't if you're willing/want to look at and modify column names and other non-data stuff.
If you don't have to do it very often, it's not that problematic.
mysqldump --username user --password pass database | sed 's/somestring/otherstring/g' | mysql -uroot -p
You can, but it requires using dynamic SQL (MySQL's Prepared Statements).
First, you need to get a list of the text based columns:
SELECT c.column_name, c.table_name
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.table_schema = your_db_name
AND c.data_type IN ('varchar') -- don't want to replace on an INT/etc
Then you need to iterate over that list to create the UPDATE statement(s)...
Here's a solution in PHP:
<?php
// edit this line to add old and new terms which you want to be replaced
$search_replace = array( 'old_term' => 'new_term', 'old_term2' => 'new_term2' );
//change the localhost,username,password and database-name according to your db
mysql_connect("localhost", "username", "password") or die(mysql_error());
mysql_select_db("database-name") or die(mysql_error());
$show_tables = mysql_query( 'SHOW TABLES' );
while( $st_rows = mysql_fetch_row( $show_tables ) ) {
foreach( $st_rows as $cur_table ) {
$show_columns = mysql_query( 'SHOW COLUMNS FROM ' . $cur_table );
while( $cc_row = mysql_fetch_assoc( $show_columns ) ) {
$column = $cc_row['Field'];
$type = $cc_row['Type'];
if( strpos( $type, 'char' ) !== false || strpos( $type, 'text' ) !== false ) {
foreach( $search_replace as $old_string => $new_string ) {
$replace_query = 'UPDATE ' . $cur_table .
' SET ' . $column . ' = REPLACE(' . $column .
', \'' . $old_string . '\', \'' . $new_string . '\')';
mysql_query( $replace_query );
}
}
}
}
}
echo 'replaced';
mysql_free_result( $show_columns );
mysql_free_result( $show_tables );
mysql_close( $mysql_link );
?>
Source

MySQL MAX_JOIN_SIZE errors

I am asking this question on behalf of a small group of my users that have this problem.
Once the script they are using gets to the 21st ID, it generates the following error:
The SELECT would examine more than
MAX_JOIN_SIZE rows; check your WHERE
and use SET SQL_BIG_SELECTS=1 or SET
SQL_MAX_JOIN_SIZE=# if the SELECT is
okay
I have researched this as much as possible and found something of an answer : http://dev.mysql.com/doc/refman/5.0/en/set-option.html
The problem is that they are on shared hosting so they cannot change their MySQL settings to fix the errors.
Is there anything I can write into my script so that they do not have this problem?
This is the function that generates the database query based on which modules are loaded:
$sql = 'SELECT a.id as id , a.address as address';
$query = 'SELECT'
. ' name AS module_name'
. ', databasename AS module_database'
. ', pregmatch AS module_pregmatch'
. ', pregmatch2 AS module_pregmatch2'
. ', html AS module_html'
. ', sqlselect AS database_sqlselect'
. ', sqljoin AS database_sqljoin'
. ', sqlupdatewithvalue AS database_sqlupdatewithvalue'
. ', sqlupdatenovalue AS database_sqlupdatenovalue'
. ' FROM #__aqsgmeta_modules'
. ' WHERE enabled = 1'
. ' ORDER BY id';
$db->setQuery($query);
$results = $db->loadObjectList();
if (count($results) != 0) {
foreach ($results as $result) {
$sqlselect .= ', ';
$sqlselect .= $result->database_sqlselect;
$sqljoin .= ' ';
$result->database_sqljoin = preg_replace('/\{DATABASENAME\}/Ui', $result->module_database, $result->database_sqljoin);
if (!(preg_match("/" . $result->database_sqljoin . "/Ui", $sqljoin)))
$sqljoin .= $result->database_sqljoin;
}
}
if ($use_sh404sef)
$sqlselect .= ', g.oldurl AS sefurl';
$sql .= $sqlselect;
$sql .= ' FROM #__aqsgmeta_address AS a';
$sql .= $sqljoin;
if ($use_sh404sef)
$sql .= ' LEFT JOIN #__redirection AS g ON g.newurl = a.address';
$sql .=
//. ' WHERE a.id IN (' . $cids . ')'
' WHERE a.id = ' . $id
. ' ORDER BY a.address asc,a.id '
;
$db->setQuery($sql);
$rows = $db->loadObjectList();
MAX_JOIN_SIZE is a safety catch commonly used on the shared hostings.
It won't let you accidentally run long queries which would hang the server.
Issue this command:
SET SQL_BIG_SELECTS = 1
before running the query you know to return lots of values.
The MAX_JOIN_SIZE gets hit when MySQL calculates the Cartesian product of a join, not the actual expected records back. Therefore, if you're joining a massive table to another massive table, this will creep up. Use indexes and views to pare down the possible table hits if it's really that large.
See more here: MySQL - SQL_BIG_SELECTS