This article shows how to write/run/execute custom SQL queries in Magento 2. We need to instantiate class Magento\Framework\App\ResourceConnection
for this. You have to inject this resource class in your module’s Block/Model/Controller class constructor. After that, you can use that object to run custom sql queries.
In this example, I will simply be using object manager to instantiate the resource class.
Suppose, I have a table named mytest
with fields id
, name
, age
, & email
.
CREATE TABLE IF NOT EXISTS `mytest` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`age` tinyint(3) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
The following example code will insert, update, delete and select records from the table mytest
.
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
$connection = $resource->getConnection();
$tableName = $resource->getTableName('mytest'); // the table name in this example is 'mytest'
// INSERT DATA
$name = 'Mukesh Chapagain';
$age = 99;
$email = 'mukesh@example.com';
$sql = "INSERT INTO " . $tableName . " (id, name, age, email) VALUES ('', '$name', $age, '$email')";
$connection->query($sql);
$sql = "INSERT INTO " . $tableName . " (id, name, age, email) VALUES ('', 'Hello World', 88, 'hello@example.com')";
$connection->query($sql);
// SELECT DATA
$sql = "SELECT * FROM " . $tableName;
$result = $connection->fetchAll($sql);
echo '<pre>'; print_r($result); echo '</pre>';
// UPDATE DATA
$id = 1; // table row id to update
$sql = "UPDATE " . $tableName . " SET name = 'Your Name', email = 'your-email@example.com' WHERE id = " . $id;
$connection->query($sql);
// DELETE DATA
$id = 1; // table row id to delete
$sql = "DELETE FROM " . $tableName . " WHERE id = " . $id;
$connection->query($sql);
In the above code, when we run the select query using fetchAll
function, the following output is obtained. It returns a multi-dimentional array with table field name and value.
Array
(
[0] => Array
(
[id] => 1
[name] => Mukesh Chapagain
[age] => 99
[email] => mukesh@example.com
)
[1] => Array
(
[id] => 2
[name] => Hello World
[age] => 88
[email] => hello@example.com
)
)
Instead of writing the whole select query by ourselves, we can also use the SQL SELECT Query generation functions that are already provided by Magento and Zend_Db_Select
. Here’s an example code:
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
$connection = $resource->getConnection();
$tableName = $resource->getTableName('mytest'); // the table name in this example is 'mytest'
// SELECT DATA
$id = 2;
$fields = array('id', 'name');
$sql = $connection->select()
->from($tableName) // to select all fields
//->from($tableName, $fields) // to select some particular fields
->where('id = ?', $id)
->where('age > ?', 30); // adding WHERE condition with AND
$result = $connection->fetchAll($sql);
echo '<pre>'; print_r($result); echo '</pre>';
You can see in detail about this in class Magento\Framework\DB\Select
present in vendor/magento/framework/DB/Select.php
.
/**
* Class for SQL SELECT generation and results.
*
* @method \Magento\Framework\DB\Select from($name, $cols = ‘*’, $schema = null)
* @method \Magento\Framework\DB\Select join($name, $cond, $cols = ‘*’, $schema = null)
* @method \Magento\Framework\DB\Select joinInner($name, $cond, $cols = ‘*’, $schema = null)
* @method \Magento\Framework\DB\Select joinLeft($name, $cond, $cols = ‘*’, $schema = null)
* @method \Magento\Framework\DB\Select joinNatural($name, $cond, $cols = ‘*’, $schema = null)
* @method \Magento\Framework\DB\Select joinFull($name, $cond, $cols = ‘*’, $schema = null)
* @method \Magento\Framework\DB\Select joinRight($name, $cond, $cols = ‘*’, $schema = null)
* @method \Magento\Framework\DB\Select joinCross($name, $cols = ‘*’, $schema = null)
* @method \Magento\Framework\DB\Select orWhere($cond, $value = null, $type = null)
* @method \Magento\Framework\DB\Select group($spec)
* @method \Magento\Framework\DB\Select order($spec)
* @method \Magento\Framework\DB\Select limitPage($page, $rowCount)
* @method \Magento\Framework\DB\Select forUpdate($flag = true)
* @method \Magento\Framework\DB\Select distinct($flag = true)
* @method \Magento\Framework\DB\Select reset($part = null)
* @method \Magento\Framework\DB\Select columns($cols = ‘*’, $correlationName = null)
*
*/
Note: If you are running your script in custom external file then you need to write the following code to instantiate ObjectManager. Otherwise, you might get the following error:
Fatal error: Class ‘Magento\Framework\App\ObjectManager’ not found
So, here is the solution to it. In the code below, I have selected data from table eav_entity_type
using custom sql script.
use Magento\Framework\App\Bootstrap;
//require __DIR__ . '/app/bootstrap.php'; // you can use this if your custom file is in your magneto root directory
$rootDirectory = '/var/www/html/magento2'; // YOUR MAGENTO ROOT DIRECTORY
require $rootDirectory . '/app/bootstrap.php';
$params = $_SERVER;
$bootstrap = Bootstrap::create(BP, $params);
$objectManager = $bootstrap->getObjectManager();
$resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
$connection = $resource->getConnection();
$tableName = $resource->getTableName('eav_entity_type'); // accessing table 'eav_entity_type'
// SELECT DATA
$sql = "SELECT * FROM " . $tableName;
$result = $connection->fetchAll($sql);
echo '<pre>'; print_r($result); echo '</pre>';
Hope this helps. Thanks.