How to insert multiple row with different ID in Laravel - mysql

I need a way to insert multiple rows into sql table, and return all inserted different primary key ids with one sql query.
foreach($request->size as $key => $value)
{
$size = new sizes;
$size->size_name = $request->size[$key];
$size->size_price = $request->sizeprice[$key];
$size->pid = $last_id;
$size->save();
$size_last_id = $size->id;
}
foreach($request->stock as $key => $value)
{
$stock = new stocks;
$stock->pid = $last_id;
$stock->size_id = $size_last_id;
$stock->stock_qty = $request->stock[$key];
$stock->save();
}
Please find the attached this image.
https://i.stack.imgur.com/LsJHZ.png

$size_last_id = $size->id;
Above code will return only last inserted row's id as you are inserting data using foreach loop.
Better to store all the ids in an array, declare a variable as an array and push id to array.
Sample code.
$size_last_id = [];
foreach($request->size as $key => $value)
{
$size = new sizes;
$size->size_name = $request->size[$key];
$size->size_price = $request->sizeprice[$key];
$size->pid = $last_id;
$size->save();
array_push($size_last_id, $size->id);
}
This will store all the inserted ids to array.
Read More about array_push
Hope this will be useful.

Related

Entering an array to the firstOrCreate generates an error Laravel 5.7

I am running the firstOrCreate on my controller with the following code:
private function validateNumberBD($areaCodes,$numbers){
$arrayAreaCodes = array();
foreach ($areaCodes as $key => $value) {
$arrayAreaCodes[] = $value->AREACODES_ID;
}
$consultArray = array();
for($i = 0; $i < count($numbers); $i++){
for($j = 0; $j < count($arrayAreaCodes);$j++){
$consultArray[] = (['PHONE' => $numbers[$i],'AREACODES_ID' => $arrayAreaCodes[$j]]);
}
}
//dd($consultArray);
$searchOrCreate = Phone::firstOrCreate($consultArray);
}
My problem is generated since executing that code generates the following error:
If I do a dd () to my $ consultArray variable, it shows me the following array
If I change the position of the array values, I get this error:
Consulting the new array would look like this.
I think my mistake is in how to list the data, but I really don't know what else to do.
In query mode, how do I know how many values ​​the firstOrCreate creates for me?
firstOrCreate cannot check or insert multiple records and you are sending an array of arrays.
for($i = 0; $i < count($numbers); $i++){
for($j = 0; $j < count($arrayAreaCodes);$j++){
$searchOrCreate = Phone::::firstOrCreate(
['PHONE' => $numbers[$i], 'AREACODES_ID' => $arrayAreaCodes[$j]]);
}
}
This could work.

Yii2 ActiveRecord add a new record with unique text field

I am using Yii2 and ActiveRecord. I have a field called "code" and for each record, it is meant to have a unique value like this: "REC0001", "REC0002", "REC0003" in a sequencial manner.
All works and I can generate a record code as described. However if I refresh my page request fast in a multiple manner (trying to test multiple requests at the same time in a very raw manner hehe), then some of the records end up with the same record code. In other words I found "REC007" a few times.
I generate the code looking at the last code and increase it by one, then I do a while foundFlag == true by checking to see if it already exists in the database.
I am suspecting there is a delay in writing to the database and hence it assumes that it is not there.
Here is a portion of the code:
static function createCode($rec){
if ($rec->code){
return $rec->code;
}
if ($rec->id){ // find it by id if one passed and record exists
$tmpRec = $rec->find()
->where([
'id' => $rec->id,
])
->one();
if ($tmpRec && $tmpRec->code){
return $tmpRec->code;
}
}
$prefix = 'REC';
if (!$prefix){
$prefix = 'REC';
}
$maxDecimals = 12;
$codeLength = $maxDecimals+strlen($prefix);
$query = $rec->find();
$query = $query->where([
'archived' => '0'
]);
// look under an organization if it exists in the model and there is one
if ($rec->hasField('organization_id') && $organization_id){
$query = addQueryWhere($query, [
'organization_id' => $organization_id,
]);
}
$query = addQueryWhere($query, [
'LENGTH(code)' => $codeLength*1,
]);
$query = $query->orderBy('code desc');
$lastRec = $query->one();
$tmpNumber = 0;
if ($lastRec && $lastRec->id){
// check what it returns
$tmpNumber = str_replace($prefix, '', $lastRec->code);
}
$tmpNumber++;
$leftDecimals = $maxDecimals - strlen($tmpNumber.'');
for ($k=0; $k <= $leftDecimals-1 ; $k++){
$tmpNumber = '0'. $tmpNumber;
}
$ret = $prefix . $tmpNumber;
return $ret;
}
public function generateCode($rec){
$foundFlag = true;
$break = 1000; // safe break point - no continuous loop
$cnt = 0;
$code = static::createCode($rec);
while ($foundFlag === true || $cnt < $break){
$tmpRec = $rec->find()
->where([
'code' => $code,
])
->one();
if (!$tmpRec->id){
$foundFlag = false;
break;
}
$time = getCurrentTimestamp();
$code = static::createCode($rec);
$cnt++;
}
$ret = $code;
return $ret;
}
So I simply call: $this->code = $this->generateCode();
Like I said it does work in generating the code, but it creates duplicates when it shouldn't!
Thank you for your assistance.

