MySQL - decrement int value, delete row if int reaches 0 - php

I'm trying to find a query that does the exact opposite of this:
INSERT INTO WordsTable (word, counter)
VALUES('$word', 1)
ON DUPLICATE KEY UPDATE counter = counter + 1
(This SQL is fine. "word" is set to unique and everything)
So, basically, decrement the counter, if the counter reaches 0, delete the whole row. I'm thinking it might look like this but I've no clue if this is valid syntax:
UPDATE WordsTable
SET counter = counter - 1
WHERE id='$deleteThisWord'
IF (occ = 0) THEN
(
DELETE *
FROM WordsTable
WHERE id='$deleteThisWord'
)
Is there a nice clean way to do this?
Thanks!

You need to do it as two queries:
DELETE
FROM WordsTable
WHERE id='$deleteThisWord' AND counter = 1;
UPDATE WordsTable
SET counter = counter - 1
WHERE id = '$deleteThisWord'

Related

How to get last inserted row ID from wordpress database with trigger which increment ID

I use Wordpress with a database. My problem is that I want to retrieve the inserted ID when using wpdb-> insert. I want to clarify that I increment the ID using a database trigger because my table is a relative entity. I was thinking of creating a procedure that I would call after my insertion.
My trigger
BEGIN
DECLARE num INTEGER;
IF NEW.id IS NULL THEN
SET num =
(
SELECT MAX(id) + 1
FROM ab_autreFrais
WHERE idDevis = NEW.idDevis
);
SET NEW.id = num;
ELSEIF NEW.id = 0 THEN
SET num =
(
SELECT MAX(id) + 1
FROM ab_autreFrais
WHERE idDevis = NEW.idDevis
);
SET NEW.id = num;
END IF;
END
There is the LAST_INSERT_ID() function that you can use instead of the trigger. Also you can get this value through an output parameter of a stored procrdure.
Or you could use auxiliary table or a global variable to put id value from the trigger. For example:
...
SET NEW.id = num;
UPDATE `SysData` SET `LastID` = num;
...
#Alexander
UPDATE ``SysData`` SET ``LastID`` = num; Does not work on MySQL SysData is not exist. I used SET SESSION last_insert_id = num in sql on phpmyadmin it work but with wpdb when i call last_insert_id() it return 0

PHP - how to make an insert until there is no duplicate field value exist?

