Duplicate Data Stop in MySQL - php

I have a table below :
+-----+-------+------+------------+
| ID | RefID | Type | EventTime |
+-----+-------+------+------------+
| 101 | 228 | 1 | 1437195633 |
| 102 | 228 | 5 | 1437195633 |
| 103 | 228 | 1 | 1437195633 |
| 104 | 228 | 1 | 1437195442 |
| 105 | 228 | 1 | 1437195442 |
| 106 | 228 | 5 | 1437195442 |
| 107 | 228 | 1 | 1437165634 |
| 108 | 228 | 5 | 1437165442 |
| 109 | 228 | 1 | 1437165634 |
| 110 | 228 | 5 | 1437165442 |
+-----+-------+------+------------+
In that I want to stop inserting duplicate data based on the columns RefID,Type,EventTime only when value of Type = 1.
In the above table ID pair is duplicate (101,103), (104,105), (107,109).
If now I will insert another data say :
INSERT INTO table VALUES('',228,1,1437165634);
Then it should not insert. I am checking while inserting into that table but that is not working as I have checked at the same time 2 insert query is happening, I need to stop it using UNIQUE key constraints.

You need change DB architecture. Add table with unique index by RefId, here you will write record with Type "1". In your Yii model in method beforesave check your Type if is 1 to write in added table otherwise write to old table. And you need change beforefind method
And I'm sorry for my english

Please try:
public function unique($attribute, $params)
{
if(!empty($model_name)){
$this->addError('RefID', 'RefID already exists! Please choose a different one');
return true;}
}
as a custom function in before save. and call it for the fields you want in the rule. I'm showing you the template for a single field refID

I have solved it by using trigger as below :
DB Trigger
delimiter $$
drop trigger if exists stop_duplicate $$
create trigger stop_duplicate before insert on table
for each row
begin
set #found := false;
if new.Type = 1 then
SELECT
TRUE
INTO #found FROM
table
WHERE
RefID = new.RefID AND EventTime= new.EventTime AND Type= new.Type;
if #found then
signal sqlstate '23000' set message_text = 'CUSTOM_MSG_DUPLICATE';
end if;
end if;
end $$
delimiter ;
Yii Model Code
public function save($runValidation = true, $attributes = null) {
Yii::log(__METHOD__.":: Start ", 'info');
try {
return parent::save();
} catch (Exception $e) {
$errorInfo = $e instanceof PDOException ? $e->errorInfo : null;
$message = $e->getMessage();
Yii::log(__METHOD__ . ": errorcode :{$e->getCode()}, errormessage:{$message} ", 'info');
// Added for handling duplicate entry issue for index
if ((int) $e->getCode() === 23000 && strpos($message, 'CUSTOM_MSG_DUPLICATE') !== false) {
return false;
}
throw new CDbException(Yii::t('yii', 'CDbCommand failed to execute the SQL statement: {error}', array('{error}' => $message)), (int) $e->getCode(), $errorInfo);
}
}

Related

how to get array in database column ? Laravel

I want to get array in database,it work in database query (my database i use postgrest) but not work in my project laravel.
Error message -> Undefined column: 7 ERROR: column sample1.text[1] does not exist
table sample1
___________________________________
| id | name | text[] |
|------+------+--------------------|
| 1 | aa | {xxx1,xxx2,xxx3} |
| 2 | bb | {xxx1,xxx2,xxx3} |
| 3 | cc | {xxx1,xxx2,xxx3} |
|______|______|____________________|
I need value
{
xxx1,
xxx1,
xxx1
}
my code
$search = DB::table("sample1")->select(array( 'sample1.text[1]'))->get();
return response()->json($search);
in my database query it work
SELECT "NSO_STAT_GIS"."BND_SET_STAT_TABLE"."MAPTB_CAT_SL_ID"[1] FROM "NSO_STAT_GIS"."BND_SET_STAT_TABLE"
$textsJson = DB::table("sample1")->select('text')->get();
$textArray = json_decode($textsJson);
https://laravel.com/docs/5.8/queries#selects

Applying if-else condition to export selective records using PhpExcel

