How to calculate (+) value from $_POST before save to database - php

This my code
$_SESSION['poraw'] = substr(md5(time()), 0, 16);
$userid= $_SESSION["userid"];
$today = date('Y-m-d');
$month = $_POST['month'];
for($i = 0; $i < count($_POST['id']); $i++){
$id = $_POST['id'][$i];
$resin = $_POST['resin'][$i];
$hasil = $_POST['hasil'][$i];
$sql="INSERT INTO po_supplier_temp (unique_code,po_customer_month,resin,qty,username)
VALUES ('".$_SESSION['poraw']."','$month','$resin','$hasil','$userid')";
$sql = $conn->query($sql);
}
Current results:
if $resin same , i want $hasil plus it (+) , before save to dabatase and only one name $resin to database in same time
Like this:
thanks

You have two options: Create a stored procedure to handle the custom logic, or integrate the logic inside your php.
I'll only show you how you can make a stored procedure to do the task you wish to complete. If you need help on how to use a stored procedure, this has already been answered somewhere around here.
--- Transact-SQL Syntax
CREATE PROCEDURE [dbo].[InsertOrUpdateMyThing]
(
#SessionId int,
#Month date,
#Resin int,
#Hasil int,
#UserId int
)
AS
BEGIN
SET NOCOUNT ON
IF EXISTS(SELECT 1 FROM po_supplier_temp WHERE resin = #Resin)
BEGIN
UPDATE p
SET p.resin = p.resin + 1
FROM po_supplier_temp p
WHERE p.resin = #Resin
END
ELSE
BEGIN
INSERT INTO po_supplier_temp (unique_code, po_customer_month, resin,qty, username)
VALUES (#SessionId, #Month, #Resin, #Hasil, #UserId)
END
END
EDIT: If you're passing multiple values at the same time, you'll need to edit this to accept a table-valued parameter with all the necessary information, as well as modify the code inside the procedure to handle a set of data. It'd be better to do that, rather than invoke this procedure X amount of times.

Related

PHP - how to make an insert until there is no duplicate field value exist?

I have a Mysql table where pincode field cant be duplicate daily (Sequential increment id), also i cant apply the unique key on that field using Mysql indexing for some reason.
Using PHP i am trying as below, but my code will become endless if i have to keep increasing by checking them as below.
Is there any better way without Mysql indexing to do it from PHP (zend framework)?
$sql = "SELECT count(*) as total
FROM `sh_av_spform`
WHERE DATE(`createdate`) = CURDATE( )";
$result = $db->fetchAll($sql);
if(count($result)>0) {
$tmp_id = $result[0]['total'] +1;
$new_id = sprintf('%03d',$tmp_id); // 009
try{
$sql1 = "SELECT id,pincode
FROM `sh_av_spform`
WHERE DATE(`createdate`) = CURDATE() and pincode='$new_id' limit 1";
$result1 = $db->fetchAll($sql1);
if(count($result1)>0) {
// 009 already exist make it 010?
$tmp_id = $result[0]['total'] +2;
$new_id = sprintf('%03d', $tmp_id); // 010
}
// Ooopsssss! 010 also exist. now what?
// keep wrting code forever? or there is better way?
$db->insert('sh_av_spform', array('pincode'=>$new_id) );// Pincode cant be duplicated
You can do this entirely in database, using a counter table.
Example:
CREATE TABLE daily_pin (day DATE PRIMARY KEY, pin INT UNSIGNED);
START TRANSACTION;
INSERT INTO daily_pin VALUES (CURDATE(),1) ON DUPLICATE KEY UPDATE pin=LAST_INSERT_ID(pin+1);
INSERT INTO table_requiring_pin (pin) VALUES (LPAD(LAST_INSERT_ID(),3,'0'));
COMMIT;
Notes:
The counter table holds a given day's highest as yet used PIN.
The INSERT .. ON DUPLICATE KEY gets a new pin, either a "1" if it's the first entry for a given day, or the current value plus 1.
LAST_INSERT_ID, when given an argument, returns the argument and remembers it for the next time LAST_INSERT_ID is called without an argument.
Finally, left pad it with LPAD to get the "000" format you're wanting.
As a side benefit of this approach, you get easy metrics on pin usage. Like, "what day of the week consumes the most pin?"
You can create one separate function for checking pin code before you insert.
For example
public function ValidatePinCode($PinCode){
if(isset($PinCode)){
$SQL=$db->prepare("SELECT pincode FROM `sh_av_spform` WHERE pincode='".$PinCode."'");
$SQL=$db->execute($SQL);
if($SQL->fetchColumn()>0){
$ResponseCode='FALSE';
}else {
$ResponseCode='TRUE';
}
return $ResponseCode;
}
}
If you get FALSE response then do not allow to insert new pin code else you can perform INSERT query.
Let me know if you want even more explanation on this.

Doing upsert in ORACLE DB and doesnt work

I am doing an insert condition in oracle that when the record based on job and subjob doesnt exists, it shall insert otherwise, if it exists then it should update the rest of the value.
this is my procedure,
CREATE OR REPLACE PROCEDURE WELTESADMIN.SP_JOB_INS
(
JOB_V VARCHAR2,
SUBJOB_V VARCHAR2,
STARTDATE_V DATE,
ENDDATE_V DATE,
JOBWEIGHT_V NUMBER
)
AS BEGIN INSERT INTO PROJECT_SPAN (JOB, SUBJOB, STARTDATE, ENDDATE, WEIGHT) VALUES (JOB_V, SUBJOB_V, STARTDATE_V, ENDDATE_V, JOBWEIGHT_V);
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
UPDATE PROJECT_SPAN SET STARTDATE = STARTDATE_V, ENDDATE = ENDDATE_V, WEIGHT = JOBWEIGHT_V WHERE JOB = JOB_V AND SUBJOB = SUBJOB_V;
END;
/
and this is from PHP Call,
$insertJobSpanSql = "BEGIN SP_JOB_INS(:JOB, :SUBJOB, :SDATE, :EDATE, :WT); END;";
$insertJobSpanParse = oci_parse($conn, $insertJobSpanSql);
oci_bind_by_name($insertJobSpanParse, ":JOB", $jobValue);
oci_bind_by_name($insertJobSpanParse, ":SUBJOB", $subJobValue);
oci_bind_by_name($insertJobSpanParse, ":SDATE", $startDateValue);
oci_bind_by_name($insertJobSpanParse, ":EDATE", $endDateValue);
oci_bind_by_name($insertJobSpanParse, ":WT", $jobWeightValue);
$insertJobSpanRes = oci_execute($insertJobSpanParse);
if ($insertJobSpanRes){
oci_commit($conn);
} else {
oci_rollback($conn);
}
problem is it keeps inserting new row with the same job and subjob value. it should be an update to the new value.
First of all, I recommend to use MERGE in such cases:
CREATE OR REPLACE PROCEDURE WELTESADMIN.SP_JOB_INS
(
JOB_V VARCHAR2,
SUBJOB_V VARCHAR2,
STARTDATE_V DATE,
ENDDATE_V DATE,
JOBWEIGHT_V NUMBER
) AS
BEGIN
merge into PROJECT_SPAN ps
using (select JOB_V, SUBJOB_V, STARTDATE_V, ENDDATE_V, JOBWEIGHT_V
from dual) new_val
on (ps.SUBJOB = new_val.SUBJOB_V and ps.JOB = new_val.JOB_V)
when matched then update
set STARTDATE = new_val.STARTDATE_V,
ENDDATE = new_val.ENDDATE_V,
WEIGHT = new_val.JOBWEIGHT_V
when not matched then insert (JOB, SUBJOB, STARTDATE, ENDDATE, WEIGHT)
values (new_val.JOB_V, new_val.SUBJOB_V, new_val.STARTDATE_V,
new_val.ENDDATE_V, new_val.JOBWEIGHT_V );
END;
/
If it still not updating values, use package DBMS_OUTPUT or logging into a table to make sure, that new and old JOB and SUBJOB really the same.
Oracle raises DUP_VAL_ON_INDEX when a DDL statement violates a primary key or unique key constraint. So for your code to work you need to define a primary key on (job, subjob) or else build a unique index on that pair.
Oracle provides an easier way of implementing upserts, in the form of the MERGE statement:
CREATE OR REPLACE PROCEDURE WELTESADMIN.SP_JOB_INS
(
JOB_V VARCHAR2,
SUBJOB_V VARCHAR2,
STARTDATE_V DATE,
ENDDATE_V DATE,
JOBWEIGHT_V NUMBER
)
AS BEGIN
merge into project_span ps
using ( select job_v, subjob_v, startdate_v, enddate_v, jobweight_v from dual ) q
on (ps.job = q.job_v
and ps.subjob = q.subjob_v)
when not matched then
insert (job, subjob, startdate, enddate, weight)
values (q.job_v, q.subjob_v, q.startdate_v, q.enddate_v, q.jobweight_v);
when matched then
update
set startdate = q.startdate_v
, enddate = q.enddate_v
, weight = q.jobweight_v
;
END;
The MERGE statement is in the documentation. Find out more.

PHP - Select & Update statement to return and update a multi dimensional array

I have a database that looks like the following
In my database both id & fb_user_id are unique. Id is an auto incremented number.
First i would like to insert a new row for arguments say with the following
$new_first_name = "John";
$new_last_name = "Nolan";
$new_email = "John#Nolan.com";
$new_link_url = "Johns_Link";
$new_signups = 0;
$new_order = $num_rows;
$referred_by = 2;
$new_fb_user_id = 4;
I use this insert statement
$New_Member = mysql_query("INSERT INTO `rotator`.`rotator` (`id`, `fb_user_id`, `first_name`, `last_name`, `email`, `link_url`, `referred_by`, `signups`, `order`) VALUES (NULL, '$new_fb_user_id', '$new_first_name', '$new_last_name', '$new_email', '$new_link_url', '$referred_by', '$new_signups', '$new_order');");
And because the person was referred by fb_user_id number 2 i want to update signups as follows
$update_sponsor_order = mysql_query("UPDATE `rotator`.`signups` = `rotator`.`signups` + 1 WHERE `rotator`.`fb_user_id` = $referred_by;");
This is where i am stuck. Maybe there is a better way to do it than inserting and updating the table as abovee.
What i would like to do now is something like the following select statement but assigning the returned values to a multi dimensional array. Basically i return columns fb_user_id and order where signups is less than 2
$get_link = mysql_query("SELECT `rotator`.`fb_user_id`, `rotator`.`order` FROM `rotator`.`rotator` WHERE `rotator`.`signups` < 2);
Now with my array i want to rotate everything that is in the column order and update the database of what entry is next in line....
Check the following question and replys to see what i am trying to do
Original Question
You're new best friend the pdo class. I know this doesn't exactly answer your question, but if you start using it now, you will thank me later.
Overview here http://www.php.net/manual/en/class.pdostatement.php
And to retreive results: http://php.net/manual/en/pdostatement.fetch.php

insert values between rows

I don't know if it can be done with just a sql query or it needs a php code
when a cid is missing
There exist many missing values which I can't handle manually
For example, here I don't have cid=1 and cid=6.
I want to insert a row:
cid=1 tcp_sport='undefined' tcp_dport='undefined'
and
cid=6 tcp_sport='undefined' tcp_dport='undefined'
It seems to me I should create a procedure and insert between lines
another solution that I thaught was that I will create a table with cid and undifined values with the respective order and then join this one with that one and this join should have for example ifnull(tcp_sport,'')
would you please help me?
First, use MAX for get the largest ID.
SELECT MAX(cid) as max FROM table
Then, create a for loop for checking if the individual IDs exist:
for ($i = 0; $i < $max; $i++) {
// $query = ... SELECT 1 FROM table WHERE cid = $i ...
// check if the number of rows for $query is greater than 0
// if not, INSERT INTO table VALUES ($i, DEFAULT, DEFAULT)
}
The whole idea of an auto increment ID is to have a value that only refers to one thing ever. By "inserting between the lines" you may be opening yourself up to a lot of unforeseen problems. Image you have another table that has some values that link to the CID of this table. What if that table already has an entry for CID=1, When you insert a new item with CID=1 it will then join to that supporting record. So Data that really belongs to the original item with CID=1 will show for the new item which it probably has nothing to do with.
You aren't going to run out of ID values (if you are approaching the limit of integer, switch it to bigInt), don't re-use IDs if you can avoid it.
You need to use PHP to automate this.
<?php
$link = mysql_connect("localhost", "mysql_user", "mysql_password");
mysql_select_db("database", $link);
while($i < max_value_cid)//replace max_value_cid by the numeric maximum value of cid (SELECT MAX(cid) as max FROM table)
{
$result = mysql_query("SELECT * FROM `table` WHERE cid=".$i, $link);
if(mysql_num_rows($result) == 0)
mysql_query("INSERT INTO `table` VALUES ($i, NULL, NULL);", $link);
$i++;
}
?>
Do test the query on a sample set before execution and remember to backup the entire table, just-in-case.

how to get insert_id in a variable before insert query

I like to create a specific filename for a file that will be created by the input of the fields from the insert query. i like to have an unique key for that. this key consists of an user_id, a timestamp and at the end of this, it should be placed the generated insert_id from the insert query fired. it should be placed the auto_increment no. for the end of my generated variable. so the problem is, that i create a variable before the insert query fired so that this variable will be part of the insert query like:
$get_num = $db->query("SELECT COUNT (*) FROM tableA");
$num = $query->fetch_assoc();
$end = $num + 1;
$file_id = $id .".". time() .".". $end;
$insert = $db->query("INSERT INTO tableA ( file_id, a, b, c) VALUES('".$file_id."','".$a."','".$b."','".c."')");
Actually, forget what I wrote previously. You cannot count on COUNT working for you because what happens when a row is deleted? You will have duplicate values. The best bet for you is to first create the row, grab the insert_id, then UPDATE the file_id uing the function you previously described.
$uid = uniqid();
$insert = $db->query("INSERT INTO tableA ( file_id, a, b, c) VALUES('".$uid."','".$a."','".$b."','".c."')");
$file_id = $id .".". time() .".". mysql_insert_id();
$db->query("UPDATE tableA SET file_id='{$file_id}' WHERE file_id='{$uid}' LIMIT 1;");
In the end, you still have to use two queries anyway, so its not like this takes any more resources. Plus you aren't doing a COUNT operation anymore.
In other news, please be sure to read up on SQLi, depending on where your a,b,c variable are coming from.
This is a bad idea. Do your insert and then use LAST_INSERT_ID. Otherwise, as #AuthmanApatira noted, you could have the wrong id. The PHP for this is mysql_insert_id().
Also note that if your index column is auto_increment, you don't even need to worry about the id; the db takes care of it for you. You can just get it after your query runs.

Categories