I have a Mysql table where pincode field cant be duplicate daily (Sequential increment id), also i cant apply the unique key on that field using Mysql indexing for some reason.
Using PHP i am trying as below, but my code will become endless if i have to keep increasing by checking them as below.
Is there any better way without Mysql indexing to do it from PHP (zend framework)?
$sql = "SELECT count(*) as total
FROM `sh_av_spform`
WHERE DATE(`createdate`) = CURDATE( )";
$result = $db->fetchAll($sql);
if(count($result)>0) {
$tmp_id = $result[0]['total'] +1;
$new_id = sprintf('%03d',$tmp_id); // 009
try{
$sql1 = "SELECT id,pincode
FROM `sh_av_spform`
WHERE DATE(`createdate`) = CURDATE() and pincode='$new_id' limit 1";
$result1 = $db->fetchAll($sql1);
if(count($result1)>0) {
// 009 already exist make it 010?
$tmp_id = $result[0]['total'] +2;
$new_id = sprintf('%03d', $tmp_id); // 010
}
// Ooopsssss! 010 also exist. now what?
// keep wrting code forever? or there is better way?
$db->insert('sh_av_spform', array('pincode'=>$new_id) );// Pincode cant be duplicated
You can do this entirely in database, using a counter table.
Example:
CREATE TABLE daily_pin (day DATE PRIMARY KEY, pin INT UNSIGNED);
START TRANSACTION;
INSERT INTO daily_pin VALUES (CURDATE(),1) ON DUPLICATE KEY UPDATE pin=LAST_INSERT_ID(pin+1);
INSERT INTO table_requiring_pin (pin) VALUES (LPAD(LAST_INSERT_ID(),3,'0'));
COMMIT;
Notes:
The counter table holds a given day's highest as yet used PIN.
The INSERT .. ON DUPLICATE KEY gets a new pin, either a "1" if it's the first entry for a given day, or the current value plus 1.
LAST_INSERT_ID, when given an argument, returns the argument and remembers it for the next time LAST_INSERT_ID is called without an argument.
Finally, left pad it with LPAD to get the "000" format you're wanting.
As a side benefit of this approach, you get easy metrics on pin usage. Like, "what day of the week consumes the most pin?"
You can create one separate function for checking pin code before you insert.
For example
public function ValidatePinCode($PinCode){
if(isset($PinCode)){
$SQL=$db->prepare("SELECT pincode FROM `sh_av_spform` WHERE pincode='".$PinCode."'");
$SQL=$db->execute($SQL);
if($SQL->fetchColumn()>0){
$ResponseCode='FALSE';
}else {
$ResponseCode='TRUE';
}
return $ResponseCode;
}
}
If you get FALSE response then do not allow to insert new pin code else you can perform INSERT query.
Let me know if you want even more explanation on this.

Add new last number automatically mysql

I have this id number in one column of my table,
0907003
0907004
0907005
1008005
1008006
1008007
1009001
1009002
1009003
When I add new value of 1009, it will add last three number of 004 because the last number begin with 1009 (10-09) is 003.
Or if I add new value of 1008, it will add last three number of 008
because the last number begin with 1008 (10-08) is 007.
Or if I add new value of 0907, it will add last three number of 006
because the last number begin with 0907 (09-07) is 007.
How to do this?
Many thanks in advance!
$front_id = $this->input->post('gameid'); //09
$middle_id = $this->input->post('netid'); //07
//$last_id will be generate automatically by sql
$forID = $front_id.$middle_id;
$sql = "INSERT INTO table ('colum') VALUES (".$forID.")"
You have to insert new id manually
$max_of_letsay1009 = mysql_result(mysql_query("select MAX(id) from table where id like '1009%'"),0);
// get the last 3 digits
$new_number = (int)substr($max_of_letsay1009,-3) + 1;
or you can try this too:
$new_id_of_letsay1009 = mysql_result(mysql_query("select MAX(id)+1 from table where id like '1009%'"),0);
this is just my idea, not yet tested and no error checking
You try this below query
If your value is 1009
SELECT MAX(RIGHT(ID,4))+1 FROM TableName WHERE LEFT(ID,4) = '1009'
It will return the max number of that series.
Try this query for dynamic ID length
SELECT MAX(RIGHT(ID,len(id)-LEN('1009')))+1 FROM #TEMP WHERE LEFT(ID,LEN('1009')) = '1009'
You can also use this query as sub query for the insert statement's ID column.
It is possible if it is not Auto_Increment coulmn.
Just need to write logic on insert time.

php auto generate number from my sql db

I need help in the following query in php. I want to create auto number like 0001, 0002.
I am using this query
$query = "SELECT MAX(cast(registration_code as decimal)) id FROM accounts ";
if($result = mysql_query($query))
{
$row = mysql_fetch_assoc($result);
$count = $row['id'];
$count = $count+1;
$code_no = str_pad($count, 4, "0", STR_PAD_LEFT);
}
It is working right but the problems is that when i delete any number like 0001, 0002, 0003 and i delete 0002 this create 0004 i want this will create deleted number i mean 0001 to 0003 if missing any that creat
thanks
used this query
SELECT ( accounts1.registration_code + 1) as gap_starts_at,
(SELECT MIN( accounts3.registration_code) -1 FROM arrc_vouchers accounts3 WHERE accounts3.registration_code > accounts1.registration_code) as gap_ends_at
FROM arrc_vouchers accounts1
WHERE NOT EXISTS (SELECT accounts2.registration_code FROM arrc_vouchers accounts2 WHERE accounts2.registration_code = accounts1.registration_code + 1)
HAVING gap_ends_at IS NOT NULL
Go fancy. Write a trigger to update next auto increment value on insert. Write trigger on delete to update the next auto increment value to the deleted id if it is lower than the current next auto increment.
I think you are trying to fill spaces of deleted auto increment primary no.
You can read this references..
Make auto increment fill previously deleted number
How to fill in the “holes” in auto-incremenet fields?

MySQL: Updating all rows setting a field to 0, but setting one row's field to 1

Is there an efficient way to update a selection of rows' field to 0, but set One of these rows to 1 based on an ID.
Basically, I have multiple objects in a database, and I want to toggle between which one is "inuse", so the query will set one of the rows (by id) to inuse=1 and the others to inuse=0.
Thanks :)
UPDATE `table`
SET `inuse` = (`id` = 23)
Sure
UPDATE table SET inuse=IF(id=ABCD, 1, 0)
would set the inuse field to 1 if id is ABCD and 0 otherwise.
UPDATE table
SET inuse = (id = #id)
WHERE id = #id
OR inuse
This will update only relevant rows.
UPDATE myTable
SET Field = 0
WHERE FieldID <> [WhateverID]
UPDATE myTable
SET Field = 1
WHERE FieldId = [WhateverID]
Try
update tbl set inuse = if(test, 1, 0);
or shorter
update tbl set inuse = test;
for example
update tbl set inuse = name = 'foo';
If you are after to set a flag, so no other part of the code uses the same object at the same time, it's better if the calling code sets inuse=1 and resets it when done. Otherwise you will end up one thread to mark an object (row) as inuse, and then if another thread needs another object, it will reset the first one, while still in use.
If this is not the case, and you just want be able to set inuse for one, and reset all others, you can use:
UPDATE myTable
SET InUse = CASE
WHEN myTable.id = #id THEN 1
ELSE 0
END
if your database uses transactions, this is the best way to do it:
update myTable set inuse = 0;
update myTable set inuse = 1 where id = ?;
if you are not using transactions, then the other answer using CASE is the best option since it's portable. but it will require more CPU time than the two UPDATE statements.

Categories