I have never asked anything on one of these before, I could usually
think of or find a way that was posted for ideas.
I tried ways I thought of, tried using a CASE example that looked like it should work and no go. It won't update in any case.
OK here is what I am trying to do:
$Mysqlinfo="INSERT INTO `$PNum` (P_IDNum, P_Name, Raw_Time, Total_Time, T_Mode)
VALUES ('$PersId', '$_POST[PersonaName]', '$Stats_Vals[1]', '$Stats_Vals[2]', '$Stats_Vals[5]')
ON DUPLICATE KEY UPDATE Car_Model='$Stats_Vals[1]', Total_Time='$Stats_Vals[5]', Raw_Time='$Stats_Vals[7]', T_Mode='$Stats_Vals[2]' (there was originally the "; at end here)
***WHERE Raw_Time > '$Stats_Vals[7]'";***
(There were more names there but I removed some so it was not sooo loong, so don't mind so much the $Stats_Vals numbers as the structure).
The thing works without the WHERE at the end except it always will INSERT or UPDATE, I know Where does not work with ON DUPLICATE KEY unfortunately so what is an easy equivalent?
It has to chk for the Val and do NOTHING if the condition is NOT True.
Oh yeah it is formatted for use in a PHP script. :0)
Thanks much for any help!
Edit - Here is most of the PHP/sql code without the condition I am trying to achieve, it is called by an application:
<?php
hostname and
database info here
Variables, $_POST... etc.
$link = mysql_connect($hostname, $username, $password);
if (!$link) {
die('Connection failed: ' . mysql_error());
}
else{
echo "Connection to Server successful!" . PHP_EOL; <for testing from web
}
$db_selected = mysql_select_db($database, $link);
if (!$db_selected) {
die ('Can\'t select database: ' . mysql_error());
}
else {
echo "Database successfully selected!". PHP_EOL;
$Mysqlinfo="INSERT INTO `$PNum` (P_IDNum, P_Name, Raw_Time, Total_Time, T_Mode)
VALUES ('$PersId', '$_POST[PersonaName]', '$Stats_Vals[1]', '$Stats_Vals[2]', '$Stats_Vals[5]')
ON DUPLICATE KEY UPDATE Car_Model='$Stats_Vals[1]', Total_Time='$Stats_Vals[5]', Raw_Time='$Stats_Vals[7]', T_Mode='$Stats_Vals[2]'";
if (!mysql_query($Mysqlinfo,$link))
{
mysql_close($link);
die('Error: ' . mysql_error());
}
}
mysql_close($link);
?>
it works except for not following the condition of only updating if Raw_Time is less.
Thanks again!
If you want to make the update conditional, then I'm afraid you can't do it with INSERT...ON DUPLICATE KEY UPDATE.... You'll have to do it in two or more queries. And in order to make it atomic, you'll have to use LOCK TABLES:
$primarykey = 'whatever';
query("LOCK TABLES mytable WRITE;");
$count = query("SELECT COUNT(*) FROM mytable WHERE id=?;", $primarykey);
if($count>0) // the ID already exists
{
$time = query("SELECT Raw_time FROM mytable WHERE id=?;", $primarykey);
if($time>$Stats_Vals[7])
query("UPDATE mytable SET ... WHERE id=?;", $primarykey);
}
else
query("INSERT INTO mytable ...");
query("UNLOCK TABLES;");
A couple of notes:
I'm calling some made up function query here because I don't know what method you're using to execute queries. I've also abbreviated some of the queries because I'm too lazy to copy all your code. You'll need to adjust the code according to your needs.
I've also used ? for parameters in the queries - this is good practice to prevent SQL injection.
The LOCK TABLES statement is there to ensure that no other process can delete the record you're working with between the time you check for the record's existence (SELECT COUNT(*)...) and the time you update. If that were to happen, your code will cause an error.
There is no single-query solution, you either have to retrieve the value of the Raw_Time column for the appropriate record (if exists) and evaluate that in your PHP script; or create a stored procedure for the task.
By the way, look out for security issues, like SQL Injection, when inserting values in your query given by the users.
Related
I'm looking to enter in a whole object of information. The data itself needs to be put into different tables so I'm using a mysqli_multi_query
Query
for($i=0;$i<$commLength;$i++){
$sql = "INSERT INTO
calinfo (Sbefore, Safter, A1, A2, CalGas, Factor, Zbefore, Zafter, Cbefore, Cafter, SysInfoID)
VALUES
('{$comm[$i]->ScB4}', '{$comm[$i]->ScA4}', '{$comm[$i]->A1}', '{$comm[$i]->A2}', '{$comm[$i]->CalGasA}', '{$comm[$i]->Factor}', '{$comm[$i]->ZB4}', '{$comm[$i]->ZA4}', '{$comm[$i]->CalB4}', '{$comm[$i]->CalA4}', '{$comm[$i]->CHNoID}');";
$sql .= "UPDATE
jobs
SET
CompletedBy = $tech
WHERE JobID = '{$comm[$i]->JobID}';";
if(!mysqli_multi_query($con,$sql))
{
die('Error: ' . mysqli_error($con));
}
else
{
$synctotal++;
}
}
I think I'm doing this wrong. All the data and values and being read correctly but I get this error code:
'Error: Commands out of sync; you can't run this command now'
Could someone point me in the right direction with this one please =)
Did you try running two sql queries as separate statements? rather than keeping them in 1 SQL string variable?
I going to create a website that can get as much as 6,000 alerts daily(those alerts containing up to 140-characters, that's approx. 30 words-tokens-). My question is if i have a function that verify if each token is already in the db, it false, do nothing, if true it get insert, and so on, but for each word it has to loop through the entire db for checking, how should i handle the connection? it is bad to open connections every time i need to check for a word?
function insertTag($tag){
$db = "test";
$user = "Eduardo";
$pass = "weaponx";
$host = "localhost";
$con = new mysqli($host, $user, $pass, $db);
$noInsert = false;
$result = $con->query("select TAG from TAGS");
$num_tags = $result->num_rows;
for($c=0; $c < $num_tags; $c++){
$row = $result->fetch_assoc();
echo "tag ". ($c+1) .": ". $row['TAG'] ."<br/>";
if ($fila['TAG'] === $tag){
echo "$tag: already exist.<br />";
$noInsert = true;
return;
}
else{
$noInsert = false;
}
}
if (!$noInsert){
$result2 = $con->query("insert into TAGS(TAG) values('$tag')");
echo "token $tag: inserted<br />";
}
}
$tags = "danger in detroit";
// insert word in the BD, only if new
for($i=0; $i < count($tags); $i++){
insertTag($tags[$i]);
}
should i use the mysqli version of persistent connection? if so how?
No no, don't do it that way :) Several points:
1) Open mysql connection at the beginning of your script, and do as many queries as you need without opening new connection for every query. (So opening connection need to be outside of your function)
2) You need to use indexes and mark your tag value in database as unique, in that case you can just INSERT every time, and if it is duplicate it will not get inserted. In order to create index for your table you need to use your favorite sql manager, or just do a query, you can read here more:
http://dev.mysql.com/doc/refman/5.0/en/create-index.html
But in short you need to make column that represents your tag name to be unique ('TAG' in 'TAGS' table), and you need to put your con->query statement inside a try catch block, as it will probably throw exception on duplicate and you need to handle that.
3) I think you are inserting wring values as tags, you are using letters instead of words, is it supposed to be like that?
4) your query look incorrect, does it work?
do something like this (obviously after you have added unique index to your table):
function insertTag($con, $tag){
try {
$con->query("INSERT INTO `TAGS` (TAG`) values('$tag')");
echo "token $tag: inserted<br />";
} catch (Exception $e) {
echo "token $tag: NOT inserted<br />";
}
}
$tags = "danger in detroit";
// will create array of words
$tags = explode(' ', $tags);
$db = "test";
$user = "Eduardo";
$pass = "weaponx";
$host = "localhost";
$con = new mysqli($host, $user, $pass, $db);
// insert word in the DB, only if new
for($i=0; $i < count($tags); $i++) {
insertTag($con, $tags[$i]);
}
Also, I think this might be even done with ONE INSERT query for all tags, but I am not 100% sure, need to check.
Connecting and disconnecting from the database is expensive; for performance, you want to avoid connection "churning".
(In our J2EE web servers, we implement connection pools which are a collection of validated database sessions. The applications can "churn" through the connection pool, retrieving and returning connections, but the actual database session stays connected.)
So, to answer your question, it's a bad design to churn through database connections. A better approach is to connect once at the beginning of the process, pass the handle of that database connection to the functions that need it, and then disconnect at the end of the process.
The answer from Avetis Zakharyan provides a good approach. I totally agree with him that there is no need to run a separate SELECT statement. It's much more efficient to have the INSERT statement check whether the value exists or not.
This approach reduces the number of roundtrips to the database, AND it also works across multiple concurrent sessions where two (or more) sessions may be running a SELECT to check for the existence of tag, and both sessions don't find it, and when both sessions insert the same tag. A UNIQUE constraint on the column would avoid duplicates; using INSERT IGNORE avoids throwing an exception, but still...
My preferred approach would be to use a SQL statement that only attempts to insert a row if a matching row doesn't already exist:
INSERT INTO tags (tag)
SELECT v.tagval
FROM (SELECT :tag AS tagval) v
LEFT JOIN tags d ON d.tag = v.tagval
WHERE d.tag IS NULL
This is not dependent on a UNIQUE constraint on the tag columns; and it's not dependent on the existence of any index, but an index with a leading column of tag would be desirable for improved performance.
(The SELECT can be run separately, for testing.)
The query is a classic antijoin... "return rows from v for which there is no match in d".
With PDO, use bind parameters, rather than including values in the SQL text.
$sql = "INSERT INTO tags (tag)
SELECT v.tagval
FROM (SELECT :tag AS tagval) v
LEFT JOIN tags d ON d.tag = v.tagval
WHERE d.tag IS NULL ";
$stmt=$conn->prepare($sql);
$stmt->bindParam(":tag",$tag);
$stmt->execute();
(Note: if the characterset of the client differs from the characterset of the target column, the conversion may need to be explicit. For example, if the client characterset is UTF8 and the column is latin1, then:
FROM (SELECT CONVERT(:tag AS latin1) AS tagval) v
i have written few codes to show time spent by users at site but when a users click on submit it should be stored in mysql but its not getting stored can you please tell where i have done mistake here is my code.
Your query seems to be wrong.
Either use INSERT without WHERE if you want to insert a new record. If however you want to update an already present record, use UPDATE instead of INSERT.
And it is always a good idea to check whether a query was successful:
if (mysql_query ("insert into jcow_accounts(Time_Spent) values ('{$Time}') where uid='{$client['id']}' ") === FALSE) {
echo 'MySQL error: ' . mysql_error() . "\n";
}
You need to use an UPDATE instead of an insert.
$dtime = getChangeInTime(); // this is the change in time from the last update
mysql_query( "UPDATE jcow_accounts SET `TIME_SPENT` = `TIME_SPENT` + $dtime ".
" where id='{$client['id']}'" );
Try
insert INTO `jcow_accounts` (`Time_Spent`) VALUES ('{$Time}') where uid='{$client['id']}' WHERE `uid` = '{$client['id']}'
Are you sure the uid is in the DB? try running it without the WHERE...
I am trying to verify that a string is unique within a MySQL column. Here is the code sample:
<?php
$con = mysql_connect("hostname", "username", "password");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("table_name", $con);
if (!mysql_num_rows(mysql_query("SELECT * FROM table_name WHERE unique_string = '123456'
LIMIT 1"))) {
die('This string is not unique.');
}
mysql_close($con);
?>
In this code sample I have input the value 123456 as an example. This example assumes that the string 123456 already exists in the column unique_string. Therefore, it should die and return the statement "This string is not unique." Sadly, it does not. Do you know why? Is there a better way to get this check done?
It's generally unwise to chain your function calls as you have. Particularly with database calls. The mysql_*() functions expect certain things, like statement handles, to be passed in. But they can return a boolean FALSE instead of a handle if there's a problem. This FALSE gets passed in instead of a handle and then everything's broken.
A general rule is to always assume your query will fail somehow, and program defensively:
$sql = "SELECT ....";
$result = mysql_query($sql) or die(mysql_error());
$rows = mysql_num_rows($result);
if ($row !== 0) then
die("Not unique");
}
Beyond that, your query statement does look to be syntactically correct. Why not see what it's returning?
$row = mysql_fetch_assoc($result);
var_dump($row);
and see exactly what's being matched. Maybe you DON'T have that value in the table and are mistaken in thinking that it's there.
Select count(*) from yourtable where mycolumn = 'unique string'
You should now test whether this returned a 1
You use "table_name" also for the DB. Is this correct? If not, mysql_select_db() fails, and any query will fail too, because no DB is selected.
HI everyone i tried for 3 days and i'm not able to solve this problem. This is the codes and i have went through it again and again but i found no errors. I tried at a blank page and it worked but when i put it inside the calendar it has the syntax error. Thanks a million for whoever who can assist.
/** QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !! IF MATCHES FOUND, PRINT THEM !! **/
$testquery = mysql_query("SELECT orgid FROM sub WHERE userid='$userid'");
while($row4 = mysql_fetch_assoc($testquery))
{
$org = $row4['orgid'];
echo "$org<br>";
$test2 = mysql_query("SELECT nameevent FROM event WHERE `userid`=$org AND EXTRACT(YEAR FROM startdate)='2010' AND EXTRACT(MONTH FROM startdate)='08' AND EXTRACT(DAY FROM startdate)='15'") or die(mysql_error());
while($row5=mysql_fetch_assoc($test2))
{
$namethis = $row5['nameevent'];
$calendar.=$namethis;
}
}
First question: what calendar are you talking about?
And here are my 2-cents: does the EXTRACT function returns a string or a number?
Are the "backticks" (userid) really in your query? Try to strip them off.
Bye!
It's a guess, given that you haven't provided the error message you're seeing, but I imagine that userid is a text field and so the value $org in the WHERE clause needs quotes around it. I say this as the commented out testquery has quotes around the userid field, although I appreciate that it works on a different table. Anyway try this:
SELECT nameevent FROM event WHERE userid='$org' AND EXTRACT(YEAR FROM startdate)='2010' AND EXTRACT(MONTH FROM startdate)='08' AND EXTRACT(DAY FROM startdate)='15'
In such cases it's often useful to echo the sql statement and run it using a database client
First step in debugging problems like this, is to print out the acutal statement you are running. I don't know PHP, but can you first build up the SQL and then print it before calling mysql_query()?
EXTRACT() returns a number not a character value, so you don't need the single quotes when comparing EXTRACT(YEAR FROM startdate) = 2010, but I doubt that this would throw an error (unlike in other databases) but there might be a system configuration that does this.
Another thing that looks a bit strange by just looking at the names of your columns/variables: you are first retrieving a column orgid from the user table. But you compare that to the userid column in the event table. Shouldn't you also be using $userid to retrieve from the event table?
Also in the first query you are putting single quotes around $userid while you are not doing that for the userid column in the event table. Is userid a number or a string? Numbers don't need single quotes.
Any of the mysql_* functions can fail. You have to test all the return values and if one of them indicates an error (usually when the function returns false) your script has to handle it somehow.
E.g. in your query
mysql_query("SELECT orgid FROM sub WHERE userid='$userid'")
you mix a parameter into the sql statement. Have you assured that this value (the value of $userid) is secure for this purpose? see http://en.wikipedia.org/wiki/SQL_injection
You can use a JOIN statement two combine your two sql queryies into one.
see also:
http://docs.php.net/mysql_error
http://docs.php.net/mysql_real_escape_string
http://www.w3schools.com/sql/sql_join.asp
Example of rudimentary error handling:
$mysql = mysql_connect('Fill in', 'the correct', 'values here');
if ( !$mysql ) { // some went wrong, error hanlding here
echo 'connection failed. ', mysql_error();
return;
}
$result = mysql_select_db('dbname', $mysql);
if (!$result ) {
echo 'select_db failed. ', mysql_error($mysql);
return;
}
// Is it safe to use $userid as a parmeter within an sql statement?
// see http://docs.php.net/mysql_real_escape_string
$sql = "SELECT orgid FROM sub WHERE userid='$userid'";
$testquery = mysql_query($sql, $mysql);
if (!$testquery ) {
echo 'query failed. ', mysql_error($mysql), "<br />\n";
echo 'query=<pre>', $sql, '</pre>';
return;
}