I need to export only those records whose column satisfies defined value.
Eg.
if(null !== ($this->f3->get('SESSION.userStatus')))
{
$userStatus = $this->f3->get('SESSION.userStatus');
}
This is how I tried to set cell values depending on set value:
$rowID = 5;
foreach ($results as $result)
{
if($result['status'] == $userStatus)
{
$objPHPExcel->getActiveSheet()->setCellValue('A'.$rowID, $result['fullname']);
$objPHPExcel->getActiveSheet()->setCellValue('B'.$rowID, $result['checkin_date']);
}
else
{
$objPHPExcel->getActiveSheet()->removeRow($rowID);
}
$rowID++;
}
The file is exported with only those records that have defined "status" value.
But the problem is that rows whose criteria doesn't meet are filled with spaces and still occupies rows.
Here is how output looks like:
A | B | C | D
1 | | |
.
.
174 | | |
175 | | |
176 | | |
177 | | |
178 John | 2014| xyz | dfdf
179 Jack | 2015| jkl | dfdf
180 | | |
.
.
How can I fix it to get records starting with top row?
Eg.
1 | John | 2014 | xyz | dfdf
2 | Jack | 2015 | jkl | dfds
between
}
$rowID++;
put this
else
{
$objPHPExcel->getActiveSheet()->removeRow($rowID);
}
That will delete your blank rows.
Note, that you start with row 5 for some reason and do not test for max rows. Your code will still need some fixing up

replace statement query in CI

i have this table
id | part_number | desc | date |
1 | 3yrt3470 | aa | 2017-02-20 |
2 | 3utitj40 | bb | 2017-02-12 |
pk=id
i want to create query insert into table but if part_number exist it will updated. anyone can help me?
i tried this
function replace($part_number)
{
$this->db->replace('tbl_master_data');
$this->db->set('description',$description);
$this->db->set('rrp',$rrp);
$this->db->set('discount_code',$discount_code);
$this->db->set('product_group',$product_group);
$this->db->set('value_discount',$value_discount);
$this->db->set('stk',$stk);
$this->db->where('part_number',$part_number);
}
error messages show you must use the 'set' method...

Insert if not exists with Codeigniter

I am encountering the following problem I am trying to insert data into the table if
phone, sushi_service_id both has a row with active = 1
for example:
ID | Phone | sushi_service_id | active
---------------------------------------
1 | 455 | 1 | 1 (LEGAL)
3 | 455 | 1 | 0 (LEGAL)
4 | 455 | 1 | 0 (LEGAL)
5 | 455 | 1 | 1 (NOT LEGAL! HAS THE SAME PHONE+SUSHI_SERVICE_ID+ACTIVE=1)
This is my codeigniter code:
how can I improve it in order to work like I said above?
public function add($service, $phone, $sushi_subscription_id, $answer_id, $affiliate_id, $ip, $query, $invite_type, $invite_msg_id)
{
$this->db->set('service_id', $service->id);
$this->db->set('sushi_service_id', $service->sushi_service_id);
$this->db->set('phone', $phone);
if ($sushi_subscription_id) {
$this->db->set('sushi_subscription_id', $sushi_subscription_id);
}
$this->db->set('answer_id', $answer_id);
if ($affiliate_id) {
$this->db->set('affiliate_id', $affiliate_id);
}
$this->db->set('added', 'NOW()', FALSE);
$this->db->set('active', 1);
$this->db->set('ip', $ip);
$this->db->set('query', $query);
if ($invite_type) {
$this->db->set('invite_type', $invite_type);
}
if ($invite_msg_id) {
$this->db->set('invite_msg_id', $invite_msg_id);
}
return ($this->db->insert($this->_table_name)) ? $this->db->insert_id() : FALSE;
}
I would just do a select * from XX where active = 1 and then based on the result of num_rows the insert query.
Easiest way to do this would be in a single INSERT with ON DUPLICATE KEY UPDATE query.
Example structure:
INSERT INTO table ... VALUES .... ON DUPLICATE KEY UPDATE

loop within a loop for updating db record

