getting a last inserted varchar id which is an primary key - php

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

Related

How to set automatically id base on date

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.

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;
}

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.

Trying to get a list of team names a member is a part of via comparing 2 sql tables

Im trying to Get the users teams he is a part of to compare the 2 tables
DB TABLES:
CREATE TABLE `teams` (
`teamid` int(11) NOT NULL AUTO_INCREMENT,
`teamname` varchar(45) DEFAULT NULL,
`teamdesc` longtext,
`founder` varchar(45) NOT NULL,
`dateformed` int(11) NOT NULL,
PRIMARY KEY (`teamid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
CREATE TABLE `teammembers` (
`teamid` int(11) NOT NULL,
`member` varchar(45) NOT NULL,
`rank` varchar(45) DEFAULT NULL,
PRIMARY KEY (`teamid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Current function i have to do stuff:
/* removeProject */
function getTeamNames($id){
global $session, $database;
$link = $database->connection;
$stmt = $link->prepare("SELECT teamname FROM teams WHERE teamid=$id");
$stmt->execute();
$r = $stmt->fetch();
return array('teams'=>$r['teamname']);
}
Query to get the team names:
$link = $database->connection;
try{
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$q = "SELECT * FROM teammembers WHERE member=:un";
$prep = $link->prepare($q);
$array = array(
':un' => $user
);
$prep->execute($array);
}catch(PDOException $error){
echo($error);
}
Then the info to display the data:
<select multiple class="form-control">
<?php
while($tid = $prep->fetch()){
$teams = $database->getTeamNames($tid['teamid']);
echo ("<option>$teams</option>");
} ?>
</select>
Its only displaying the data as "Array"
UPDATE!!!
This is how i fixed it :)
while($tid = $prep->fetch()){
$teams = $database->getTeamNames($tid['teamid']);
//echo var_dump($teams);
$team = $teams['teams'];
echo ("<option>$team</option>");
}
The code is correct, you returned the data as array (return array('teams'=>$r['teamname']);)
So when you echo the data, use echo("<option>".$teams['teams']."</option>") or dont return result as an array.
Your function function getTeamNames($id) returns an associative array that's why you are not getting the results.
Your loop should look something like
<?php
while($tid = $prep->fetch()){
$teams = $database->getTeamNames($tid['teamid']);
foreach($teams['teams'] as $team){
echo ("<option>$teams</option>");
}
}
?>

how can I make loop within a loop in codeigniter?

I have table faq_categories with following fields
CREATE TABLE IF NOT EXISTS `faq_categories` (
`catid` int(11) NOT NULL AUTO_INCREMENT,
`categoryname` varchar(37) NOT NULL,
`parentid` int(11) DEFAULT NULL,
`description` text NOT NULL,
`metatags` text NOT NULL,
`sorder` int(11) NOT NULL,
`visible` tinyint(4) NOT NULL,
`categoryphoto` varchar(255) NOT NULL,
PRIMARY KEY (`catid`),
KEY `parentid_fk` (`parentid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=52 ;
In my php code I have the following code :
$query="SELECT * FROM categories";
$result=mysql_query($query);
$num=mysql_num_rows($result);
$i=0;
while ($i < $num) {
$id=mysql_result($result,$i,"id");
$name=mysql_result($result,$i,"name");
$parentid=mysql_result($result,$i,"parentid");
$categoryphoto=mysql_result($result,$i,"categoryphoto");
$sorder=mysql_result($result,$i,"sorder");
$visible=mysql_result($result,$i,"visible");
echo $id;
echo $name;
// THIS IS WHAT I DON'T KNOW HOW TO DO IN CODEIGNITER
// HOW TO GET THE CATEGORYNAME ON BASE ON PARENTID
if ($parentid) {
//echo $parentid;
$query1="SELECT name as parentname FROM categories WHERE id = ".$parentid;
echo mysql_result(mysql_query($query1),0,"parentname");
} else {
echo "Root Category";
}
How can I do this in codeigniter? If possible, I would like to avoid joins.
First: I think you can check Database class
Second: why don't you want use joins? If you hate it maybe you can use FROM table1,table2 :) IMHO lesser queries is better :)
EDIT
Install an sql-gui (e.g. phpMyAdmin, adminer...) and try some query! An example similar what you need:
SELECT *, catjoin.categoryname AS parentname
FROM categories
JOIN categories AS catjoin ON (catjoin.catid=categories.parentid)
You can extend catjoin.categoryname with IFNULL to returns ROOT category.

Categories