My Use Case :
I am trying to create a GUI and implement it with MYSQL Database. The problem I am facing is the scenario when I have to update a certain entry in the Database.
I know that we can update an Entry in MYSQL database using :
ALTER TABLE <TABLENAME> SET <PARAMETERS=NEW VALUES> WHERE <CONDITION> ;
For eg : If I want to change the name of the guy who id is 2 , I have to write :
ALTER TABLE StudentInfo SET Name='ABC' WHERE id=2 ;
But the problem is , in a GUI based environment , a user can choose to update any particular value wihtout having a constant condition like id in the previous example.
In the UI , the user can opt to select anything from the parameters and modify it and then click the update button.
Now How will I figure out what <CONDITION> to put in the MYSQL query when I need to update the database ?
Any help would be greatly appreciated !
you update a by using the UPDATE command not ALTER, which will change table. Your gui already knows ho tow identify the row in your case for example by the column name
UPDATE StudentInfo SET Name='ABC' WHERE Name='QUERTY';
SEE example
CREATE TABLE StudentInfo(
Name VARCHAR(20),
class int,
section VARCHAR(2),
roll_no int
);
INSERT INTO StudentInfo VALUES ('abc',12,'A',18), ('xyz',12,'A',17),('QUERTY',12,'A',16)
UPDATE StudentInfo SET Name='ABC',class = 15,section = 'B',roll_no= 99 WHERE Name='QUERTY';
SELECT * FROM StudentInfo
Name | class | section | roll_no
:--- | ----: | :------ | ------:
abc | 12 | A | 18
xyz | 12 | A | 17
ABC | 15 | B | 99
db<>fiddle here
The main problem is to identify the correct row, so you should have a field that is unique.
Like an id auto_increment, that is invisible for the user, but you can identify every row and use this id to update the row.
UPDATE StudentInfo SET Name='ABC' WHERE id = 3;
So that if you have two rows with John Smith you still could update the right one
Related
I want to add a new record in a table if duplicate value enters in a unique field. I don't want to update the existing one but want to add a new record by modifying the unique field value.
Is this possible in mysql?
EDIT:
Edited after user comment on this post:
You need write table locking on both of those two processes.
A WRITE lock has the following features:
The only session that holds the lock of a table can read and write data from the table.
Other sessions cannot read data from and write data to the table until the WRITE lock is released.
Also look at SQL UNIQUE Constraint
BEFORE EDIT:
Yes it is possible. And it took me awhile to figure it out. I build this on your input and compering values as test1, test2 etc, where test is always the same and has trailing number. As you specified.
It can be done as MySQL TRANSACTION in 4 steps.
Lets say you have table testT where name is unique to insure we have no doubles.
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
And you want to insert a new item with name test1 we set is as:
SET #newName = 'test1';
Then we need to check if it already exists in table:
SELECT #check:=COUNT(*) FROM testT WHERE name = #newName;
We do a count here to get true or false and save it as #check here so we can compare it later. This will result into 1 row as test1 already exists in table.
Next we do another selection to get the highest number of test* and store it as #number, this next query selects all tests and does a SUBSTRING after 4 latter's giving us all numbers after first 4 latter's. (99999999999) numbers actually just to be sure we don't miss any but in our case result is only "3" because that is last record "test3" in table.
SELECT
#number:= SUBSTRING(name,5,99999999999)
FROM testT;
Now we can do an insert:
INSERT INTO testT(name)
VALUES
(
IF(#check = "", #newName , CONCAT(LEFT(#newName,4),RIGHT(#number,1)+1)
)
);
This tries to insert our #newName into table under IF condition, and that is if our #check is empty then he will insert #newName, if not it will take word test out of string and append a highest #number from earlier and add + 1 too it.
So result for #newName = 'test1' is below. If you change this into #newName = 'test3' result wold be same new insert test4.
**Schema (MySQL v5.7)**
SET #newName = 'test1';
---
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test4 |
---
And if you change it in ANY test* that number does not already exists it will insert it normally. In case below: #newName = 'test6'
SET #newName = 'test6';
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test6 |
This way an insert will always be made.
You can play with this here : View on DB Fiddle just by changing SET #newName = 'test6'
I am no expert and it took me couple of hours to figure this way out, as I wanted to know if this was even possible.
And I would appreciate if any other user can suggestion any other way or improve my method.
I have 3 tables in mysql database that is linked to my issue tracker.
tables are:
1.Issues (contains ID, Issue_name & assignee)
2.change_group (contains ID, Issue_id, created_time)
3.change_item (contains id, group_id,field, old string , new string)
when any change occures about my isuues like changing status or assignee of issue,
table change_group will have new record. one goupid is matched with one or more records in change_item table. for example on group_id can save change in status and assignee of an issue:
now
according to changing assignees of issue I added a column with assignee name into issue table and I want to have a trigger that save snapshot of assigee field when a change happens.and I tried this:
create TRIGGER save_Assignee AFTER INSERT ON changeitem
FOR EACH ROW
BEGIN
SET new.assignee=(select assignee from jiraissue INNER JOIN changegroup ON jiraissue.ID=changegroup.issueid)
END
It seems that I cant Have inner join with trigger at same time.
If anyone has any thoughts on this it would be much appreciated. Thanks
MINA
table "issues"
id | Issue_name | Assignee
11 | R&D | User1
table "changegroup"
id | issue_ID | Created_time
12 | 11 | 2015/2/2 16:40
table "change_item"
id | group_id | field | old string | new string
13 | 12 |status | to do | in progress
I want to have a trigger to save who is assignee at the time that change happens on an issue?
You want a before insert trigger, not an after insert trigger:
create TRIGGER save_Assignee BEFORE INSERT ON changeitem
FOR EACH ROW
BEGIN
SET new.assignee=(select assignee from jiraissue INNER JOIN changegroup ON jiraissue.ID = changegroup.issueid)
END
I also suspect that your subquery is all wrong. It probably returns too many rows, because it needs a reference to new. However, that is not your question. If you decide that you have such problems, then ask another question, with sample data and desired results.
I have one table in my database. Field of table are describe below.
ID | NAME | QUALIFICATION
1 | ABC | Phd
2 | XYZ | MBA
3 | ADS | MBA
Now my problem is related to update QUALIFICATION record. Suppose if I update record of QUALIFICATION, it should be append new value to existing value.
For example, I am going to update record of id=1. Now I update "QUALIFICATION" MCA then it should add MCA to the existing record Phd, separated with comma. Output will looks like below.
ID | NAME | QUALIFICATION
1 | ABC | Phd,MCA
2 | XYZ | MBA
3 | ADS | MBA
When "QUALIFICATION" is null then the update should not be add comma before MCA.
Thats a bad database design never store the data as comma separated string, this will make things messy in future.
You should think of normalizing the table something as for the student your table should look like
- id primary key auto_incremented
- name
- other columns related to student
Then another table as student_qualification
- id primary key auto_incremented
- id_student ( id from student table)
- qualification
So for each student you can add as many qualification as possible to this table and can easily do add/edit/delete data
You can later easily retrieve data using simple joining the table.
first u have to select your existing value of Qualification column
that u want to update
Using
select qualification from tb_name where id = 1
Using above query u will get your qualification column value
suppose in
$qulification
Now update that row using
update set tb_name set qualification = '".$qualification."."your new value" where id = 1
May you can try this
update employee set qualification = qualification || ',MCA' where id = 1
the above will work in oracle
EDIT:
Then you can have the case statement with it
update employee set qualification = case when qualification is null then
'MCA' else qualification || ',MCA' end where id = 1
You can test for NULL in the SET clause, and use concatenation to format the string appropriately.
update student
set qualification = concat(if (qualification is not null
, concat( qualification, ',')
, '' )
, 'MBA')
where id = 1;
Here is a working SQL Fiddle (which also demonstrates behaviour with a NULL qualification).
I agree with #Abhik that this is a bad design for this specific data, and normalization is the better approach for the use case you provide However, there are other use cases where doing this sort of update would be perfectly valid so the question is worthy of a proper answer..
first of all sorry if this question is very bad , but I 'm really confused and google doesn't help :(
I have a table named "project" which has the following columns:
Name | Description | Max Grade |
1 | blabla | 2 |
I have another table named "uploaded_projects" which has the following columng:
Pname | Team Code | Grade | Max Grade |
1 | 234 | 2 | (that's what i want) |
I added a foreign key constrait with the following code.
ALTER TABLE uploaded_projects
ADD CONSTRAINT 'fk_u_p' FOREIGN KEY 'fk_u_p'(Pname)
REFERENCES 'project'(Name)
Now I want to fill the second table's column " Max Grade" with the values of 1st table's "max grade" column , which are conected through columns "Name"(1st tabled primary key) and "Pname" ( 2nd table column). How can I do that?
Thank you in advance
You can try update statement
UPDATE uploaded_projects, project
SET uploaded_projects.max_grade= project.max_grade
WHERE project.`name`= uploaded_projects.pname
or use join
UPDATE uploaded_projects AS t1
INNER JOIN project AS t2 ON t1.pname= t2.`name`
SET t1.max_grade = t2.max_grade
Update upload_projects
Inner join project on (upload_projects.pName = project.Name )
set upload_projects.MaxGrade = project.MaxGrade
My problem is: I have a table with an auto_increment column. When I insert some values, all is right.
Insert first row : ID 1
Insert second row : ID 2
Now I want to insert a row at ID 10.
My problem is, that after this there are only rows inserted after ID 10 (which is the normal behaviour ).
But I want that the database first fills up ID 3-9 before making that.
Any suggestions?
EDIT:
To clarify: this is for an URL shortener I want to build for myself.
I convert the id to a word(a-zA-z0-9) for searching, and for saving in the database I convert it to a number which is the ID of the table.
The Problem is now:
I shorten the first link (without a name) -> ID is 1 and the automatically name is 1 converted to a-zA-Z0-9 which is a
Next the same happenes -> ID is 2 and the name is b, which is 2 converted.
Next interesting, somebody want to name the link test -> ID is 4597691 which is the converted test
Now if somebody adds another link with no name -> ID is 4597692 which would be tesu because the number is converted.
I want that new rows will be automatically inserted at the last gap that was made (here 3)
You could have another integer column for URL IDs.
Your process then might look like this:
If a default name is generated for a link, then you simply insert a new row, fill the URL ID column with the auto-increment value, then convert the result to the corresponding name.
If a custom name is specified for a URL, then, after inserting a row, the URL ID column would be filled with the number obtained from converting the chosen name to an integer.
And so on. When looking up for integer IDs, you would then use the URL ID column, not the table auto-increment column.
If I'm missing something, please let me know.
You could do 6 dummy inserts and delete/update them later as you need. The concept of the auto increment, by design, is meant to limit the application's or user's control over the number to ensure a unique value for every single record entered into the table.
ALTER TABLE MY_TABLE AUTO_INCREMENT = 3;
You would have to find first unused id, store it as user variable, use as id for insert.
SELECT #id := t1.id +1
FROM sometable t1 LEFT JOIN sometable t2
ON t2.id = t1.id +1 WHERE t2.id IS NULL LIMIT 1;
INSERT INTO sometable(id, col1, col2, ... ) VALUES(#id, 'aaa', 'bbb', ... );
You will have to run both queries for every insert if you still have gaps, its up to you to decide whether it is worth doing it.
not 100% sure what you're trying to achieve but something like this might work:
drop table if exists foo;
create table foo
(
id int unsigned not null auto_increment primary key,
row_id tinyint unsigned unique not null default 0
)
engine=innodb;
insert into foo (row_id) values (1),(2),(10),(3),(7),(5);
select * from foo order by row_id;
+----+--------+
| id | row_id |
+----+--------+
| 1 | 1 |
| 2 | 2 |
| 4 | 3 |
| 6 | 5 |
| 5 | 7 |
| 3 | 10 |
+----+--------+
6 rows in set (0.00 sec)