Magento - Module INSERT,UPDATE, DELETE, SELECT code - sql

I created a module and want to used core write and read function to insert,update,delete or select database value with condition, how can I do it without using SQL?
Example:
$customer_id=123
Model=(referral/referral)
SELECT
$collection3 = Mage::getModel('referral/referral')->getCollection();
$collection3->addFieldToFilter('customer_id', array('eq' => $customer_id));
foreach($collection3 as $data1)
{
$ref_cust_id.= $data1->getData('referral_customer_id');
}
INSERT
$collection1= Mage::getModel('referral/referral');
$collection1->setData('customer_id',$customer_id)->save();
DELETE,UPDATE(with condition)=???

Suppose, I have a module named mynews.
Here follows the code to select, insert, update, and delete data from the news table.
INSERT DATA
$data contains array of data to be inserted. The key of the array should be the database table’s field name and the value should be the value to be inserted.
$data = array('title'=>'hello there','content'=>'how are you? i am fine over here.','status'=>1);
$model = Mage::getModel('mynews/mynews')->setData($data);
try {
$insertId = $model->save()->getId();
echo "Data successfully inserted. Insert ID: ".$insertId;
} catch (Exception $e){
echo $e->getMessage();
}
SELECT DATA
$item->getData() prints array of data from ‘news’ table.
$item->getTitle() prints the only the title field.
Similarly, to print content, we need to write $item->getContent().
$model = Mage::getModel('mynews/mynews');
$collection = $model->getCollection();
foreach($collection as $item){
print_r($item->getData());
print_r($item->getTitle());
}
UPDATE DATA
$id is the database table row id to be updated.
$data contains array of data to be updated. The key of the array should be the database table’s field name and the value should be the value to be updated.
// $id = $this->getRequest()->getParam('id');
$id = 2;
$data = array('title'=>'hello test','content'=>'test how are you?','status'=>0);
$model = Mage::getModel('mynews/mynews')->load($id)->addData($data);
try {
$model->setId($id)->save();
echo "Data updated successfully.";
} catch (Exception $e){
echo $e->getMessage();
}
DELETE DATA
$id is the database table row id to be deleted.
// $id = $this->getRequest()->getParam('id');
$id = 3;
$model = Mage::getModel('mynews/mynews');
try {
$model->setId($id)->delete();
echo "Data deleted successfully.";
} catch (Exception $e){
echo $e->getMessage();
}
In this way you can perform select, insert, update and delete in your custom module and in any magento code.
Source: http://blog.chapagain.com.np/magento-how-to-select-insert-update-and-delete-data/

