How to set automatically id base on date - php

I'm a newbie in PHP. I hope someone can help me. before that sorry my english's bad.
I want set kd_transaksi base on date and id from another table. when people booking, system automatically set kd_transaksi.
$tgl_pesan = date("Ymd");
$cek = mysqli_query($conn, "SELECT max(kd_booking) AS kode FROM booking WHERE kd_booking LIKE '$tgl_pesan%'");
$row = mysqli_fetch_array($cek);
$kdMax = $row['kode'];
$nourut = substr($kdMax, 8, 4);
$nourut++;
$char = "BO";
$kd_transaksi = $char.$tgl_pesan.printf('%04s', $nourut);
$kd_booking = mysqli_insert_id($conn);
$book = "INSERT INTO detail_booking (kd_booking,kd_transaksi,total_bayar) VALUES ('".$kd_booking."','$kd_transaksi',$total_bayar')";
$ok = mysqli_query($conn,$book);
if ($ok) {
header('location:../mybooking.php');
} else{
mysqli_close($conn);
}
but result in query $cek is NULL.
$cek = mysqli_query($conn, "SELECT max(kd_booking) AS kode FROM booking WHERE kd_booking LIKE '$tgl_pesan%'");
how do I fix it?
booking table
CREATE TABLE `booking` (
`kd_booking` int(11) NOT NULL,
`id_user` int(11) NOT NULL,
`kd_paket` int(11) NOT NULL,
`jml_org` int(11) NOT NULL,
`tgl_pesan` date NOT NULL,
`tgl_wisata` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
What i want is
If someone booking today and get kd_booking 21, then the output would be : BO2018120521.

First of all, you have something wrong with your CREATE TABLE. When you create a table you should have an AUTOINCREMENT primary key, this is your id. So it would be something like this:
CREATE TABLE `booking` ( `id` INT NOT NULL AUTO_INCREMENT , `id_user` INT(11) NOT NULL , `kd_paket` INT(11) NOT NULL , `jml_org` INT(11) NOT NULL , `tgl_wisata` DATE NOT NULL , `tgl_pesan` DATE NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;
As i can se you have two errors:
Date should be like date('Y-m-d') http://php.net/manual/en/function.date.php
You're trying to insert an int value like '".$kd_booking."' when that just works for strings.
Hope it helped.

Related

Reduce MySQL request time with Codeigniter

I use Codeigniter 3.1.11 and have some code which makes one big query to MySQL with an array. The time of a query with a limit of 30000 is about 9 seconds.
How can I reduce the request time? Maybe by using some indexes on my table, or do you know another method? If I need to use indexes, what indexes would I need to use and how can I use these indexes in my query on Codeigniter?
Code from model:
function rows_update() {
$query = $this->db->order_by('rating', 'DESC')->get_where('members', 'game_rating_and_balance_update_last_time <= now() - INTERVAL 1 DAY', '30000', '0');
$arrUpdateBatchData = [];
while ($row = $query->unbuffered_row('array'))
{
// some code here
$arrUpdateData = [
'UserID' => $row['UserID'],
'game_vault_balance' => $new_game_vault_balance,
'game_available_balance' => $new_game_available_balance,
'rating' => $rating_member,
'game_rating_and_balance_update_last_time' => date('Y-m-d H:i:s')
];
$arrUpdateBatchData[] = $arrUpdateData;
if (count($arrUpdateBatchData) > 500)
{
$this->db->update_batch('members', $arrUpdateBatchData, 'UserID');
$arrUpdateBatchData = [];
}
}
//update last items
if (count($arrUpdateBatchData) > 0)
{
$this->db->update_batch('members', $arrUpdateBatchData, 'UserID');
$arrUpdateBatchData = [];
}
return;
}
Raw query to MySQL with update_batch (I simply write only one row from an array):
UPDATE members SET game_vault_balance = CASE WHEN UserID = '9915075' THEN 803.60516004772 ELSE game_vault_balance END, game_available_balance = CASE WHEN UserID = '9915075' THEN 4.1253850908788 ELSE game_available_balance END, rating = CASE WHEN UserID = '9915075' THEN 0.24 ELSE rating END, game_rating_and_balance_update_last_time = CASE WHEN UserID = '9915075' THEN '2020-07-24 22:00:36' ELSE game_rating_and_balance_update_last_time END WHERE UserID IN('9915075')
Table structure:
CREATE TABLE `members` (
`id` int(10) UNSIGNED NOT NULL,
`UserID` varchar(64) NOT NULL,
`telegram_id` varchar(64) DEFAULT NULL,
`first_name` varchar(64) DEFAULT NULL,
`last_name` varchar(64) DEFAULT NULL,
`language` varchar(64) DEFAULT NULL,
`currency` varchar(64) DEFAULT NULL,
`status` varchar(64) DEFAULT NULL,
`rating` varchar(64) DEFAULT NULL,
`game_vault_balance` decimal(32,8) DEFAULT 0.00000000,
`game_available_balance` decimal(32,8) DEFAULT 0.00000000,
`game_rating_and_balance_update_last_time` datetime DEFAULT NULL,
`updated` datetime DEFAULT NULL,
`created` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Indexes of this table:
ALTER TABLE `members`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `UserID` (`UserID`) USING BTREE;
AUTO_INCREMENT for the members table:
ALTER TABLE `members`
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;
COMMIT;

PHP MYSQL prevent getting duplicate unique id while inserting from different users at same time

I am trying to generate invoice id in each invoice, now i am having thousands of invoices, Now while adding from different ip same time i am getting duplicate invoice ids how to prevent it,
invoice id generating by getting the last inserted invoice id and increment 1 to it.
my function as follows parameters
get_new_tbl_id('table_name','invoice_id_column','string to strip (INV in INV0012)','any conditions');
function get_new_tbl_id($tbl_name,$id_field,$string,$options='')
{
$new_id = 0;
$query_count_rows = "SELECT MAX(CONVERT(replace(replace($id_field,',',''),'$string',''), SIGNED INTEGER)) as $id_field FROM $tbl_name WHERE $id_field LIKE '$string%' $options";
$count_rows = mysql_query($query_count_rows);
$num_rows = mysql_num_rows($count_rows);
if($num_rows >0)
{
$last_row = mysql_fetch_assoc($count_rows);
$last_id = $last_row[$id_field];
$last_inserted_id = intval(str_replace($string,'',$last_id));
$new_id = $last_inserted_id+1;
}
else
$new_id = 1;
$format = '%1$03d';
$new_id=sprintf($format,$new_id,'');
return $string.$new_id;
}
My table as follows
CREATE TABLE IF NOT EXISTS `tbl_invoice` (
`invoice_tbl_id` int(11) NOT NULL AUTO_INCREMENT,
`invoice_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`invoice_ip` varchar(25) NOT NULL,
`invoice_status` tinyint(1) NOT NULL DEFAULT '0',
`invoice_added_by` smallint(6) NOT NULL,
`invoice_edited_by` smallint(6) NOT NULL,
`invoice_date` date NOT NULL,
`invoice_id` varchar(15) NOT NULL,
`customer_id` varchar(11) NOT NULL,
`invoice_credit_date` tinyint(4) NOT NULL,
`invoice_credit_status` tinyint(1) NOT NULL DEFAULT '0',
`total_items_count` smallint(6) NOT NULL,
`invoice_total_amount` varchar(20) NOT NULL,
`invoice_grandtotal_amount` double NOT NULL,
`invoice_discount` double NOT NULL DEFAULT '0',
`invoice_total_card_amount` double NOT NULL,
`invoice_total_cash_amount` double NOT NULL,
`invoice_total_profit` varchar(10) NOT NULL,
`cashier_approval` tinyint(1) NOT NULL DEFAULT '0',
`cashier_approval_id` smallint(6) NOT NULL,
`cashier_approval_time` datetime NOT NULL,
`cashier_approval_ip` varchar(20) NOT NULL,
`invoice_delete_note` text NOT NULL,
PRIMARY KEY (`invoice_tbl_id`),
KEY `invoice_id` (`invoice_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Use a myisam table to generate the ids for you with 2 fields. The 1st field contains the prefix (this is $string in your function), the second should be an auto increment field. Add a primary key on these 2 fields, but the prefix field must be the 1st one in the index. If you insert a new row into this table with a prefix, then mysql will increment the auto increment value within that group.
See myisam notes section in mysql documentation on auto increment for details and example.
CREATE TABLE animals (
grp ENUM('fish','mammal','bird') NOT NULL,
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (grp,id)
) ENGINE=MyISAM;
INSERT INTO animals (grp,name) VALUES
('mammal','dog'),('mammal','cat'),
('bird','penguin'),('fish','lax'),('mammal','whale'),
('bird','ostrich');
If your base table is mysql, then just alter it to get this behaviour, if not, then create a separate myisam table, do the inserts into that one first, then obtain the ids fo use in your main table.
May there will be some optimized solution, but for now I can give you this solution
use static variable lock if one person is getting id make $lock=true and keep other requests on waiting for 1 second and check again by goto start; until first request is completed; make $lock=false; at the end to release the function.
public static $lock=false;
function get_new_tbl_id($tbl_name,$id_field,$string,$options='')
{
global $lock;
start:
if($lock==true){
sleep(1);
goto start;
}
if($lock==false){
$lock==true;
}
$new_id = 0;
$query_count_rows = "SELECT MAX(CONVERT(replace(replace($id_field,',',''),'$string',''), SIGNED INTEGER)) as $id_field FROM $tbl_name WHERE $id_field LIKE '$string%' $options";
$count_rows = mysql_query($query_count_rows);
$num_rows = mysql_num_rows($count_rows);
if($num_rows >0)
{
$last_row = mysql_fetch_assoc($count_rows);
$last_id = $last_row[$id_field];
$last_inserted_id = intval(str_replace($string,'',$last_id));
$new_id = $last_inserted_id+1;
}
else
$new_id = 1;
$format = '%1$03d';
$new_id=sprintf($format,$new_id,'');
$lock=false;
return $string.$new_id;
}

getting a last inserted varchar id which is an primary key

I have multiple table ,which has to be inserted using different forms and all table have one id which is primary key and its varchar (NOT NULL),So i have one class function named as id_calc($tbl,$id) where $tbl is a parameter with table name and $id is a field id .And each time while inserting this function has to be called for id.
for example: If my id is "web1" ,next when i insert it shud give "web2","web3"...... i have tried with LAST_INSERT_ID() but its not working.so i tried with fetching the max(id) and splitting the string and variable but is also giving some problem.so how can i do this.please help!!!
class first{
public function id_calc($tbl,$id)
{
$sql = mysql_query("SELECT max($id) FROM $tbl where $id like '%web%'");
if($sql)
{
while ($row = mysql_fetch_assoc($sql))
{
$user=$row;
$a=implode(" ",$user);
}
$pattern = "/(\d+)/";
$array = preg_split($pattern, $a, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
$new[]=$array['0'];
$new[]=$array['1']+1;
$result=implode("",$new);
return $result;
}
}
}
this function is called like
public function insertreport1()
{
$obj=new first();
$id=$obj->id_calc(tablename,idfield);
//insert query
}
this is my table structure
CREATE TABLE `report` (
`inc_id` varchar(25) NOT NULL,
`inc_status` int(11) NOT NULL,
`inc_date` datetime NOT NULL,
`inc_Name` varchar(45) NOT NULL,
`inc_Age` int(11) NOT NULL,
`inc_Gender` varchar(45) NOT NULL,
`inc_Mobile` varchar(45) NOT NULL,
`inc_Address` varchar(250) NOT NULL,
`inc_treatment` varchar(45) DEFAULT NULL,
`inc_userid` varchar(10) NOT NULL,
`inc_repTime` datetime NOT NULL
PRIMARY KEY (`inc_id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
i think you can do it this way..write the query as
"SELECT MAX(CAST(SUBSTRING($id,4,12) AS UNSIGNED)) FROM $tbl WHERE $id LIKE '%web%'"
and then increment the id as web+(max+1).
Pseudo implementation would be
alter table definition
alter table `table` add column id int(11) not null auto_increment
change code
public function id_calc($tbl,$idcol) {
$sql = mysql_query("SELECT id FROM $tbl order by id desc limit 1");
if($sql){
while($row = mysql_fetch_assoc($sql));
$id = isset($row['id']) ? $row['id'] + 1 : 1;
return "{$idcol}{$id}";
}
}
Hope this helps

Get a record with maxid and condition in mysql in yii, but sometime it get second record?

my table:
CREATE TABLE IF NOT EXISTS `the_kho_chi_tiet_with_id` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ngay_thang` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`ma_phieu` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`id_san_pham` int(11) NOT NULL,
`id_kho` int(11) NOT NULL,
`khoi_luong_nhap` double NOT NULL,
`so_luong_nhap` int(11) NOT NULL,
`khoi_luong_xuat` double NOT NULL,
`so_luong_xuat` int(11) NOT NULL,
`khoi_luong_ton` double NOT NULL,
`so_luong_ton` int(11) NOT NULL,
`kho_du_tru` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
PHP code:
$sql = "SELECT so_luong_ton, khoi_luong_ton, kho_du_tru FROM the_kho_chi_tiet_with_id WHERE id_kho = $id_kho and id_san_pham = $id_san_pham ORDER by id DESC LIMIT 1";
$command=$connection->createCommand($sql);
$dataReader=$command->queryAll();
if($dataReader!=null)
{
foreach($dataReader as $row)
{
.................
}
}
**Get a record with maxid and condition in mysql in yii, *but sometime it get second record* !?**
Please check with the below, hope it works!..if not please tell...
$id_kho=373;//sample value declaration
$id_san_pham=1;//sample value declaration
$select="select max(id) as id,so_luong_ton, khoi_luong_ton, kho_du_tru from
the_kho_chi_tiet_with_id where users_ref_id=".$id_kho." and
status=".$id_san_pham;
$command = Yii::app()->db->createCommand($select)->queryRow();
$Maxid=$command['id'];
$so_luong_ton=$command['so_luong_ton'];
$khoi_luong_ton=$command['khoi_luong_ton'];
$kho_du_tru=$command['kho_du_tru'];
I think, the problem is conflict. It mean that when I get record have max_id, and then before i insert new record, having another process insert new record was inserted.
if such cases happen, so how to handle to fix above problem?
My solution:
$lock = $connection->createCommand('LOCK TABLES `the_kho_chi_tiet_with_id` READ');
$lock->execute();
$sql = "SELECT so_luong_ton, khoi_luong_ton, kho_du_tru FROM the_kho_chi_tiet_with_id WHERE id_kho = $id_kho and id_san_pham = $id_san_pham ORDER by id DESC LIMIT 1";
$command=$connection->createCommand($sql);
$dataReader=$command->queryAll();
if($dataReader!=null)
{
foreach($dataReader as $row)
{
.................
}
}
//Insert new record here
TheKhoChiTietWithId::model()->InsertNewRecord(1,300,1,333,1);
$unlock = $connection->createCommand('UNLOCK TABLES');
$unlock->execute();
I lock table to keep no other session work to this table.

SQL query retrieve fields from current date

This is my database SQL code;
CREATE TABLE ProductType
(
ptID int not null auto_increment,
pType varchar(30),
PRIMARY KEY(ptID)
)ENGINE=InnoDB;
CREATE TABLE Service
(
sID int not null auto_increment,
description varchar(30) not null,
revenue int,
stID int not null,
PRIMARY KEY(sID),
FOREIGN KEY(stID) references ServiceType(stID)
)ENGINE=InnoDB;
CREATE TABLE Product
(
pID int not null auto_increment,
model varchar(30) not null,
cogs int,
ptID int not null,
PRIMARY KEY(pID),
FOREIGN KEY(ptID) references ProductType(ptID)
)ENGINE=InnoDB;
CREATE TABLE Sale
(
saleID int not null auto_increment,
assetID int not null,
eID int not null,
sID int not null,
pID int,
saDate date not null,
PRIMARY KEY(saleID),
FOREIGN KEY(eID) references Employee(eID),
FOREIGN KEY(sID) references Service(sID),
FOREIGN KEY(pID) references Product(pID)
)ENGINE=InnoDB;
CREATE TABLE Employee
(
eID int not null auto_increment,
firstName varchar(30) not null,
lastName varchar(30) not null,
phone varchar(30),
email varchar(30),
PRIMARY KEY(eID)
)
This is my attempt but I don't know how to access the 'revenue' field from 'Service' when I am querying the 'Sale' table.
<?php
// Make a MySQL Connection
mysql_connect("localhost", "root", "root") or die(mysql_error());
mysql_select_db("pnl") or die(mysql_error());
// Retrieve all the data from the "example" table
$result = mysql_query("SELECT * FROM Sale WHERE saDate = CURDATE()")
or die(mysql_error());
// store the record of the "example" table into $row
$row = mysql_fetch_array( $result );
// Print out the contents of the entry
echo "revenue: ".$row['revenue'];
?>
Can anyone give me an example of how I would write a php script to retrieve the revenue of all sales for the current date?
Also this was my first attempt at SQL and relational database models, so if you notice any critical mistakes I've made or things I can improve please let me know!
Try this way. Name the SUM field and access it by given name:
// Retrieve all the data from the "example" table
$result = mysql_query("SELECT SUM(Service.revenue) sum FROM Service JOIN Sale ON Sale.sID = Service.sID WHERE Sale.saDate = $some_date") or die(mysql_error());
// store the record of the "example" table into $row
$row = mysql_fetch_array( $result );
// Print out the contents of the entry
echo "revenue: ".$row['sum'];
If sID on sales and Service both are same and unique to every sales then you can use query like this:
$result = mysql_query(SELECT Sale.saleID, Sale.assetID, Sale.eID, Sale.sID, Sale.pID, Sale.saDate, Service.revenue "."FROM Sale, Service "."WHERE Sale.sID = Service.sID AND Sale.saDate = CURDATE()) or die(mysql_error());
Or if Service.sID = Sale.saleID then change acordingly.
This way you can control which column exactly you would like to retrive from each table.

Categories