how to set a column to be a primary key? - mysql

I have this table in mysql database
number | username | friendname | location
------------------------------------------------------------
1 | Nifa salem |jack | 47.117828 -88.545625
2 | Flora | fred | 38.898556 -77.037852
3 | Flora | Nifa salem | 32.9697 -96.80322
4 | Flora | Anne | 29.46786, -98.53506
but it says this " This table does not contain a unique column. Grid edit, checkbox, Edit, Copy and Delete features are not available."
Now i need to set the number column to be the priamry key column! how can o do it! as i need to edit the data in this table.

You can do this when creating the table ...
CREATE TABLE `admin` (
`id` int(8) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL DEFAULT '',
`friendname` varchar(64) NOT NULL DEFAULT '',
`locatino` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Is this not as simple as
ALTER TABLE yourTableName
ADD PRIMARY KEY (number);

ALTER TABLE TableName ADD PRIMARY KEY(Number);

Related

Calculate date based on row values and timestamp

So i'm trying to create a library database and was wondering if something i'm trying to achieve is possible through the use of triggers or similar.
I have this table called "category" which contains the different categories that you can borrow, like books or dvds.
And depending on what product category you lend from, you have different times allowed, like books you can borrow for 3 weeks but dvds are only allowed 3 days.
+--------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
| time_allowed | time | NO | | NULL | |
| days_allowed | varchar(400) | NO | | NULL | |
+--------------+---------------+------+-----+---------+----------------+
And then i have the table "Borrowed" which looks like this
+---------------+-------------------+-------+-----+----------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------------+-------+-----+----------------------+-----------------------------+
| id | int(11) | NO | PRI | None | auto_increment |
| item_id | int(11) | NO | | NULL | |
| date_borrowed | timestamp | NO | | CURRENT_TIMESTAMP | |
| return_by | datetime | NO | | None | |
| returned | enum('No','Yes') | NO | | No | |
| borrower_id | int(11) | NO | | None | |
| time_returned | timestamp | Yes | | CURRENT_TIMESTAMP | ON UPDATE CURRENT_TIMESTAMP |
+---------------+-------------------+-------+-----+----------------------+-----------------------------+
Now what i want to do is take the "date_borrowed" from "Borrowed" + "time_allowed" + "days_allowed" from the "Category" table to create the datetime value for "return_by" in the "Borrowed" table.
So if the "date_borrowed" is "2016-01-01 12:00:00" and a dvd is borrowed then the "return_by" should be "2016-01-04 12:00:00".
Is this possible to do through Triggers ?
Any and all feedback is much appreciated.
UPDATE:
CREATE TABLE `borrowed` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_id` int(11) DEFAULT NULL,
`date_borrowed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`return_by` datetime NOT NULL,
`returned` enum('No','Yes') CHARACTER SET utf8 NOT NULL DEFAULT 'No',
`borrower_id` int(11) NOT NULL,
`time_returned` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `borrower_id_idx` (`borrower_id`),
KEY `item_id_idx` (`item_id`),
CONSTRAINT `borrowed_ibfk_1` FOREIGN KEY (`item_id`) REFERENCES `items` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `borrower_id` FOREIGN KEY (`borrower_id`) REFERENCES `borrower` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
CREATE TABLE `category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8 NOT NULL,
`time_allowed` time NOT NULL,
`days_allowed` varchar(400) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
CREATE TABLE `items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_name` varchar(150) CHARACTER SET utf8 NOT NULL,
`item_uniqueid` varchar(100) CHARACTER SET utf8 NOT NULL COMMENT 'This can be a Serial Number or a ISBN number. But has to be unique for that item',
`item_status` enum('Ok','Damaged','Broken') CHARACTER SET utf8 NOT NULL,
`item_comment` longtext CHARACTER SET utf8,
`item_retired` enum('No','Yes') CHARACTER SET utf8 NOT NULL DEFAULT 'No',
`item_dop` date NOT NULL COMMENT 'item_dop = Item Date Of Purchaes',
`item_category` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id_category_idx` (`item_category`),
CONSTRAINT `id_category` FOREIGN KEY (`item_category`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
First you need to allow NULLs for the return_by column:
ALTER TABLE `borrowed`
ALTER `return_by` DROP DEFAULT;
ALTER TABLE `borrowed`
CHANGE COLUMN `return_by` `return_by` DATETIME NULL AFTER `date_borrowed`;
Then create a BEFORE INSERT trigger for the borrowed table:
DELIMITER //
CREATE TRIGGER `borrowed_before_insert` BEFORE INSERT ON `borrowed` FOR EACH ROW BEGIN
set new.return_by = (
select new.date_borrowed
+ interval c.days_allowed day
+ interval time_to_sec(c.time_allowed) second
from items i
join category c on c.id = i.item_category
where i.id = new.item_id
);
END//
DELIMITER ;
SQLFiddle-Demo
If you ever update the date_borrowed column, you will also need an UPDATE trigger to ajust the return_by value.
Assuming that you time_allowed is in HOUR, your days_allowed is in number of days (an not a varchar for string) and the two tables are related by a column relation_key and key you could suing a select llike this
select TIMESTAMPADD(HOUR, c.time_allowed,
TIMESTAMPADD( DAY ,c.days_allowed,b.date_borrowed) )
from Borrowed as b
inner join catogory on b.relation_key = c.key

SQL one to many users foreign key issue

Error: Cannot add or update a child row: a foreign key constraint
fails?
(testlogin.leavetable, CONSTRAINT leavetable_ibfk_1 FOREIGN KEY
(users_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE)
Been getting this message for the last day and a half. Trying to make a one to many (foreign key) relationship between the two tables. Between users:id and leavetable:users_id. When user logs in they get a id. when they submit a form to column hours I'd like for the id to stay with the form data. It is throwing the error when someone creates a new id number and it wont update the leavetable:user_id. It throws the error above.
What's going on? Am I approaching this the right way?
Here's my code:
CREATE TABLE IF NOT EXISTS `users` (
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`id` int(11) NOT NULL,
`password` char(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`salt` char(16) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `leavetable` (
`hours` int(11) NOT NULL,
`users_id` int(11) DEFAULT NOT NULL,
`id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `users`
ADD PRIMARY KEY (`id`) USING BTREE,
ADD UNIQUE KEY `email` (`email`) USING BTREE,
ADD UNIQUE KEY `username` (`username`) USING BTREE;
ALTER TABLE `leavetable`
ADD PRIMARY KEY (`id`) USING BTREE,
ADD KEY `users_id` (`users_id`) USING BTREE;
ALTER TABLE `leavetable`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
-- AUTO_INCREMENT for table `users`
ALTER TABLE `users`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `leavetable`
ADD CONSTRAINT `leavetable_ibfk_1` FOREIGN KEY (`users_id`) REFERENCES
`users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
my table structure:
+---------------------+
| Tables_in_testlogin |
+---------------------+
| leavetable |
| users |
+---------------------+
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| email | varchar(255) | NO | UNI | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
| password | char(64) | NO | | NULL | |
| salt | char(16) | NO | | NULL | |
| username | varchar(255) | NO | UNI | NULL | |
+----------+--------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| hours | int(11) | NO | | NULL | |
| users_id | int(11) | NO | MUL | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
+----------+---------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
php code:
mysql_select_db("testlogin", $con);
$sql="INSERT INTO leavetable (hours)
VALUES
('$_POST[hours]')";
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
$sql="INSERT INTO leavetable (hours)
VALUES
('$_POST[hours]')";
The above sql code does not contain any reference to user id. How should mysql guess which user this leave entry belong to? Include tge user id both in the columns and the values section of the insert statement. Probably you should store the user id in the php session.
Looks like I've got it going. I basically have a hidden field in my form with the users id. when the form is submitted it is submitted with the form information to leavetable. Not sure if this is the right way to go about it but it seems to work.
form code:
<input type="number" name="hours" value="" />
<label>id: </label>
<input type="text" name="id" value="<?php
echo htmlentities($_SESSION['user']['id'], ENT_QUOTES, 'UTF-8');
?>" /> <br /><br />
<input type="submit" class="btn btn-info" name="submit" value="Submit" />
sql:
$sql = "INSERT INTO leavetable ( hours, users_id )
VALUES ( '{$mysqli->real_escape_string($_POST['hours'])}',
'{$mysqli->real_escape_string($_POST['id'])}' )";
$insert = $mysqli->query($sql);
It works. Is it the best way to go about this?

Trying to remove a primary key from MySQL table

Edit: Not sure why this is marked as a duplicate. The error I am getting is different
I am trying to remove a primary key definition but am receiving an error for some reason.
mysql> ALTER TABLE `aux_sponsors` DROP PRIMARY KEY;
ERROR 1091 (42000): Can't DROP 'PRIMARY'; check that column/key exists
mysql> desc aux_sponsors;
+-------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| unit | varchar(8) | NO | | MF | |
| code | varchar(32) | NO | PRI | NULL | |
| userid | varchar(32) | NO | | | |
| fullName | varchar(64) | NO | | | |
| department | varchar(255) | NO | | | |
| description | varchar(255) | NO | | NULL | |
+-------------+--------------+------+-----+---------+-------+
6 rows in set (0.01 sec)
Am I doing something wrong here? I simply want no more primary key in this table.
mysql> SHOW CREATE TABLE aux_sponsors;
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| aux_sponsors | CREATE TABLE `aux_sponsors` (
`unit` varchar(8) NOT NULL DEFAULT 'MF',
`code` varchar(32) NOT NULL,
`userid` varchar(32) NOT NULL DEFAULT '',
`fullName` varchar(64) NOT NULL DEFAULT '',
`department` varchar(255) NOT NULL DEFAULT '',
`description` varchar(255) NOT NULL,
UNIQUE KEY `code` (`code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
You don't have a PRIMARY KEY; you have a UNIQUE key. So, you can't do this:
ALTER TABLE `aux_sponsors` DROP PRIMARY KEY
Instead, just do
ALTER TABLE `aux_sponsors` DROP KEY `code`
DESC (a/k/a DESCRIBE) is not a true MySQL feature; according to the docs, "The DESCRIBE statement is provided for compatibility with Oracle."
More from the documentation:
A UNIQUE index may be displayed as PRI if it cannot contain NULL values and there is no PRIMARY KEY in the table. A UNIQUE index may display as MUL if several columns form a composite UNIQUE index; although the combination of the columns is unique, each column can still hold multiple occurrences of a given value.
In your case, the column code is NOT NULL and is the only column in a UNIQUE key, so DESC is showing it as PRI. Because of this type of problem, it's better to use SHOW INDEX to find out the types of keys on a table.

Altering existing unique constraint

I have a table that was defined like this:
CREATE TABLE `Message` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`user_id` integer NOT NULL,
`user_to` integer NOT NULL,
`top_num` integer NOT NULL,
`priority` smallint NOT NULL,
`error` varchar(120) NOT NULL,
UNIQUE (`user_id`, `user_to`, `top_num`)
);
Later, I added another column to it, msg_type, like this:
ALTER TABLE Message ADD COLUMN msg_type SMALLINT(6) NOT NULL DEFAULT 0;
However, I have come to realize that I need to change my original UNIQUE constraint to include msg_type. I tried running
ALTER TABLE Message
ADD UNIQUE INDEX (`user_id`, `user_to`, `top_num`, `msg_type`);
but INSERTs into my table still fail, and the error message indicates that that is because the old uniqueness constraint fails.
When I call describe Messages in mysql I see the following:
+-----------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| user_to | int(11) | NO | MUL | NULL | |
| top_num | int(11) | NO | MUL | NULL | |
| priority | smallint(6) | NO | | NULL | |
| error | varchar(120) | NO | | NULL | |
| msg_type | smallint(6) | NO | | 0 | |
+-----------------+----------------------+------+-----+---------+----------------+
which makes it seem like msg_type really isn't part of the constraint... How can I alter the constraint that the table was defined with, short of recreating the table?
As in previous answer to change foreign key constraint use steps:
Step 1: Drop old constraint:
ALTER TABLE `Message` DROP INDEX `user_id`;
Step 2: Add new:
ALTER TABLE `Message` ADD UNIQUE INDEX (
`user_id`,
`user_to`,
`top_num`,
`msg_type`);
Use SHOW CREATE TABLE to know name of constraint:
mysql> SHOW CREATE TABLE `Message` ;
| Message | CREATE TABLE `Message` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`user_to` int(11) NOT NULL,
`top_num` int(11) NOT NULL,
`priority` smallint(6) NOT NULL,
`error` varchar(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`user_to`,`top_num`)
-- ^^^^^^^^^ name
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
If you checks:
mysql> SHOW INDEX FROM `Message`;
Key_name is user_id that is first argument in UNIQUE (user_id ....
Suppose if you write:
ALTER TABLE `Message` ADD UNIQUE INDEX (
`user_to`,
`user_id`,
`top_num`,
`msg_type`);
Then you have to drop using user_to as:
ALTER TABLE `Message` DROP INDEX `user_to`;
This is because you are adding unique index. Please first drop unique index and then add unique constraint.
-- you have to drop each index one by one.
ALTER TABLE Message DROP UNIQUE INDEX user_id;
and now add unique constraint.
ALTER TABLE Message ADD CONSTRAINT uc_message UNIQUE (`user_id`, `user_to`, `top_num`, `msg_type`);
This is because you haven't deleted the first unique constraint you have created. Right now, you have two unique constraints on your table.
To delete a unique constraint, have a look at this post
Dropping Unique constraint from MySQL table
This is because you are adding unique index. Please first drop unique index and then add unique constraint.
DROP INDEX index_name ON table_name
and now add unique constraint.
ALTER TABLE Message
ADD CONSTRAINT uc_message UNIQUE ((`user_id`, `user_to`, `top_num`, `msg_type`);)

Trouble adding foreign key

I'm trying to add a foreign key constraint to the table ag by using:
alter table ag
add foreign key fk_ag_protein1 (protein_PID) references protein (PID);
But I get the following error message:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
(`mux_new`.`#sql-884_3`, CONSTRAINT `#sql-884_3_ibfk_1` FOREIGN KEY (`protein_PID`)
REFERENCES `protein` (`PID`))"
To get more details I checked output from:
SHOW ENGINE INNODB STATUS\G
Which was:
LATEST FOREIGN KEY ERROR
------------------------
TRANSACTION 193923, ACTIVE 0 sec inserting, thread declared inside InnoDB 4999
mysql tables in use 2, locked 2
5 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 3, OS thread handle 0x1714, query id 143 localhost ::1 root copy
to tmp table
alter table ag
add foreign key fk_ag_protein1 (protein_PID) references protein (PID)
Foreign key constraint fails for table `mux_new`.`#sql-884_3`:
,
CONSTRAINT `#sql-884_3_ibfk_1` FOREIGN KEY (`protein_PID`) REFERENCES `protein
` (`PID`)
Trying to add in child table, in index `fk_ag_protein1` tuple:
DATA TUPLE: 2 fields;
0: len 4; hex 80000000; asc ;;
1: len 3; hex 002711; asc ' ;;
But in parent table `mux_new`.`protein`, in index `PRIMARY`,
the closest match we can find is record:
PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 696e66696d756d00; asc infimum ;;
But I do not understand this at all. The table ag currently contains some data but protein does not.
Any ideas of what my problem could be or things I could check?
Protein table:
describe protein output:
+---------------------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------+---------+------+-----+---------+-------+
| PID | int(11) | NO | PRI | NULL | |
| uniprot_UniprotAC | char(6) | YES | MUL | NULL | |
| pubmedhits_id | int(11) | YES | MUL | NULL | |
| internallyDefinedNames_id | int(11) | YES | MUL | NULL | |
| comment | int(11) | YES | MUL | NULL | |
+---------------------------+---------+------+-----+---------+-------+
show create table protein output:
CREATE TABLE `protein` (
`PID` int(11) NOT NULL,
`uniprot_UniprotAC` char(6) COLLATE utf8_unicode_ci DEFAULT NULL,
`pubmedhits_id` int(11) DEFAULT NULL,
`internallyDefinedNames_id` int(11) DEFAULT NULL,
`comment` int(11) DEFAULT NULL,
PRIMARY KEY (`PID`),
KEY `fk_protein_uniprot1_idx` (`uniprot_UniprotAC`),
KEY `fk_protein_pubmedhits1_idx` (`pubmedhits_id`),
KEY `fk_protein_internallyDefinedNames1_idx` (`internallyDefinedNames_id`),
KEY `fk_protein_comments1_idx` (`comment`),
CONSTRAINT `protein_ibfk_4` FOREIGN KEY (`uniprot_UniprotAC`) REFERENCES `uniprot` (`UniprotAC`),
CONSTRAINT `protein_ibfk_1` FOREIGN KEY (`comment`) REFERENCES `comments` (`idcomments`),
CONSTRAINT `protein_ibfk_2` FOREIGN KEY (`internallyDefinedNames_id`) REFERENCES `internallydefinednames` (`id`),
CONSTRAINT `protein_ibfk_3` FOREIGN KEY (`pubmedhits_id`) REFERENCES `pubmedhits` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
ag table:
describe ag:
+-------------+--------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------------------------+------+-----+---------+-------+
| Article_AID | mediumint(5) unsigned zerofill | NO | PRI | NULL | |
| Name | varchar(200) | YES | | NULL | |
| Form | varchar(150) | YES | | NULL | |
| Mw | varchar(40) | YES | | NULL | |
| Source | varchar(260) | YES | | NULL | |
| protein_PID | int(11) | YES | | NULL | |
+-------------+--------------------------------+------+-----+---------+-------+
show create table ag:
`ag` (
`Article_AID` mediumint(5) unsigned zerofill NOT NULL,
`Name` varchar(200) COLLATE utf8_unicode_ci DEFAULT NULL,
`Form` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL,
`Mw` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
`Source` varchar(260) COLLATE utf8_unicode_ci DEFAULT NULL,
`protein_PID` int(11) DEFAULT NULL,
PRIMARY KEY (`Article_AID`),
KEY `fk_ag_Article1_idx` (`Article_AID`),
CONSTRAINT `fk_ag_Article1` FOREIGN KEY (`Article_AID`) REFERENCES `article` (`AID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
I figured out what the problem was. In the ag table the protein_PID column was added when there was already data in the table and when it was first created it was set to be not null. Then the rows where all set to 0 for protein_PID as default and since there was no data in protein I could not add the foreign key.
Make PID and protein_PID both to not NULL
May this will solve your issue