I have a deals table with the following data:
dealID | date | followUP | user
1 |2012-10-15 | Yes |
2 |2012-12-24 | Yes |
3 |2013-01-05 | |
4 |2013-02-02 | Yes |
5 |2013-02-02 | Yes |
And a users table with my users list
userID | name
1 | john
2 | eric
3 | anne
What I would like to do is to query the first table that has followUP set as 'YES' then from the result assign a user to them in sequence from the users table so my final deals table will look like this
dealID | date | followUP | userID
1 |2012-10-15 | Yes | 1
2 |2012-12-24 | Yes | 2
3 |2013-01-05 | |
4 |2013-02-02 | Yes | 3
5 |2013-02-02 | Yes | 1
I know its a loop but for some reason i cant figure out how to setup the second loop to assign the value of the users. Any help would be appreciated.
First get your user IDs into an array so it looks:
$uids = array(1, 2, 3);
Then, when reading the records from deals table compose update queries like so:
$follow_up_user_idx = 0;
$update_queries = array();
while($row=mysqli_fetch_assoc($result)) {
// ... do whatever you need to
if($row['followUP'] != 'Yes') continue;
$update_queries[] = "UPDATE `deals` SET `user` = '" . $uids[$follow_up_user_idx] . "'
WHERE `dealID` = '" . $row['dealID'] . "' LIMIT 1";
$follow_up_user_idx++;
if($follow_up_user_idx > count($uids) - 1) $follow_up_user_idx = 0;
}
Now you have all update queries. Just execute them:
foreach($update_queries as $uq) {
mysqli_query($link, $uq);
}
You will have to follow a series of steps to achieve what you have mentioned.
1) Fetch all the records from database where followUP is 'Yes'.
Lets say that first table is deals. So, fetch all records where followUP is 'Yes'.
Lets say, you have result in $deals_details.
2) Fetch all the users(name) from database.
Lets say that second table is users. So, fetch all users.
Lets say, you have all users' names in $users_details array.
Get a count of total users in system in seperate variable say $users_count.
3) Loop through $deals_details and assign each user one-by-one sequentially from $users_details.
$i = 0;
foreach($deals_details as $keyDD => $valueDD){
$user = $users_details[$i];
$i++;
if($i == $users_count)
$i = 0;
$query = "update `deals` set user = '".$user."' where dealID = '".$valueDD['dealID']."'";
//fire query
//$link is connection variable.
mysqli_query($link, $query);
}
Table user
+---------------+---------------+------------+
| user_id | username | user_level |
+---------------+---------------+------------+
| 1 | superadmin | admin |
| 2 | subadmin | admin |
| 3 | team1 | team |
| 4 | team2 | team |
| 5 | team3 | team |
| 6 | customer1 | customer |
| 7 | customer2 | customer |
| 8 | customer3 | customer |
| 9 | customer4 | customer |
+---------------+---------------+------------+
Table complaint:
+---------------+---------------+------------+
| complaint_id | complaint | user_id |
+---------------+---------------+------------+
| 1 | os issue | 7 |
| 2 | USB issue | 8 |
| 3 | OS currepted | 7 |
| 4 | HD issue | 9 |
| 5 | DVD issue | 6 |
| 6 | SW problem | 9 |
| 7 | Network issue| 9 |
| 8 | system issue | 6 |
+---------------+---------------+------------+
Table assign_work
+---------------+------------+
| complaint_id | user_id |
+---------------+------------+
| 1 | 3 |
| 2 | 4 |
| 3 | 5 |
| 4 | 3 |
| 5 | 4 |
| 6 | 5 |
| 7 | 3 |
| 8 | 4 |
+---------------+------------+
When customer raise the complaint data should save in complaint table also that last
complaint_id should save in assign_work table at the same time
user_id also save sequencially, fetch from user table who are the team that person id only.
I m new in ph please any one help me.
This may be a poor design decision. Without knowing more about your application, I'd be tempted to wait for a user to become available/request a deal, then assign to them (from a queue) the next deal requiring follow-up. Even if you have good reasons to assign users before they are "available", you might consider doing so upon deal creation/modification based on some appropriate business logic (e.g. maintaining a queue of users to be assigned to the next deal).
Indeed, there's no particularly nice way of performing this operation with a simple UPDATE statement. One way to accomplish it purely within the database would be to use a stored procedure (it's not especially concurrency-safe though, as changes to the Users table between closing and reopening the _curUser cursor may cause undesirable effects; one might instead copy the Users to a temporary table for the purposes of this procedure, depending on your desired logic):
DELIMITER //
CREATE PROCEDURE assignDeals() BEGIN
DECLARE _userID, _dealID BIGINT UNSIGNED;
DECLARE _done BOOLEAN DEFAULT FALSE;
DECLARE _curUser CURSOR FOR
SELECT userID
FROM users
ORDER BY userID;
DECLARE _curDeal CURSOR FOR
SELECT dealID
FROM deals
WHERE followUP = 'Yes'
ORDER BY dealID
FOR UPDATE;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET _done := TRUE;
PREPARE stmt FROM 'UPDATE deals SET userID = ? WHERE dealID = ?';
OPEN _curUser;
OPEN _curDeal;
readDeal: LOOP
FETCH _curDeal INTO _dealID;
IF _done THEN
LEAVE readDeal;
END IF;
FETCH _curUser INTO _userID;
IF _done THEN
SET _done := FALSE;
CLOSE _curUser;
OPEN _curUser;
FETCH _curUser INTO _userID;
IF _done THEN
SIGNAL SQLSTATE VALUE '45000' SET
MESSAGE_TEXT = 'No users';
LEAVE readDeal;
END IF;
END IF;
SET #userID := _userID, #dealID := _dealID;
EXECUTE stmt USING #userID, #dealID;
END LOOP readDeal;
CLOSE _curUser;
CLOSE _curDeal;
DEALLOCATE PREPARE stmt;
END//
DELIMITER ;
See it on sqlfiddle.

Categories