SQL : INSERT if no exist and UPDATE if exist - php

I have a program that can perform inserts and updates to the database, I get the data from API.
This is sample data when I get:
$uname = $get['userName'];
$oname = $get['offerName'];
$visitdata= $get['visits'];
$convdata = $get['conversion'];
I save this data to database sql. (sucess) this is a sample:
$sql = "INSERT INTO data_tester(username_data, name_offer_data, visit_data, conversion_data) VALUES('$uname','$oname', '$visitdata', '$convdata')";
Sample data in database table
id | username_data | name_offer_data | visit_data | conversion_data
1 | MOJOJO | XXX AU | 177 | 13
2 | MOJOJO | XX US | 23 | 4
Now, I want to save data $uname, $oname, $visitdata, $convdata if NOT EXIST and UPDATE $visitdata, $convdata where $uname, $oname if EXIST
How to run the code with a simple query.
Please give me an example.
Thank you.

The feature you are looking for is called UPSERT and it is the part of SQL-2008 Standard. However not all DBMS-s implement it and some implement it differently.
For instance on MySQL you can use:
INSERT ... ON DUPLICATE KEY UPDATE
syntax (link to docs)
or
REPLACE INTO
syntax (link to docs).
These methods require you to have a proper PRIMARY KEY: (username_data name_offer_data) in your case.
Some PHP frameworks support this feature too provided you are using ActiveRecord (or similar) class. In Laravel it is called updateOrCreate and in Yii it is called save(). So if you are using a framework try to check its documentation.
If you are using neither framework nor modern DBMS you have to implement the method yourself. Run SELECT count(*) from data_tester WHERE username_data = ? AND name_offer_data = ?, check if it returned any rows and call an appropriate UPDATE/INSERT sql

it's simple, try this:
if(isset($get['userName'])){
$sql = "SELECT * FROM data_transfer WHERE userName = ".$userName.";";
$result = connection()->query($sql);
$rs = mysqli_fetch_array($result);
connection()->close();
//if is not void, means that this username exists
if ($rs != ''){
mysqli_free_result($result);
//InsertData
}
else{
mysqli_free_result($result);
//UpdateData
}
*chech that you have to use your PrimaryKey on where clause to ensure there are only one of this. if you use an ID and you don't get it by $_GET, you'll have to modify something to ensure non-duplicated data. For example, checking that userName cannot be duplicated or something similar

You can simply use replace into command instead of insert into command.
$sql = "REPLACE INTO data_tester(username_data, name_offer_data, visit_data, conversion_data) VALUES('$uname','$oname', '$visitdata', '$convdata')";
It is one of mysql good and useful feature. I used it many times.

Please ensure there is a unique key on column username_data, if so Mysql's ON DUPLICATE KEY UPDATE is suitable for this case, the SQL statement is like that:
$sql = "INSERT INTO data_tester(username_data, name_offer_data, visit_data,
conversion_data) VALUES('$uname','$oname', '$visitdata', '$convdata')
ON DUPLICATE KEY UPDATE username_data = '$uname', name_offer_data =
'$oname', visit_data = '$visitdata', conversion_data = '$convdata'"

Related

How to insert json object into mysql table

