I'm working on an application using JSP and MYSQL.
The application includes feature for user to input 'Date' and 'Hours', which are stored in a table 'epinfo' in MYSQL.
+-------+-------------+------+-----+------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+------------+-------+
| uid | varchar(10) | NO | PRI | | |
| dt | date | NO | PRI | 0000-00-00 | |
| hrs | int(2) | YES | | NULL | |
+-------+-------------+------+-----+------------+-------+
Another feature is applying for leave, stored in a different table 'leave'
+--------+-------------+------+-----+------------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+------------+-------+
| uid | varchar(10) | NO | PRI | | |
| stdt | date | NO | PRI | 0000-00-00 | |
| enddt | date | NO | PRI | 0000-00-00 | |
+--------+-------------+------+-----+------------+-------+
I need to disable and delete any entries for this time period, in the table epinfo.
Eg. If a leave application entry is 2014-06-14 to 2014-06-16, I need to make sure the user cannot enter any data for 14,15,16th of June in the table epinfo.
I know a BEFORE INSERT Trigger can help here, which goes something like this:
create trigger cons_check
before insert on epinfo
for each row
begin
if exists(select * from leave where stdt<=entered_date and enddt>=entered_date)
then
Disable entry in database
else
insert into table.
end if
end
Can someone help me create this trigger? Or help with a different solution?
Also, the entered date is the value I have in my insert query. How can I use this value in the trigger?
Related
I want start_date and start_time copied into latest_time and latest_date, while adding a new entry into my logbook. But I want dependency on logbook.logbook_index_id = logbook_index.id for all entries too.
mysql> describe logbook;
+-------------------------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------------------+-----------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| logbook_index_id | int(10) unsigned | NO | | NULL | |
| start_date | date | NO | | NULL | |
| start_time | time | NO | | NULL | |
mysql> describe logbook_index;
+--------------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+----------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| first_date | date | NO | | NULL | |
| first_time | time | NO | | NULL | |
| latest_date | date | NO | | NULL | |
| latest_time | time | NO | | NULL | |
+--------------------+----------------------+------+-----+---------+----------------+
atm I got this far ...
create trigger update_dates after insert on logbook
for each row update logbook_index
set latest_date = start_date where logbook_index.id = logbook_index_id;
I do it mostly wrong I bet. How does this work correctly and how do I get the time copied too ?
If I understood your question correctly:
For this I would suggest using a trigger
You can put an AFTER INSERT trigger on the table that you insert, inside the trigger you can put the update to the other table.
In order to access variables from the newly insert record, you need to do the following:
UPDATE logbook_index
SET latest_date = NEW.start_date
WHERE logbook_index.id = NEW.logbook_index_id;
Notice the keyword NEW that is used to access the newly insert record.
If you were using an AFTER UPDATE trigger, you could access the old values by using OLD
What you're searching for is a Trigger, a procedure that's automatically invoked in response to an event, in your case the insertion of a row in the logbook table.
Here's my table.
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| Postcode | varchar(255) | YES | | NULL | |
| Town | varchar(255) | YES | | NULL | |
| Region | varchar(255) | YES | | NULL | |
| Company Name | varchar(255) | YES | | NULL | |
| Fee | double | YES | | NULL | |
| Company Benefits | varchar(255) | YES | | NULL | |
| Date Updated | date | YES | | NULL | |
| Website | mediumtext | YES | | NULL | |
| Updated By | varchar(255) | YES | | NULL | |
| Notes | varchar(255) | YES | | NULL | |
| LNG | varchar(255) | YES | | NULL | |
| LAT | varchar(255) | YES | | NULL | |
+-------------------+--------------+------+-----+---------+----------------+
You can see we have an "Updated by" column.
How can I make it so that, when a user updates the row, the "Updated By" column automatically updates (or inserts if it's a new row they're adding) with the currently logged-in users name?
Many Thanks
You will have to explicitly make sure about that and whenever an UPDATE is happening then you need to update that column as well saying below. Best way to assure it, have your application logic fill in the column whenever an UPDATE to the record is happening from current logged-in user principle or claim
update tbl1
set ...,
Updated By = <logged in user name>
where Id = <some val>
You can use USER() or CURRENT_USER() in Update or Insert statements to achieve needed effect.
From my side - the only one secure way is to create stored procedures, providing inserts or updates to desired table.
Indeed, this problem was discussed here:
mysql Set default value of a column as the current logged in user
Something like this !
CREATE TRIGGER `updater`.`tableName_BEFORE_INSERT` BEFORE INSERT ON `tableName`
FOR EACH ROW
BEGIN
Set New.Updated_By = current_user();
END
I have a db with 10 fields, of which only a few change very often. I would like to open the current record, update it, and enter it back into the db with a new auto id while retaining the previous record.
If I INSERT a new record, I have to re-enter all the info even tho it may not have changed.
If I UPDATE a record, it overwrites the previous values.
Any suggestion would be greatly appreciated
How about a suitably modified version of
insert into table select * from table where id='current_id'
Sample query:Say i want to read first record ,lift student, subject but change marks and insert a new record
insert into score(student,subject,marks)
select student,subject,'30' from score where id=1;
Sample Data
+---------+---------+-------+----+
| student | subject | marks | id |
+---------+---------+-------+----+
| A1 | phy | 20 | 1 |
| A1 | bio | 87 | 2 |
| A2 | che | 24 | 3 |
| A3 | che | 50 | 4 |
Table structure:
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| student | varchar(20) | YES | | NULL | |
| subject | varchar(20) | YES | | NULL | |
| marks | int(1) | YES | | NULL | |
| id | int(10) | NO | PRI | NULL | auto_increment |
+---------+-------------+------+-----+---------+----------------+
You can do it via two different queries: SELECT and INSERT, or you can use INSERT INTO SELECT construction. Check documentation for complete reference http://dev.mysql.com/doc/refman/5.0/en/insert-select.html
I have table with auction lots:
mysql> desc lots;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(10) | NO | PRI | NULL | auto_increment |
| account_id | int(10) | YES | | NULL | |
| item_id | int(10) | YES | | NULL | |
| bid | int(10) | YES | | NULL | |
| buyout | int(10) | YES | | NULL | |
| leader | int(13) | YES | | NULL | |
| left | int(10) | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
left - field in unix timestamp format like '1391143424'. This shows the timestamp after which the lot should be expired.
I need to develop efficient algorithm for:
-when customer click on SEARCH button, the result will show only non-expired lots
-once lot expired it should be automatically put into completed_lots table
I have some ideas, but want to verify if there is any better approaches:
1: add additional search criteria like:
WHERE '$currtime' <= left;
2: setup some asynchronous tasks using crontab that will check lots table for expired lots every 5 minutes and move it to completed_lots table.
Are there any better ways? maybe using another mysql filed types for unix time, or create some mysql functions that will do that job automatically?
I have one table:
I first create a new record in CARTONS_CURRENT inserting values to "part_no" and "qty".
Next, I later need to add or pull (subtract) from "qty" using two other columns for adding and pulling.
How do I make "qty" show the latest result from CARTONS_ADDED and CARTONS_PULLED?
I also need to timestamp each new, add and pull.
TABLE NAME: cartons_current
+------------+--------------+--------+--------+-------------------+------------+
| Column | Type | Null | Key | Default | Extra |
+------------+--------------+--------+--------+-------------------+------------+
| part_no | varchar(20) | No | Prim | | |
+------------+--------------+--------+--------+-------------------+------------+
| qty | int(8) | No | | | |
+------------+--------------+--------+--------+-------------------+------------+
| qty_time | timestamp | No | | CURRENT_TIMESTAMP | |
+------------+--------------+--------+--------+-------------------+------------+
| add_qty | int(8) | No | | | |
+------------+--------------+--------+--------+-------------------+------------+
| add_time | timestamp | No | | CURRENT_TIMESTAMP | |
+------------+--------------+--------+--------+-------------------+------------+
| pull_qty | int(8) | No | | | |
+------------+--------------+--------+--------+-------------------+------------+
| pull_time | timestamp | No | | CURRENT_TIMESTAMP | |
+------------+--------------+--------+--------+-------------------+------------+
In a BEFORE UPDATE trigger you can change the values, so you can do your timestamp magic in those, you you store the last change.
DELIMITER $$
CREATE TRIGGER ai_cartons_each BEFORE UPDATE ON cartons
FOR EACH ROW
BEGIN
IF new.qty_added <> old.qty_added THEN
SET new.added_timestamp = NOW();
END IF;
END $$
DELIMITER ;
See also this answer to your other question:
How do I update a qty field from adding and subtracting fields with timestamps?