Yii2 : MySql Insert On Duplicates Key Update

Class activerecord dalam yii2 framework adalah powerfull, akan tetapi saya kesulitan untuk melakukan insert data ketabel dan apabila data tersebut sudah ada maka kolom data tersebut akan di update, dengan kata lain Insert On Duplicate Key Update 

Setelah googling sana sini akhirnya menemukan sebuah fungsi untuk melakukan hal tersebut diatas

Dengan sedikit otak atik pada fungsinya, maka fungsi tersebut dapat melakukan beberapa hal antara lain :

  • Insert data baru
  • Update kolom jika data sudah ada
  • Melakukan penambahan dan pengurangan nilai dari kolom
  • Insert data atau update data secara massal

 

Dan berikut ini fungsinya, anda dapat meletakkannya pada class model anda atau manapun, dalam contoh ini fungsi tersebut diletakkan pada class  Ajax dengan namespace ajax

<?php

namespace ajax;

use yii;
use yii\db\Command;

class Ajax{
    static function insertDuplicate($table, $columns, $duplicates, $values="",$ignores=false){
		$params=array();
		$names=array();
		$tipe="VALUES";
		$ignore="";
		if($ignores!==false){
			$ignore="IGNORE";
		}
		$placeholders=array();
		if(is_array($columns)){
			if(!isset($columns[0])){
				foreach($columns as $name=>$value)
				{
					$names[]=$name;
					if($value instanceof CDbExpression)
					{
						$placeholders[] = $value->expression;
						foreach($value->params as $n => $v)
							$params[$n] = $v;
					}
					else
					{
						$placeholders[] = ':' . $name;
						$params[':' . $name] = $value;
					}
				}
			}else{
				$names=$columns;
			}
			$myColumn=implode(', ',$names);
			if($values!=""){
				$myValue=$values;
			}else{
				$myValue='('.implode(', ', $placeholders).')';
			}
		}else{
			$myColumn=$columns;
			$myValue=$values;
		}
		if($values!=""){
			if(substr(strtoupper($values),0,6)=="SELECT"){
				$tipe="";
			}
		}
		$d = array();
		if(is_array($duplicates)){
			if(!isset($duplicates[0])){
				foreach($duplicates as $duplicate=>$act)
				{
					
					if($act=="increase"){
						$dup=$table.".".$duplicate . ' = '.$table.".".$duplicate.' + VALUES('.$duplicate.')';
					}elseif($act=="decrease"){
						$dup=$table.".".$duplicate . ' = '.$table.".".$duplicate.' - VALUES('.$duplicate.')';
					}else{
						$dup=$table.".".$duplicate . ' = VALUES('.$duplicate.')';
					}
					$d[] = $dup;
				}
			}else{
				foreach($duplicates as $duplicate){
					$dup=$duplicate . ' = VALUES('.$duplicate.')';
					$d[] = $dup;
				}
			}
			$myDuplicate= implode(', ', $d);
		}else{
			$myDuplicate=$duplicates;
		}
		
		
		$sql='INSERT '.$ignore.' INTO ' . $table
			. ' (' . $myColumn . ') '.$tipe.' '
			. $myValue . ' ON DUPLICATE KEY UPDATE ' .$myDuplicate;
		return Yii::$app->db->createCommand($sql)->bindValues($params)->execute();
	}
}

Ada 5 parameter dalam fungsi tersebut yang ketiga parameternya harus diisi, yaitu :

  • $table : nama tabel, berupa string
  • $columns : berupa array nama kolom dari tabel beserta nilainya, atau bisa berupa string dari nama kolom dipisahkan dengan tanda koma
  • $duplicates : berupa array dari kolom yang akan diupdate, bisa juga array tersebut beserta parameternya apakah ‘increase’ atau ‘decrease’
  • $value : berupa string, opsional dilakukan jika anda ingin insert/update secara massal
  • $ignores : berupa boelan, true atau false, default false, jika true maka mysql akan mengabaikan error dalam pengeksekusiannya

Berikut ini cara penggunaannya

<?php

use Yii;
use Ajax;

$tabel='stok';
$columns=[
	   'iditem' => 12,
	   'iduser' => 2,
	   'qty' => 2,
	];
$duplicates=[
	   'qty'=>''
	 ];	
// contoh untuk mengupdate stok barang sebanyak 2

$result=Ajax::insertDuplicate($tabel, $columns,$duplicates);

//contoh untuk menambah stok sebanyak 2 dari stok sebelumnya
$duplicates=[
	   'qty'=>"increase"
	];	
$result=Ajax::insertDuplicate($tabel, $columns,$duplicates);	

//contoh untuk mengurangi stok sebanyak 2 dari stok sebelumnya
$duplicates=[
	   'qty'=>"decrease"
	];	
$result=Ajax::insertDuplicate($tabel, $columns,$duplicates);	

//contoh untuk insert atau update massal

$columns="iditem,iduser,qty";
$duplicates=["qty"];
$value="(1,2,19),(2,2,5),(3,2,10)";

$result=Ajax::insertDuplicate($tabel, $columns,$duplicates,$value);	

//contoh untuk insert atau update dari tabel lain (kata kuncinya select pada $value)

$value="SELECT iditem, 2 as iduser, jumlah as qty from item_temp WHERE jumlah>0";

$result=Ajax::insertDuplicate($tabel, $columns,$duplicates,$value);

Demikianlah cara untuk insert on duplicate key update dalam Yii2 framework

Semoga bermanfaat