UPDATE is basically the combination of SELECT and INSERT. You load a collection, iterate over them setting the values as needed, then call ->save() on each model.
DELETE is handled directly via the ->delete() functon of models. So either load a single model or iterate over a SELECTed collection of them and call ->delete()
(Not that due to the iteration, this is not the 'fastest' way of doing these operations on collections (because each one is going to generate a new query, instead of a single query that handles multiple deletes at once), but the performance is fine for either small data sets/SELECTs (less than 1k?) or for things that you don't do very often (like importing or updating prices ok 10k products once per day).

FOR UPDATE
$new=$this->getRequest()->getParams();
$id=$new['id'];
$name=$new['name'];
$con=Mage::getModel('plugin/plugin')->load($id);
$con->setData('name',$name)->save();
echo "Update Success";
FOR DELETE
$id = $this->getRequest()->getParam('id');
$model = Mage::getModel('plugin/plugin');
$model->setId($id)->delete();
echo "Data deleted successfully.";

You can use select query like this also. its very easy.
$salesInvoiceCollection_sql = "SELECT `entity_id` , `increment_id`,`order_id`
FROM `sales_flat_invoice`
WHERE `erp_invoice_id` = 0
ORDER BY `entity_id`
DESC limit 1000";
$salesInvoiceCollection = Mage::getSingleton('core/resource')->getConnection('core_read')->fetchAll($salesInvoiceCollection_sql);

If you want to delete with condition based on collection you can use addFieldToFilter, addAttributeToFilter
$model = Mage::getModel('mynews/mynews')->getCollection();
try {
$model->addAttributeToFilter('status', array('eq' => 1));
$model->walk('delete');
echo "Data deleted successfully.";
} catch (Exception $e){
echo $e->getMessage();
}

Related

PDO - can both CREATE and DROP statements be in the same query?

I have SQL code that executes CREATE TABLE and DROP TABLE in the same query. When I run it, it prints bool(false) meaning error. Can it be done in one query?
$dbh = new PDO("sqlite::memory:");
$stmt = $dbh->prepare("create table a ( i int, j int);drop table a");
var_dump($stmt);
I don't know why but it works if I try it again.
You need to execute your query
Like this :
$stmt ->execute();
And yes you can create and delete a table in the same query.
You can maybe try this to catch an error, it will help you
try
{
$db = new PDO('sqlite::memory');
echo "SQLite created in memory.";
}
catch(PDOException $e)
{
echo $e->getMessage();
}

Appropriate sql command to delete a row from table using form?

I want to delete one row from one of my tables, based on a form -> "username".Let's assume, i have a log in page, where i write into the fields the apropriate username, and password based on a database which contains these values. After log in, i want to log out. And then I want to delete from the table the username and passwrod i used to sign in. How can i do it? Here's my code, it's unfortunately delete all the rows from the table. I have tried many ways... please help.
$sql="DELETE FROM login WHERE username='username'" ;
$result = mysqli_query($sqlconnection,$sql) or die...
assume that you receive the username value by a form by post and assign the value to a vars
$username = $_SESSION['login_user'];
then you can pass the value to you query this way
$sql="DELETE FROM login WHERE username='$username';" ;
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// sql to delete a record
$sql="DELETE FROM login WHERE username='$username';" ;
if ($conn->query($sql) === TRUE) {
echo "Record deleted successfully";
} else {
echo "Error deleting record: " . $conn->error;
}

how to save same model multiple times as new recode?

I need to save same model($modelcrite) multiple times after changing a id here is the code
protected function saveed($data1,$studentid,$modelcrite,$model)
{
$index = 0;
foreach ($data1 as $key => $value) {
$studentid[$index]=(string)$key;
$modelcrite->setAttribute('st_id',$key);
if ($modelcrite->validate()){
$modelcrite->setScenario('insert');
$modelcrite->save();
}
else {
$this->Delete($model->ass_id);
return FALSE;
}
$index=$index+1;
}
return TRUE;
}
but the problem is when second time save the $modelcrite value it is updating the database.I need to save it as new one
please can any one tell how can i do that.thank you.
I believe that you confusion comes from the fact that an ActiveRecord model does not represent a table, but instead represents a row in the table. So changing the terminology a bit, when you pass in the new model(row) $modelcrite ActiveRecord recognizes that this is a new model(row), and the save performs an insert. At this point now Active record realizes that the model(row) exists in the table, and any additional saves against that model(row) will generate an update.
With that background in mind what you need to do is in your foreach loop create a new model for the insert, and set the attributes of the new model to $modelcrite, then set the student_id, then validate and save.
Something like this:
foreach ($data1 as $key => $value) {
$newModel = new CriteModel();
$newModel->attributes = $modelcrite->attributes;
$studentid[$index]=(string)$key;
$newModel->setAttribute('st_id',$key);
if ($newModel->validate()){
$newModel->save();

Inserting the looped data into sql

I'm trying to scrape some data with xpath and then inserting into SQL.
Echo is working fine but when inserting into sql, it only gets the first line.
Example:
<?php
$res=mysql_query("SELECT table.title, table.link FROM table WHERE table.link LIKE 'http://www.%' AND streams.title = ''");
while($row=mysql_fetch_array($res))
{
$html = new DOMDocument();
#$html->loadHtmlFile($row["link"]);
$xpath = new DOMXPath($html);
foreach ($xpath->query("//table[#style='margin-left: 5px;']//td[#width='150']//a") as $files)
{
$html = new DOMDocument();
#$html->loadHtmlFile($files->getAttribute('href'));
$xpath = new DOMXPath($html);
$hl = $xpath->query("//div[#style='width:742px']/a[preceding-sibling::div[#id='help1']]/#href")->item(0)->nodeValue;
$link=serialize(array('link' => $hl));
$link=sqlesc($link);
echo $link; // all lines gets printed, thats okay?
mysql_query("UPDATE streams SET streams.hl=$link") or die(mysql_error()); // Only first line gets inserted, why?
}
}
?>
you are updating all rows , and you get all rows containing the same data because last update updates all the rows , do you want to update an existing rows or just insert new rows ?
if you want to insert try this
INSERT INTO streams (hl) VALUES ($link)
if there is others non-optional columns in the table , insert those values also

SQL optimisation

I want to optimize some of the SQL and just need an opinion on whether I should do it or leave it as is and why I should do it. SQL queries are executed via PHP & Java, I will show an example in PHP which will give an idea of what Im doing.
Main concerns are:
-Maintainability.
-Ease of altering tables without messing with all the legacy code
-Speed of SQL (is it a concern???)
-Readability
Example of what I have right now:
I take a LONG array from a customer (cant make it smaller unfortunately) and update the existing values with the new values provided by a customer in the following way:
$i = 0;
foreach($values as $value)
{
$sql = "UPDATE $someTable SET someItem$i = '$value' WHERE username='$username'";
mysql_query($sql, $con);
$i+=1;
}
Its easy to see from the above example that if the array of values is long, than I execute a lot of SQL statements.
Should I instead do something like:
$i = 0;
$j = count($values);
$sql = "UPDATE $someTable SET ";
foreach($values as $value)
{
if($i < $j) //append values to the sql string up to the last item
{
$sql .= "someItem$i = '$value', ";
}
$i+=1;
}
$sql .= "someItem$i = '$value' WHERE username='$username'"; //add the last item and finish the statement
mysql_query($sql, $con); //execute query once
OR which way should it be done / should I bother making these changes? (there a lot of the type and they all have 100+ items)
Thanks in advance.
The only way you'll get a definitive answer is to run both of these methods and profile it to see how long they take. With that said, I'm confident that running one UPDATE statement with a hundred name value pairs will be faster than running 100 UPDATE statements.
Don't run 100 seperate UPDATE statements!
Use a MySQL wrapper class which, when given an array of name => value pairs will return an SQL UPDATE statement. Its really simple. I'm just looking for the one we use now...
We use something like this (registration required) but adapted a little more to suit our needs. Really basic but very very handy.
For instance, the Update method is just this
/**
* Generate SQL Update Query
* #param string $table Target table name
* #param array $data SQL Data (ColumnName => ColumnValue)
* #param string $cond SQL Condition
* #return string
**/
function update($table,$data,$cond='')
{
$sql = "UPDATE $table SET ";
if (is_string($data)) {
$sql .= $data;
} else {
foreach ($data as $k => $v) {
$sql .= "`" . $k . "`" . " = " . SQL::quote($v) . ",";
}
$sql = SQL::trim($sql , ',');
}
if ($cond != '') $sql .= " WHERE $cond";
$sql .= ";";
return $sql;
}
If you can't change the code, make sure it is enclosed in transaction (if the storage engine is InnoDB) so no non-unique indexes will be updated before commiting transaction (this will speed up the write) and the new row won't be flushed to disk.
If this is MyISAM table, use UPDATE LOW_PRIORTY or lock table before the loop and unlock after read.
Of course, I'm sure you have index on the username column, but just to mention it - you need such index.