Codeigniter update_batch in Core PHP - codeigniter

everyone.
In the codeigniter there is update_batch function by using it we are able to bulk update multiple rows.
$this->db->update_batch('table_name', $update_data_array, 'where_condition_field_name');
I want similar functionality in core PHP in one function or in one file. Is there any workaround?
Is there any way to extract update_batch function from Codeigniter in one file/function?
I tried to extract this function but it is very lengthy process and there will be many files / functions should be extracted.
Please help me in this regard
Thanks in advance

You can also insert multiple rows into a database table with a single insert query in core php.
(1)One Way
<?php
$mysqli = new mysqli("localhost", "root", "", "newdb");
if ($mysqli == = false) {
die("ERROR: Could not connect. ".$mysqli->connect_error);
}
$sql = "INSERT INTO mytable (first_name, last_name, age)
VALUES('raj', 'sharma', '15'),
('kapil', 'verma', '42'),
('monty', 'singh', '29'),
('arjun', 'patel', '32') ";
if ($mysqli->query($sql) == = true)
{
echo "Records inserted successfully.";
}
else
{
echo "ERROR: Could not able to execute $sql. "
.$mysqli->error;
}
$mysqli->close();
? >
(2)Second Way
Let's assume $column1 and $column2 are arrays with same size posted by html form.
You can create your sql query like this:-
<?php
$query = 'INSERT INTO TABLE (`column1`, `column2`) VALUES ';
$query_parts = array();
for($x=0; $x<count($column1); $x++){
$query_parts[] = "('" . $column1[$x] . "', '" . $column2[$x] . "')";
}
echo $query .= implode(',', $query_parts);
?>

You can easily construct similar type of query using PHP.
Lets use array containing key value pair and implode statement to generate query.
Here’s the snippet.
<?php
$coupons = array(
1 => 'val1',
2 => 'va2',
3 => 'val3',
);
$data = array();
foreach ($coupons AS $key => $value) {
$data[] = "($key, '$value')";
}
$query = "INSERT INTO `tbl_update` (id, val) VALUES " . implode(', ', $data) . " ON DUPLICATE KEY UPDATE val = VALUES(val)";
$this->db->query($query);
?>
Alternatively, you can use CASE construct in UPDATE statement. Then the query would be something
like:
UPDATE tbl_coupons
SET code = (CASE id WHEN 1 THEN 'ABCDE'
WHEN 2 THEN 'GHIJK'
WHEN 3 THEN 'EFGHI'
END)
WHERE id IN(1, 2 ,3);

Related

check data that is not in array with 2 value matches

I have 2 arrays and I want to check those arrays with 2 value matches,
if those 2 value not matches I want to insert into database.
Code I have tried :
$data1 = {['reg_no'=>123,'name'=>'John'],['reg_no'=>1234,'name'=>'Lisa']};
$data2 = {['reg_no'=>123,'name'=>'John'],['reg_no'=>1234,'name'=>'Lisa'],['reg_no'=>12345,'name'=>'Roger']};
foreach($data1 as $d1)
foreach($data2 as $d2)
if($d1['reg_no'] != $d2['reg_no'] && $d1['name'] != $d2['name'])
//insert into database
// this not work because it will enter all data that not match
endif
endforeach
endforeach
you can use FirstOrNew Or FirstOrCreate in laravel.
like insert if not exist
$students = User::firstOrNew(['student_id' => $request->student_id, 'course_code' => $request->course_code]);
$students->foo = $request->foo;
$students->save();
$data1 = {['reg_no'=>123,'name'=>'John'],['reg_no'=>1234,'name'=>'Lisa']};
$data2 = {['reg_no'=>123,'name'=>'John'],['reg_no'=>1234,'name'=>'Lisa'],['reg_no'=>12345,'name'=>'Roger']};
$data = array_uintersect($data1, $data2, "strcasecmp");
if($data['reg_no'] != $data1['reg_no'] && $data2['reg_no']) {
// insert
}

Make unique invoice numbers with mysql and use

At the moment this is my function to create a random unique invoice number which is stored in a form's hidden field
function generate_invoice_number() {
global $wpdb;
$lastVisitor = $wpdb->get_results("SELECT visitorID FROM event_visitors_2014 ORDER BY visitorsID DESC LIMIT 1", ARRAY_A);
$nr_last = $lastVisitor[0]['visitorID'];
$nr = 501 + $nr_last;
$value = sprintf( '%04d', $nr );
$number = 'LEDEXPO'.date('Y').'-'.uniqid().'-'.$value;
return $number;
}
I have a problem when multiple people are using the form at the same time, say 3 people are using the form they all have the same number generate.
So i added uniqid(), so $value could be duplicated but $number should be unique? Is this correct or is there a better way?
How can i make test function to test this function on uniqueness?
regards
Try This:
function generate_invoice_number()
{
global $wpdb;
$lastVisitor = $wpdb->get_results("SELECT visitorID FROM event_visitors_2014 ORDER BY visitorsID DESC LIMIT 1", ARRAY_A);
$nr_last = $lastVisitor[0]['visitorID'] + 1;
$number = date('Ymd') . $nr_last;
return $number;
}