Creating Json file from mysql

i can't get more than one return in this json. when the original query returns 90k results.
i can't figure out what's hapening.
also the return i get isn't organized as it should. it return the following
{"material":["R8190300000","0"],"grid":["R8190300000","0"]}
sorry to ask this i have been looking for an answer but couln't get it in the internet.
<?php
$link = mysqli_connect("localhost","blablabla","blablabla","blablabla");
if (mysqli_connect_error()) {
die("Could not connect to database");
}
$query =" SELECT material,grid FROM ZATPN";
if( $result = mysqli_query( $link, $query)){
while ($row = mysqli_fetch_row($result)) {
$resultado['material']=$row;
$resultado['grid']=$row;
}
} else {
echo"doesnt work";
}
file_put_contents("data.json", json_encode($resultado));
?>
The problem is that you are overriding the value for the array keys:
$resultado['material']=$row;
$resultado['grid']=$row;
At the end you will have only the last 2 rows; I suggest you to use something like:
$resultado['material'][] = $row;
$resultado['grid'][] = $row;
This will save you pair rows in $resultado['grid'] and unpaired rows in $resultado['material'];
After the information in comments you can use this code:
$allResults = array();
while ($object = mysqli_fetch_object($result)) {
$resultado['id'] = $object->id;
$resultado['name'] = $object->name;
$resultado['item'] = $object->item;
$resultado['price'] = $object->price;
$allResults[] = $resultado;
}
file_put_contents("data.json", json_encode($allResults));

Deleting row from table in mysql database

I am trying to delete a certain item from a database depending on conditions. Here is what I have:
while ($row = mysql_fetch_array($result)) {
$now = strtotime("now");
$dateArray = date_parse_from_format("n-j-Y", $row["date"]);
$event_date = strtotime($dateArray['year'].'-'.$dateArray['month'].'-'.$dateArray['day']);
// temp user array
$event = array();
if($event_date > $now) {
//Event is in the future
$pid_check =$row["pid"];
$event["pid"] = $row["pid"];
$event["name"] = $row["name"];
$event["longitude"] = $row["longitude"];
$event["latitude"] = $row["latitude"];
$event["pavement"] = $row["pavement"];
$event["traffic"] = $row["traffic"];
$event["environment"] = $row["environment"];
$event["image_b64"] = $row["image_b64"];
$event["date"] = $row["date"];
$event["time"] = $row["time"];
$event["type"] = $row["type"];
// push single product into final response array
array_push($response["events"], $event);
} else {
$result2 = mysql_query("DELETE FROM events WHERE pid = $pid_check");
}
}
But when I try this it comes up blank, when I comment out result2 it works but doesn't delete(duh). How can I get it to delete? Sorry if this is a simple question, my knowledge of the language is not much.
I think $pid_check is getting set only if the condition in your if is TRUE.
It's not getting set for the else branch.
One option is to relocate the assignment of $pid_check before the if test.