There are many examples around which parse the JSON and then insert the respective fields into MySQL table.
My case is different in a way that I am creating a json at runtime.
my table looks like this:
mysql> describe turkers_data;
+-----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------+------+-----+---------+-------+
| id | char(36) | NO | PRI | NULL | |
| sentences | json | NO | | NULL | |
+-----------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)
based on the input received, I build a json using json_encode method in php, which I alredy validated on jsonlint and it is of course valid.
example json:
{
"opening": "[\"John arrived at Sally's house to pick her up.\",\"John and Sally were going to a fancy restaurant that evening for a dinner.\",\"John was little nervous because he was going to ask Sally to marry him.\"]",
"first_part": "[\"aa\",\"bb\"]",
"first_mid": "[\"Waiter shows John and Sally to their table.\"]",
"mid_part": "[\"cc\",\"dd\"]",
"mid_late": "[\"John asks Sally, \\\"Will you marry me?\\\"\"]",
"last_part": "[\"ee\",\"ff\",\"gg\"]"
}
I use following code to insert into mysql table using mysqli
$opening = array("John arrived at Sally's house to pick her up.", "John and Sally were going to a fancy restaurant that evening for a dinner.", "John was little nervous because he was going to ask Sally to marry him.");
$mid_early = array("Waiter shows John and Sally to their table.");
$mid_late = array('John asks Sally, "Will you marry me?"');
$json_data->opening = json_encode($opening);
$json_data->first_part = json_encode($jSentence_1);
$json_data->first_mid = json_encode($mid_early);
$json_data->mid_part = json_encode($jSentence_2);
$json_data->mid_late = json_encode($mid_late);
$json_data->last_part = json_encode($jSentence_3);
$data = json_encode($json_data);
echo($data);
$sql = "INSERT INTO turkers_data (id, sentences)
VALUES ($id, $data)";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
but it does not work, i get the error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"opening":"[\"John arrived at Sally's house to pick her up.\",\"John and Sally w' at line 2
I do not know what is wrong. I could not find much information on how to do this, I read that it is not recommended to have json data dumped as it is into mysql table, but in my case i am unsure of how many sentences are going to there. Also, I believe this serves the purpose for the time being, I plan to just get that JSON from mysql back and process the data in python.
Also pardon me for using json, JSON, MySQL, mysql, I do not know the standard yet.
You are having a problem with your SQL insert because you have this:
$sql = "INSERT INTO turkers_data (id, sentences) VALUES ($id, $data)";
There is no escaping of quotes on $data, and the $data is not wrapped in single quotes either.
You should build this as a prepared statement and bind the params which will do all that for you:
$sql = "INSERT INTO turkers_data (id, sentences) VALUES (?,?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ss', $id, $data );
$stmt->execute();
The above assumes you are using mysqli, and not PDO. If its PDO, this is syntax for PDO method:
$sql = "INSERT INTO turkers_data (id, sentences) VALUES (?,?)";
$stmt = $conn->prepare($sql);
$stmt->execute(array($id, $data));
EDIT
Last ditch effort (AND ILL-ADVISED), if your php and mysql do not support prepared statements (it should!), then you can resort to the old method of wrapping and escaping your fields in the sql build string:
$sql = "INSERT INTO turkers_data (id, sentences)
VALUES (
'". $conn->real_escape_string($id) ."',
'". $conn->real_escape_string($data) ."'
)";
But this is NOT ADVISED! If at all costs you should try to get prepared statements to work, or upgrade your PHP, or mysqli extensions.

SQL - Inserting data where values are an array

I want to be able to add an array of strings to a table so that each string is a new row (in PHP).
This is it in psuedo-code:
$Array = "10000,10001,10002,10003";
$Data = "ImportantData";
mysqli_query($db, "INSERT INTO MyTable(`id`,`data`) VALUES($Array, $Data)");
So that a previously empty table would look like:
id | data
------------------------
10000 | ImportantData
10001 | ImportantData
10002 | ImportantData
10003 | ImportantData
In an update script, with those rows already established, I could just say:
mysqli_query($db, "UPDATE MyTable SET data = $Data WHERE `id` IN($Array));
However I want it to create rows, not just update old ones.
Is there any way I can do this?
Just create a foreach loop on $Array, and insert the data. I assume you want to update it if it exists as it makes little sense to create a new record with the same PK, so use the following (assumes you are using PHP PDO
INSERT INTO MyTable (id,data) VALUES (:id,:data) ON DUPLICATE KEY UPDATE data=:data;
Use REPLACE INTO:
REPLACE INTO table SET id = 10001, data = 'new important data';
MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/replace.html

PHP/MySQL: INSERT INTO with variable column name not working

I've used INSERT INTO hundreds of times, but it has been a while and I have been driving myself crazy on this one:
//Database Connection
$movieID = 41154;
$userID = 15;
$vote = 'yes';
$postVote = mysql_query("INSERT INTO votes (movieID, userID, yesNo, $vote) VALUES ('$movieID', '$userID', 1, 1)");
I'm able to successfully connect to the database and get data from the votes table, but for some reason, I'm having trouble using INSERT INTO.
The following columns exist in the vote table: movieID, userID, yesNo, and yes.
Any thoughts on what I can do differently? I must be overlooking something very obvious.
Using ... or die(mysql_error(), as Marc B pointed out, lead me to my problem. This displayed the error that I couldn't set duplicate keys...I forgot to auto increment the primary key for the votes table. Thus it kept trying to create a voteID of 1 each time I tried to INSERT INTO votes.
$postVote = mysql_query(...) or die(mysql_error());
This solved my challenge. However, Tim G points out that using PDO is a much better approach than mysql_query(). With a little bit of reading, Tim G is probably right about PDO. Based on PHPEveryday's Tutorial, I could rewrite my Insert Statement as such:
// database connection
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
//set variables
$movieID = 41154;
$userID = 15;
$vote = 'yes';
//query/insert statement
$sql = "INSERT INTO votes (movieID,userID,yesNo,$vote) VALUES (:movieID,:userID, :yesNo, :$vote)";
$q = $conn->prepare($sql);
$q->execute(array(':movieID'=>$movieID,
':userID'=>$userID)),
':yesNo'=>1)),
':$vote'=>1));
Instead of using or die(), PDO also has a different way of handling errors and exceptions. You can learn more about it on PHPHash.org's Tutorial: PDO for MySQL - Error Handling.
INSERT INTO votes (movieID,userID,yesNo,$vote)
and replace $vote with vote