Bind params for the bulk INSERT query? (avoid SQL injections)

I want to do some mass DB population from Excel file.
The most time economic way is to use INSERT INTO statement with lots of values to be stored in one transaction:
INSERT INTO `assortment`(`id`, `sku`, `agroup`, `subgroup`, `title`, `measure_unit`, `price`, `discount`, `imageUrl`, `fileUrl`)
VALUES ([value-1],[value-2],[value-3],[value-4],[value-5],[value-6],[value-7],[value-8],[value-9],[value-10]),
([value-1],[value-2],[value-3],[value-4],[value-5],[value-6],[value-7],[value-8],[value-9],[value-10]),
([value-1],[value-2],[value-3],[value-4],[value-5],[value-6],[value-7],[value-8],[value-9],[value-10]),
([value-1],[value-2],[value-3],[value-4],[value-5],[value-6],[value-7],[value-8],[value-9],[value-10]),
...
Yet, to avoid SQL injection i wish to bind params, the yii providing functionality for that. Yet, it seems impossible for me to do it for hundredes/thousands of values. Isn't it?
To keep SQL hygene i did the simple insert thru Active Record attributes (Yii AR functionality sanitizes input data by default):
$auxarr = array();
for ($i = 0; $sheetData[$i]; $i++)
{
$model = new Assortment();
$j = 0;
foreach ($labels as $label)
{
$auxarr[$label] = $sheetData[$i][$j++];
}
$model->attributes = $auxarr;
if (!$model->save())
throw new CHttpException(400, 'Error db storing');
}
This approach obviously being time non-efficient.
Is there any way that would feature both security and time efficiency in the bulk SQL inserting?
Yii is using conventional PDO in CDbCommand.
So, you can create a string consists of series values like this
(?,?,?),(?,?,?),(?,?,?),(?,?,?),(?,?,?),(?,?,?)
then create an array with values for all these placeholders
and finally execute all the stuff
My approach is
$sql = "INSERT INTO `assortment`(`id`, `sku`, `agroup`, `subgroup`, `title`, `measure_unit`, `price`, `discount`, `imageUrl`, `fileUrl`) VALUES "
$params = array();
$cntRows = count($sheetData);
for ($i = 0; $i < $cntRows; $i++)
{
$j = 0;
$rowParams = array();
foreach ($labels as $label)
{
$rowParams[":{$label}_{$i}_{j}"] = $sheetData[$i][$j++];
}
$params = array_merge($params, $rowParams);
$sql . = "(" . implode(",", array_keys($rowParams) ) .")"
}
/*
Sql now is : INSERT INTO assortment (....) VALUES ( :id_1_1 , sku_1_1 , ... ) (:id_2_1 , sku_2_1 , ...)
AND $params is { :id_1_1 => [value] ........ }
*/
$cmd = Yii::app()->db->createCommand($sql);
$cmd->execute($params);
We excute insert sql in one transaction, no multiple transactions or use ActiveRecord (waste memory and many functions are executed) and avoid SQL injections. If your data is large you can split it to multiple transactions.

display results on query basis in Codeigniter with Pagination

I have a table of products. I need to display all the products. I am fetching results on different conditions.
create table `products` (
`id` double ,
`category_id` double ,
`subcategory_id` double ,
`product_name` varchar (765),
`product_description` varchar (765),
`product_viewed` varchar (765),
`sale_wanted` tinyint (2),
`added_date` datetime ,
`updated_date` datetime ,
);
I need to diplay the results like this
1. The latest products (use of added date)
2. Most Wanted (Sorting by sale_wanted 1 for sale , 2 for wanted)
3. Most Viewed (Sorting by product_viewed)
4. Sorting by Specific Subcategory
All the results should display with pagination. This is all right if i first get the result. But if i walk with pagination links all the condition data is lost and the query fetches the results without any condition. How can i manage This situation. Please i dont need Code i need hints and suggestions. The other thing is that i am using Codeigniter's pagination class.
EDITED
Here is my Model Method i am using
public function getProductsList($per_page=5,$page=0)
{
$info = $this->input->post();
if(isset($info['type']))
{
$type = $info['type'];
if($type == 'most_wanted'){
$where = " AND sale_wanted = 1";
$order_by = " ORDER BY ldc.added_date desc";
}else if($type == 'most_viewed'){
$where = " ";
$order_by = " ORDER BY ldc.product_viewed desc";
}else{
$where = " ";
$order_by = " ORDER BY ldc.added_date desc";
}
}else if(isset($info['sale_wanted']) AND isset($info['subcategory_id'])){
$sale_wanted = $info['sale_wanted'];
$subcategory_id = $info['subcategory_id'];
$where = " AND sale_wanted = $sale_wanted AND ldc.subcategory_id = $subcategory_id";
$order_by = " ORDER BY ldc.added_date desc";
}else if(isset($info['keyword'])){
$keyword = $info['keyword'];
$search_type = $info['search_type'];
$where = " AND ldc.$search_type like '$keyword%'";
$order_by = " ";
}else{
$where = " ";
$order_by = " ";
}
$num = 0;
if($page != 0){
$num = ($page * $per_page) - $per_page;
}
$sql_query = "
SELECT
ldc.id,
ldc.product_name,
ldc.product_viewed,
DATE_FORMAT(ldc.added_date, '%m/%d/%Y') as added_date,
ifnull(dc.name,'Unknown') as category,
dpi.product_image
FROM default_products AS ldc
LEFT JOIN default_manufacturers as dm ON dm.id = ldc.manufacturer
LEFT JOIN default_category as dc ON dc.category_id = ldc.category_id
LEFT JOIN ((select product_id , product_image from default_product_images group by product_id) as dpi)
ON dpi.product_id = ldc.id
WHERE approved = 1
$where
$order_by
LIMIT $num,$per_page
";
$query = $this->db->query($sql_query);
return $query->result();
}
i would highly recommend these two Free tutorials on codeigniter pagination -
video tutorials, working sample code ( might need to update code to CI 2.1 ), and even some helpful info in the comments.
CodeIgniter from Scratch: Displaying & Sorting Tabular Data
http://net.tutsplus.com/tutorials/php/codeigniter-from-scratch-displaying-sorting-tabular-data/
CodeIgniter from Scratch: Search Results without Query Strings
http://net.tutsplus.com/tutorials/php/codeigniter-from-scratch-search-results-without-query-strings-2/

