Insert multiple rows using a single query - joomla

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();

Related

Codeigniter update_batch in Core PHP

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

Propel ORM: Order By FIELD

I'm trying to do a query with a custom "order by" with Propel 1.6
select * from myObject ORDER BY FIELD(id, 3, 11, 7, 1)
this does not work:
myObjectQuery::create()
->orderById($someIds)
->find()
how can i do?
$ids = array(3, 11, 7, 1);
$cids = implode(',', $ids);
myObjectQuery::create()
->addAscendingOrderByColumn("FIELD (tableName.id, {$cids})")
->find()
you can stack order-by's in order that you want:
myObjectQuery::create()
->orderByField1
->orderbyField3('desc')
->orderbyField2
->find()
Try that.
Update 2:
$con = Propel::getConnection();
$query = 'SELECT COUNT(t1.user) AS users, t1.choice AS lft, t2.choice AS rgt
FROM choice t1 iNNER JOIN choice t2 ON (t1.user = t2.user)
WHERE t1.choice IN (?, ?) AND t2.choice IN (?, ?)
GROUP BY t1.choice, t2.choice';
$stmt = $con->prepare($query);
$stmt->bindValue(1, 'foo');
$stmt->bindValue(2, 'bar');
$stmt->bindValue(3, 'baz');
$stmt->bindValue(4, 'foz');
$res = $stmt->execute();
in your case, I would establish $con, create a query to get your value list, then use a for loop to assign your $stmt->bindValue(#,#) and then execute.
$ids = array(3, 11, 7, 1);
$cids = implode(',', $ids);
myObjectQuery::create()
->orderBy("FIELD(id, {$cids})")
->find()

Active record of not in

$this->db->query('DELETE FROM default_model WHERE cat_id NOT IN (SELECT id FROM default_category)');
the active record format for this query
$query = $this->db->select('id')
->get('category')->result();
$this->db->where_not_in('cat_id',$query )
->delete('model');
I tried a lot but could not do it. How to pass $query
The query results are returned as standard objects. Therefore you need to fetch the ids from the returned objects in a non associative array before passing that array to the delete query.
Like this:
$result = $this->db->select('id')->get('category')->result();
$ids = [];
foreach($result as $result)
$ids[] = $result->id;
$this->db->where_not_in('cat_id', $ids)->delete('model');

How do you write a 'not in' select statement in Joomla 2.5 SQL?

Please explain how to write the commented out line in Joomla in the query below.
I can't figure it out using the documentation; that has only the simplest of queries.
function getUsersFromDatabase()
{
$db = JFactory::getDBO();
$query = $db -> getQuery(true);
$query
->select($db->quoteName(array('u.id', 'u.name', 'u.username', 'u.email')))
->from($db->quoteName('#__users', 'u'))
//->where($db->quoteName('u.id') . ' not in (select m.user_id from ' . $db->quoteName('#__user_usergroup_map', 'm') .' where ' . $db->quoteName('m.group_id') . ' in (4,19))') //no admins or superusers
->order($db->quoteName('u.name') . ' ASC');
$db ->setQuery($query);
$result = $db -> loadObjectList();
return $result;
}
You don't have to use Joomla's restrictive SQL querying platform to query your database. You can do the following:
$db = JFactory::getDBO();
$sql = "YOUR SQL QUERY";
$db->setQuery($sql);
$result = $db->loadAssocList();
Major extension, including K2, use the above straightforward method (they don't use Joomla's restrictive SQL).
Try this,
There is some alternate options like below,
$query
->select('*')
->from('products')
->where('category = ' . $db->q('catA'))
;
$q2
->select('*')
->from('products')
->where('category = ' . $db->q('catB'))
;
$query->union($q2);
$products = $db->setQuery($query)->loadObjectList();
There is some performance boostup with Joomla3.x using union. and it have some restriction over Joomla older versions.
Hope it helps..

jdatabase no numbers appearing in article

I am testing outputting a query in a article in Joomla 3.0.2 via Sorcerer.
When i output the array storing the query only values that are no numbers are appearing.
E.g. say i have 2 rows in a table called 'goofy' like this
id, description
1, test
2, test2
My code then looks like this
$query = "SELECT * FROM goofy";
$db->setQuery($query);
$results = $db->loadAssocList();
print_r($results);
The output I am getting in the article is like this;
Array ( [0] => Array ( [id] => [description] => test ) [1] => Array ( [id] => [description] => test2 ) )
Any ideas why the numbers wont output?
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('*');
$query->from('goofy');
$db->setQuery($query);
$results = $db->loadAssocList();
print_r($results);
You haven't specified the table name correctly. When using database queries, you have to add the prefix onto the table name. You also need to call the database using $db = JFactory::getDBO();
So your query should be like this:
$db = JFactory::getDBO();
$query = "SELECT * FROM #__goofy";
$db->setQuery($query);
$results = $db->loadAssocList();
print_r($results);
If you database table isn't Joomla related, then you don't need to use the #__ prefix.

Resources