Value in Column

I am developing a small hobby application. Though I've worked with MySQL and PostgreSQL before, I'm more of a n00b here and would appreciate any help.
I have a table in my MySQL database called "TECH". This table has two columns: "ID" (primary key) and "name" (name of the tech - not a key of any sort). Here are a couple of example rows:
+----+--------+
| ID | name |
+----+--------+
| 1 | Python|
| 2 | ASP |
| 3 | java |
+----+--------+
Here is the code that creates TECH:
CREATE TABLE TECH (
id INT(5) ,
name VARCHAR(20),
PRIMARY KEY (id)
);
I have developed an html form for the user to input a new technology into TECH. However, I would like to ensure that duplicate entries do not exist in TECH. For example, the user should not be allowed to enter "Python" to be assigned ID 4. Further, the user should also not be allowed to enter "pYthon" (or any variant of capitalization) at another ID.
Currently, I have the following code that does this (on the PHP side, not the MySQL side):
// I discovered that MySQL is not case sensitive with TECH.name
$rows = 0;
$result = $mysql_query("SELECT * FROM tech AS T WHERE T.name='python'");
while ($row = mysql_fetch_array($result)) {
$rows += 1;
}
if ($rows != 0) {
echo "'python' cannot be inserted as it already exists";
} else {
// insertion code
}
Now, I know that the correct way to do this would be to constrain TECH.name to be UNIQUE by doing UNIQUE (name) and catching an "insert error" on the PHP side.
However, I have the following two questions regarding this process:
Does defining the UNIQUE constraint maintain the apparent case-insensitivity addressed above?
How do I go about catching exactly such an insert error on the PHP side?
I'd appreciate any help with this or any better ideas that anyone has.
When you manipulate mysql form php (i.e. by doing an INSERT or UPDATE), you can call mysql_get_rows_affected which will return the rows affected. If the query has failed due to the UNIQUE constraint then the affected rows will be 0
http://php.net/manual/en/function.mysql-affected-rows.php
I usually check the number of rows returned from that function, The same check can be applyed if you take the INSERT OR IGNORE approach
TRY
INSERT IGNORE INTO mytable
(primaryKey, field1, field2)
VALUES
('abc', 1, 2),
('def', 3, 4),
('ghi', 5, 6);
duplicated rows would be ignored
Changing the collation of the field to _ci or _cs would determine whether a unique key was caseinsensitive or casesensitive.
As for catching the error, you should try using mysqli or PDO to run db queries: http://www.php.net/manual/en/pdo.exec.php
You can catch a duplicate error entry with PDO like so:
try
{
$dbh->exec($mySqlQuery);
// insert was successful...
} catch (PDOException $e) {
if ($e->errorInfo[1]==1062) {
// a 'duplicate' error occurred...
} else {
// a non 'duplicate error' occurred...
}
}
Edit:
If you're not using PDO, this should work after your mysql_query:
if (mysql_errno() == 1062)
{
// you have a duplicate error...
}

help in uniquely identifying combine columns

How can I uniquely identify two or more columns, that I have used table named address in the database, now address is has fields like street name, suite name and street num.
strnum | strnam | sutname
1 | xyz | 32
1 | xyz | 32
now how can I uniquely these three columns. That is I want to check whether these three column are already inserted or not. If any field valus is changed than its ok, it will insert new one. but in case all three similar field..Help me to combinely identify these three fields.
You do it by adding unique constraint.
ALTER TABLE your_table ADD UNIQUE(strnum, strnam, sutname);
Then you do the following:
INSERT IGNORE INTO your_table (strnum, strnam, sutname) VALUES ('1', 'xyz', 'etc');
If the value exists already - no insert will happen and no errors will be raised (that's what the IGNORE part is).
By the way why do you use such short and vague column names? It's not the DOS era any more, you can be descriptive with your column names.
$query = "SELECT * FROM `address` WHERE `strnum` = '$strnum' AND `strnam` = '$strnam' AND `sutname` = '$sutname' LIMIT 1";
$result = mysql_query($query);
if (!mysql_num_rows($result)) {
// If you get to here, there is no existing record
$query = "INSERT INTO `address` (`strnum`,`strnam`,`sutname`) VALUES ('$strnum','$strnam','$sutname')";
if (!mysql_query($query)) print('Insert failed!');
} else print('Record already exists!');
EDIT I just added a missing ; so this parses...
just add them as unique keys in table structure and you'll not be able to insert two of them
you can do something like this
SELECT * FROM table WHERE col1 = $something AND col2 = $something2 AND col3 = $something3
(remember about escpaing php variables)
if the record is returned it means it exists. You can also add LIMIT 1 to make it faster.
if your question is about ENSURING that no duplicates occur in the table (for those 3 columns), then probably the best solution is to add UNIQUE index on those three columns.

Categories