Insert multiple rows using a single query

Can Joomla's DB object add multiple rows at once? MySQL can do this like so:
INSERT INTO x (a,b)
VALUES
('1', 'one'),
('2', 'two'),
('3', 'three')
But can Joomla's own functions achieve the same thing in a single query? Currently I am doing a loop to insert each row (same table) in separate query. Not a good idea when dealing with tons of rows at once.
In your model you can do this:
$db = $this->getDBO();
$query = "
INSERT INTO x (a,b)
VALUES
('1', 'one'),
('2', 'two'),
('3', 'three')
";
$db->setQuery($query);
$db->query();
If you are outside your model you need to get the DB object like so:
$db = JFactory::getDBO();
You can use:
$db = JFactory::getDbo();
$query = $db->getQuery(true); // !important, true for every new query
$query->insert('#__table_name'); // #__table_name = databse prefix + table name
$query->set('`1`="one"');
$query->set('`2`="two"');
$query->set('`3`="three"');
/* or something like this:
$query->columns('`1`,`2`,`3`');
$query->values('"one","two","three"');
*/
$db->setQuery($query);
$db->query();
and $db->insertId() can return you autoinc id if you have one.
Try this, if you have values in an array :
$query = $this->db->getQuery(true);
$query->insert($this->db->quoteName('#__table_name'));
$query->columns($this->db->quoteName(array('col_1','col_2','col_3','col_4')));
for($i=0; $i < lengthOfArray; $i++)
{
$values= $arr_1[$i].','.$this->db->quote($arr_2[$i]).','.$this->db->quote($arr_3[$i]).','. $arr_4[$i];
$query->values($values);
}
$this->db->setQuery($query);
$result = $this->db->query();
You don't need $db = $this->getDBO();
just use this:-
$query = "
INSERT INTO x (a,b)
VALUES
('1', 'one'),
('2', 'two'),
('3', 'three')
";
$this->_db->setQuery($query);
$this->_db->query();
Try this:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->insert('x');
$query->columns('a,b');
$query->values('1', 'one');
$query->values('2', 'two');
$query->values('3', 'three');
$db->setQuery($query);
$db->query();
A description of "values" method
Adds a tuple, or array of tuples that would be used as values for an INSERT INTO statement.
Usage:
$query->values('1,2,3')->values('4,5,6');
$query->values(array('1,2,3', '4,5,6'));
In latest version of Joomla!, you can use it's own DB class as follows. Remember to use 'quoteName()' and 'quote()' functions as you needed.
$dbo = JFactory::getDbo();
$query = $dbo->getQuery(true);
$columns = array('col_one','col_two', 'col_three');
$values = array();
//if you need, here you can use forloop/foreach loop to populate the array
$values[] = 'val_1, val_2, val_3'; // first row values
$values[] = 'val_4, val_5, val_6'; // second row values
...
$query->insert($dbo->quoteName('#__table_name'));
$query->columns($columns);
$query->values($values);
$dbo->setQuery($query);
$dbo->query();
Hope this saves your time. Thanks. Happy coding! :)
...
$columns = array('user_id', 'type', 'object', 'lvl', 'date');
$values = array();
foreach ($batch as $row) {
$array = array(
$row->user_id,
$db->quote($row->type),
$db->quote($row->object),
$db->quote($row->lvl),
$db->quote($row->date),
);
$values[] = implode(',', $array);
}
$query->insert($db->quoteName('#activity_log'));
$query->columns($db->quoteName($columns));
$query->values($values);
$db->setQuery($query);
$result = $db->execute();

Resources