How to make codeigniter function that works same as insert_batch() but generates query Like INSERT IGNORE INTO ?
I need INSERT IGNORE INTO because one of my table's key is unique and its showing error when duplicate entry comes.
I searched code for add "INSERT IGNORE INTO " instead of "INSERT INTO" in codeigniter batch insert query but I didn't found results for that.
Yes we can made our custom batch insert query by using PHP login But if you want to do it in codeigniter use this function.
Add this function in (codeigniter/system/database/DB_active.rec.php).
/*
*Function For Batch Insert using Ignore Into
*/
public function custom_insert_batch($table = '', $set = NULL)
{
if ( ! is_null($set))
{
$this->set_insert_batch($set);
}
if (count($this->ar_set) == 0)
{
if ($this->db_debug)
{
//No valid data array. Folds in cases where keys and values did not match up
return $this->display_error('db_must_use_set');
}
return FALSE;
}
if ($table == '')
{
if ( ! isset($this->ar_from[0]))
{
if ($this->db_debug)
{
return $this->display_error('db_must_set_table');
}
return FALSE;
}
$table = $this->ar_from[0];
}
// Batch this baby
for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
{
$sql = $this->_insert_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100));
$sql = str_replace('INSERT INTO','INSERT IGNORE INTO',$sql);
//echo $sql;
$this->query($sql);
}
$this->_reset_write();
return TRUE;
}
To use this function
$this->db->custom_insert_batch($table_name, $batch_data);
Thanks !
Related
I'm trying to build a permission/action control system for my users.
There are 3 tables:
appName_actions:
appName_roles:
appName_roles_members:
There are 2 functions that will obtain the relevant data:
$memRoleIDs = AccessControl::get_memberRoleIDs($appName);
$memActionIDs = AccessControl::get_memberActionIDs($appName, $memRoleIDs);
get_memberRoleIDs works fine, it targets member 327 and returns the desired '2,4'
That is then passed to get_memberActionIDs as '2,4'
It's at this point I'm having trouble working out how to return all the actionIDs in one variable/string.
get_memberActionIDs:
public static function get_memberActionIDs($appName = NULL, $memRoleIDs = NULL)
{
if($appName !== NULL && $memRoleIDs !== NULL)
{
$tbl = 'app_'.$appName.'_roles';
$memRoleID = explode(',',$memRoleIDs);
foreach($memRoleID as $value)
{
$db = openDB();
$sql = $db->prepare("SELECT actionIDs FROM $tbl WHERE roleID = '$value'");
if(!$sql->execute())
{
logThis('ERROR_crit' , 'Database Query Failed !!!' , 1 , __FILE__ , __LINE__);
die('<h2>There was a critical error and data has not been loaded correctly. Developers have been notified.</h2><h3>Please try reloading the page</h3>');
}
else
{
// sql executed ok - bind fetch results
$sql->bind_result($actionID);
$sql->fetch();
print $actionID.'<br>';
}
}// return all the actionIDs as 1 variable here
}
}// end func
Now with this, there is success up-to-a-point. It prints out the correct info:
1,2,3,4
5
And this is where I cannot go any further :(
I've looked into GROUP_CONCAT and CONCAT in the SELECT statement and .= in the PHP loop, but I just cannot figure this out.
I'd like to return this as '1,2,3,4,5' all in 1 string.
If you could point me in the right direction I would be very grateful :)
Instead of printing out separate results, create a single string and print after the loop exits. You say you've tried this but you didn't include the relevant code to check if the implementation is correct. Is this what you did?
public static function get_memberActionIDs($appName = NULL, $memRoleIDs = NULL)
{
if($appName !== NULL && $memRoleIDs !== NULL)
{
$tbl = 'app_'.$appName.'_roles';
$memRoleID = explode(',',$memRoleIDs);
$result = "";
foreach($memRoleID as $value)
{
$db = openDB();
$sql = $db->prepare("SELECT actionIDs FROM $tbl WHERE roleID = '$value'");
if(!$sql->execute())
{
logThis('ERROR_crit' , 'Database Query Failed !!!' , 1 , __FILE__ , __LINE__);
die('<h2>There was a critical error and data has not been loaded correctly. Developers have been notified.</h2><h3>Please try reloading the page</h3>');
}
else
{
// sql executed ok - bind fetch results
$sql->bind_result($actionID);
$sql->fetch();
$result .= $actionID;
}
}// return all the actionIDs as 1 variable here
print $result.'<br>';
}
}// end func
There is an error while i insert "3 + 1 room" or update description area with "3 + 1 room" in MySQL database.
I saw there is no addition sign "+" in MySQL log (data inserted in database)
UPDATE testtable set status='0',title='3 1 room',
description='3 1 Daire. 1 Balkon kapalı.' WHERE id='60';
create table testtable ( id int(11), status tinyint(4), title varchar(20),
description text) ENGINE=InnoDB DEFAULT CHARSET=utf8
php file
$baglanti=new PDO("mysql:host="localhost";dbname="test";charset=utf8",$us
ername,$passwd) or die("error");
$val=$baglanti->exec("UPDATE testtable set status='0',title='$title',
description='$dest' WHERE ad_no='$ad_no' ");
return $val;
What should I do?
EDIT
update.php
<?php
include("database.php");
$fields = array();
$values=array();
$fvalue=$_POST['id'];
$table=$_POST['table'];
foreach ($_POST as $key => $value) {
if( $key!='table' && $key!='id' && $key!='alan'){
if( strpos($key,"date")){
$datet=new DateTime($value);
$value=$datet->format('Y-m-d');
}
array_push($fields,$key);
array_push($values,$value);
}
}
$alan=$_POST['alan'];
$ID=Updt($table,$fields,$values,$alan,$fvalue);
if($ID!=0){
echo $ID;
}
?>
database.php
<?php
$baglanti=new PDO("mysql:host="localhost";dbname="test";charset=utf8",$us
ername,$passwd) or die("error");
#UPDATE
function Updt($table,$set,$value,$field,$fvalue){
$bag=$GLOBALS['baglanti'];
$sts='';
if(is_array($set)){
for ($i=0; $i < count($set); $i++) {
$sts.=$set[$i]."='".$value[$i]."',";
}
$sts=rtrim($sts,",");
}else{
$sts=$set."='".$value."'";
}
$val=$bag->exec("UPDATE $table set $sts WHERE $field='$fvalue'");
return $val;
}
?>
this one, programmers wrote code. I try to take question parts from all code. There were lots of codes in file.
My guess is that you are not generating the query you think you are.
This should allow you to see the query.
I have also added some error checking, that really should be used in this code.
I have amended the connection line as I am sure a newline in the middle of the $username variable will cause an error.
database.php
<?php
try {
$baglanti = new PDO("mysql:host=localhost;dbname=test;charset=utf8",
$username,$passwd);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
exit;
}
#UPDATE
function Updt($table,$set,$value,$field,$fvalue){
$bag = $GLOBALS['baglanti'];
$sts='';
if(is_array($set)){
for ($i=0; $i < count($set); $i++) {
$sts.=$set[$i]."='".$value[$i]."',";
}
$sts=rtrim($sts,",");
}else{
$sts=$set."='".$value."'";
}
$sql = "UPDATE $table set $sts WHERE $field='$fvalue'";
echo $sql; // you can comment this line out when you are sure the SQL is good
$val = $bag->exec($sql);
return $val;
}
?>
update.php
Small amendment here just so you know whats actually being returned from the function is a count and not a row ID. It could also be FALSE, indicating an error occured in the Updt() function in the query.
<?php
include("database.php");
$fields = array();
$values=array();
$fvalue=$_POST['id'];
$table=$_POST['table'];
foreach ($_POST as $key => $value) {
if( $key!='table' && $key!='id' && $key!='alan'){
if( strpos($key,"date")){
$datet=new DateTime($value);
$value=$datet->format('Y-m-d');
}
array_push($fields,$key);
array_push($values,$value);
}
}
$alan=$_POST['alan'];
//$ID=Updt($table,$fields,$values,$alan,$fvalue);
// this is not an ID it is a coumt of the number or rows
// updated by the Updt() function
$cnt = Updt($table,$fields,$values,$alan,$fvalue);
if ( $cnt === FALSE ) {
// then we had an error in Updt()
print_r($baglanti->errorInfo(), true);
exit;
}
if($cnt != 0){
echo 'Rows updated = ' . $cnt;
}
?>
I have to mention this as others will if I dont. Your code is open to SQL Injection you should really be using prepared statements. Maybe you should mention this to the Programmers you mentioned. Maybe you should also not assume everything they wrote was done correctly.
I've been trying to find a solution to this problem for a long time now and nowhere on the internet was I able to find the answer. I have this situation where i need to insert or update a blob field (subtype 1) from a firebird database with php. The problem is that when the text get like really big >36k it will not execute the query. I know line queries are limited to 32k of data and I tried to use parametrized queries in c#, but i was not able to find something to work for me in PHP. Not even close to working.
I tried with ibase_blob_Create and so on i tried inserting directly like Insert into table (blob_value) values (?), ibase_prepare that and so on. Nothing seems to work for me. Is there some magical way to make this work in php or is it just impossible to get large text into blob from php?
Ive tried using things like:
class DBMgmt_Ibase_Blob extends DBMgmt_Generic_Blob
{
var $blob; // resourse link
var $id;
var $database;
function DBMgmt_Ibase_Blob(&$database, $id=null)
{
$this->database =& $database;
$this->id = $id;
$this->blob = null;
}
function read($len)
{
if ($this->id === false) return ''; // wr-only blob
if (!($e=$this->_firstUse())) {
return $e;
}
$data = #ibase_blob_get($this->blob, $len);
if ($data === false) return $this->_setDbError('read');
return $data;
}
function write($data)
{
if (!($e=$this->_firstUse())) return $e;
$ok = #ibase_blob_add($this->blob, $data);
if ($ok === false) return $this->_setDbError('add data to');
return true;
}
function close()
{
if (!($e=$this->_firstUse())) return $e;
if ($this->blob) {
$id = #ibase_blob_close($this->blob);
if ($id === false) return $this->_setDbError('close');
$this->blob = null;
} else {
$id = null;
}
return $this->id ? $this->id : $id;
}
function length()
{
if ($this->id === false) return 0; // wr-only blob
if (!($e=$this->_firstUse())) return $e;
$info = #ibase_blob_info($this->id);
if (!$info) return $this->_setDbError('get length of');
return $info[0];
}
function _setDbError($query)
{
$hId = $this->id === null ? "null" : ($this->id === false ? "false" : $this->id);
$query = "-- $query BLOB $hId";
$this->database->_setDbError($query);
}
// Called on each blob use (reading or writing).
function _firstUse()
{
// BLOB is opened - nothing to do.
if (is_resource($this->blob)) return true;
// Open or create blob.
if ($this->id !== null) {
$this->blob = #ibase_blob_open($this->id);
if ($this->blob === false) return $this->_setDbError('open');
} else {
$this->blob = #ibase_blob_create($this->database->link);
if ($this->blob === false) return $this->_setDbError('create');
}
return true;
}
}
Which i use like this:
$text = new DBMgmt_Ibase_Blob($DB);
if (!$text->write(htmlspecialchars($Data["Text"]))){
throw new Exception("blob fail");
}
$blobid = $text->close();
//similar query
$DB->query("INSERT INTO TABLE1 (BLOB_VALUE) VALUES (?)",$blobid);
After that in my database I find a number which I know I have to use with:
Blob = new DBMgmt_Ibase_Blob($DB,$data->Text);
$data->Text = $Blob->read($Blob->length());
But i get String is not a BLOB ID with a number in database like 30064771072.
I tried directly to add it but of course it does not work like this
$DB->query('insert into table (blob) values (?)',$string); // where string is like 170k chars
I get error of Dynamic SQL Error SQL error code = -104 Unexpected end of command - line 1, column 236
I tryed putting it into file following php.net reference php.net blob_import with code similar to this:
$dbh = ibase_connect($host, $username, $password);
$filename = '/tmp/bar';
$fd = fopen($filename, 'r');
if ($fd) {
$blob = ibase_blob_import($dbh, $fd);
fclose($fd);
if (!is_string($blob)) {
// import failed
} else {
$query = "INSERT INTO foo (name, data) VALUES ('$filename', ?)";
$prepared = ibase_prepare($dbh, $query);
if (!ibase_execute($prepared, $blob)) {
// record insertion failed
}
}
} else {
// unable to open
But I am still getting result like the blob writing method.
You need to use parameters :
$query = ibase_prepare($DB, 'insert into table (blob) values (?)');
ibase_execute($query, $string);
cf : http://php.net/manual/en/function.ibase-execute.php
I seem to be having a problem with the below code. I cannot get the insert query to run when the query returns nothing. But when there is a row in the db, the else statement runs correctly. Does anybody know why this could be happening?
$query5 = $this->db->get_where('loggedstatus', array('userid_loggedstatus' => $userid));
if ($query5->num_rows() < 0) {
$data1 = array('isLoggedIn_loggedstatus' => 'yes', 'userid_loggedstatus' => $userid);
$this->db->insert('loggedstatus', $data1);
} else {
$data = array('isLoggedIn_loggedstatus' => 'yes');
$this->db->where('userid_loggedstatus', $userid);
$this->db->update('loggedstatus', $data);
}
Have you tried changing this if ($query5->num_rows() < 0) { to something like if ($query5->num_rows() <= 0) {, just a thought. It would make a difference because your telling it to only execute if its less than zero however it might be equal to zero and you would skip to the else statement.
And just for CodeIgniter num_rows() reference:
/**
* Number of rows in the result set
*
* #return int
*/
public function num_rows()
{
if (is_int($this->num_rows))
{
return $this->num_rows;
}
elseif (count($this->result_array) > 0)
{
return $this->num_rows = count($this->result_array);
}
elseif (count($this->result_object) > 0)
{
return $this->num_rows = count($this->result_object);
}
return $this->num_rows = count($this->result_array());
}
Changing if condition shown below should fix the problem.
if ($query5->num_rows() == 0)
Can anyone explain what the following PHP Code does
function query($query_string)
{
if ($query_string == "") {
return 0;
}
if (!$this->connect()) {
return 0;
};
if ($this->QueryID) {
$this->free_result();
}
if ($this->RecordsPerPage && $this->PageNumber) {
$query_string .= " LIMIT " . (($this->PageNumber - 1) * $this->RecordsPerPage) . ", " . $this->RecordsPerPage;
$this->RecordsPerPage = 0;
$this->PageNumber = 0;
} else if ($this->RecordsPerPage) {
$query_string .= " LIMIT " . $this->Offset . ", " . $this->RecordsPerPage;
$this->Offset = 0;
$this->RecordsPerPage = 0;
}
$this->QueryID = #mysql_query($query_string, $this->LinkID);
$this->Row = 0;
$this->Errno = mysql_errno();
$this->Error = mysql_error();
if (!$this->QueryID) {
$this->halt("Invalid SQL: " . $query_string);
}
return $this->QueryID;
}
function next_record()
{
if (!$this->QueryID) {
$this->halt("next_record called with no query pending.");
return 0;
}
$this->Record = #mysql_fetch_array($this->QueryID);
$this->Row += 1;
$this->Errno = mysql_errno();
$this->Error = mysql_error();
$stat = is_array($this->Record);
if (!$stat && $this->AutoFree) {
$this->free_result();
}
return $stat;
}
Can the above be done in a simpler way , would it be wise to use an ORM ?
The first class method looks like it performs a MySQL query and adds a LIMIT clause for pagination. The second moves the current query onto the next record, while incrementing the pagination counters.
In more detail, here's the first sample:
Exit the method if the query is empty or the database connection doesn't exist.
Free any existing query.
If the number of records per page and page number are set:
Add them to the LIMIT clause of the query.
And reset them to 0.
Otherwise if records per page is set:
Add it to the LIMIT clause of the query.
And reset them to 0.
Run the query.
Set the current row to 0.
Collect errors.
If the query failed halt with the error.
Return the query.
And the second:
If the query is not set halt with an error.
Fetch row information as an array for the current row.
Increment the row number.
Catch any errors.
If the result isn't an array free/close the query.
Otherwise return the result set.
Yes you are right Ross it something like pagination function in a class which calls the records one by one.