code igniter active records - help streamlining process

I am currently using the below code to get a list of uuid's then split them into groups of 1000, then insert those groups into the database.
This works fine except this has to work on at times, over a million uuid's
The issue is this uses a massive amount of memory, so I need help to streamline this process to use less memory...
public function send_daily_email($dealId) {
set_time_limit(0);
$deal = $this->ci->deal->get($dealId);
if ($deal == false)
throw new exception('Unknown Deal Specified');
$users = $this->db->select('uuid')->from('userRegionLink')->where('regionId', $deal->region)->get();
if ($users->num_rows() == 0)
throw new exception('No users in region');
$message = $this->ci->load->view('emails/daily', array('name' => $deal->title, 'content' => $deal->snippet), true);
$uuids = array();
foreach ($users->result() as $u)
$uuids[] = $u->uuid;
$uuids = array_chunk($uuids, 1000);
$sendId = 0;
foreach ($uuids as $batch) {
$count = count($batch);
$this->db->set('dealId', $dealId)->set('content', $message)->set('regionId', $deal->region)->set('recipients', $count)->set('created', 'NOW()', false)->set('status', 'Creating');
if ($sendId === 0) {
$this->db->insert('dealEmailParent');
$sendId = $this->db->insert_id();
$this->db->set('sendId', $sendId)->where('id', $sendId)->update('dealEmailParent');
}
else
$this->db->set('sendId', $sendId)->insert('dealEmailParent');
$insert = array();
foreach ($batch as $uuid)
$insert[] = array('parentId' => $sendId, 'uuid' => $uuid);
$this->db->insert_batch('dealEmailChild', $insert);
}
}
I hate to say this, but from what I know about CodeIgniter, the only way it knows to fetch results is to fetch the entire resultset at once, even if you only need one row, or even if you want to fetch a row at a time and do some processing. It doesn't operate with cursors as the native mysql(i)/PDO functionality does.
For this large a dataset, I'd suggest sticking to the native PHP database functions and foregoing CodeIgniter's active record database classes.
This reworking can insert 1,000,000 "users" in under a minute without any memory limits :)
public function create_daily_email($dealId)
{
$time_start = microtime(true);
set_time_limit(0);
$deal = $this->ci->deal->get($dealId);
if ($deal == false)
throw new exception('Unknown Deal Specified');
$message = $this->ci->load->view('emails/daily', array('name' => $deal->title, 'content' => $deal->snippet), true);
$start = 0;
$end = 50000;
$q = $this->db->select('uuid')->from('userRegionLink')->where('regionId', $deal->region)->limit($end, $start)->get();
$sendId = 0;
while ($q->num_rows() != 0) {
//do stuff
$uuids = array();
foreach ($q->result() as $u)
$uuids[] = $u->uuid;
$uuids = array_chunk($uuids, 1000);
foreach ($uuids as $batch) {
$count = count($batch);
$this->db->set('dealId', $dealId)->set('content', $message)->set('regionId', $deal->region)->set('recipients', $count)->set('created', 'NOW()', false)->set('status', 'Creating');
if ($sendId === 0) {
$this->db->insert('dealEmailParent');
$sendId = $this->db->insert_id();
$this->db->set('sendId', $sendId)->where('id', $sendId)->update('dealEmailParent');
$parentId = $sendId;
}
else {
$this->db->set('sendId', $sendId)->insert('dealEmailParent');
$parentId = $this->db->insert_id();
}
$insert = array();
foreach ($batch as $uuid) {
$insert[] = array(
'parentId' => $parentId,
'uuid' => $uuid
);
}
$this->db->insert_batch('dealEmailChild', $insert);
}
//stop stuff
unset($q);
unset($uuids);
unset($insert);
$start = $start + $end;
$q = $this->db->select('uuid')->from('userRegionLink')->where('regionId', $deal->region)->limit($end, $start)->get();
}
$this->db->set('status', 'Pending')->where('sendId', $sendId)->update('dealEmailParent');
$time_end = microtime(true);
$time = $time_end - $time_start;
die("Did nothing in $time seconds");
}