I'm a totally MySQL newcomer. Sr if my question is quite obvious. I got 2 tables
CREATE TABLE tbl_addresses(
PK_ADDRESS_ID int NOT NULL AUTO_INCREMENT,
house_number int NOT NULL,
street varchar(35),
district varchar(35),
city varchar(35),
postcode varchar(8),
PRIMARY KEY (PK_ADDRESS_ID)
);
CREATE TABLE tbl_people(
PK_PERSON_ID int NOT NULL AUTO_INCREMENT,
title varchar(6) NOT NULL, # Master / Mister therefor 6 is max
forename varchar(35) NOT NULL,
surname varchar(35) NOT NULL,
date_of_birth DATE NOT NULL,
contact_number varchar(12) NOT NULL,
FK_ADDRESS_ID int NOT NULL,
PRIMARY KEY (PK_PERSON_ID),
FOREIGN KEY (FK_ADDRESS_ID) REFERENCES tbl_addresses (PK_ADDRESS_ID)
);
and I'm trying to import data into these tables from Java using below syntaxes
INSERT INTO tbl_addresses (house_number,street,district,city,postcode) VALUES ('1','abc','','abc','abc');
INSERT INTO tbl_people (title,forename,surname,date_of_birth,contact_number) VALUES ('Mr','Tri ','Nguyen','1991-1-1','0123456789');
I got an error Field 'FK_ADDRESS_ID'doesn't have a default value and data actually goes into tbl_addresses but not tbl_people. Am I missing anything? Thanks in advance!
This error is being caused by that you labelled the FK_ADDRESS_ID field in the tbl_people table as NOT NULL, yet you are trying to do an INSERT without specifying a value for this column.
So something like this would work without error:
INSERT INTO tbl_people (title, forename, surname, date_of_birth,
contact_number, FK_ADDRESS_ID)
VALUES ('Mr', 'Tri', 'Nguyen', '1991-1-1', '0123456789', 1);
You could also specify a default value for FK_ADDRESS_ID (the error message you got alluded to this). Here is how you could adda default value:
ALTER TABLE tbl_people MODIFY COLUMN FK_ADDRESS_ID int NOT NULL DEFAULT 1
But because FK_ADDRESS_ID is a key into another table, the value should really be based on the primary key in tbl_addresses.
The fact that you are using a foreign key isn't the reason that you are getting this error. Let's take a look at your column definition.
FK_ADDRESS_ID int NOT NULL,
This is not null but does not a default. Now a look at your insert statement
INSERT INTO tbl_people (title,forename,surname,date_of_birth,contact_number)
FK_ADDRESS_ID isn't in your column list but it cannot be null and doesn't have a default so what can mysql do? Produce an error of course.
The best bet is to define that column as nullable.
Let's revisit the foreign key constraint.
FOREIGN KEY (FK_ADDRESS_ID) REFERENCES tbl_addresses (PK_ADDRESS_ID)
What this really says is that if you asign a value to FK_ADDRESS_ID that value should be present in PK_ADDRESS_ID column in tbl_address
as a side note, it's customary to use lower case for table/column names.
Related
I have a database. As you can see the primary key is an auto_increment and is also unique. I read that publically sharing a row's primary key of a table to the public is unsafe. I want to assign each row in customers a unique ID that I can publically share. How can I do this without having to specify each time what the public_id is in the INSERT statement? The database should automatically find a unique ID to assign to that row just like it does for id because of auto_increment.
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
-- public_id (an ID I can give to the public to uniquely identify this row
);
INSERT INTO customers (name) VALUES ('Bob'), ('Sarah'), ('Bob');
Well, here's one way:
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
public_id char(36) not null unique default uuid()
);
Note that the manual says:
Warning
Although UUID() values are intended to be unique, they are not necessarily unguessable or unpredictable. If unpredictability is required, UUID values should be generated some other way.
So this is simple, and maybe will float your goat, but we can also try better:
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
public_id char(24) not null unique default to_base64(random_bytes(18))
);
This will be a nice and dense identifier, but it will have characters + and / which don't play well with URLs. You can encode them, of course, but if you want to go one lazier, you can also do this:
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
public_id char(32) not null unique default hex(random_bytes(16))
);
Mind you, the identifier will get quite a bit longer this way.
To get the best of both worlds, we can do this, at the expense of a really long default value:
CREATE TABLE customers (
id int primary key auto_increment,
name varchar(32) not null,
public_id char(24) not null unique default replace(replace(to_base64(random_bytes(18)), '+', '_'), '/', '-')
);
Also note that messing around with MD5()/SHA()/SHA1()/SHA2() is no better than just generating a random hex string with a given length.
I keep getting the error code 'ORA-02270' and no matter what I try, I can't seem to fix it. Below are my Create Table statements:
CREATE TABLE student
(
studentID CHAR(8) PRIMARY KEY,
studentName VARCHAR(25) NOT NULL,
studentAddress VARCHAR(30) NOT NULL,
studentDOB DATE NOT NULL,
studentGender CHAR(1) NOT NULL CHECK ((studentGender = 'F') OR (studentGender = 'M')),
studentNationality VARCHAR(15) NOT NULL,
studentCourse VARCHAR(30) NOT NULL,
studentSemesterExcellent CHAR(1) NOT NULL CHECK ((studentSemesterExcellent = 'Y') OR (studentSemesterExcellent = 'N'))
);
CREATE TABLE leaseAgreement
(
leaseNo CHAR(6) PRIMARY KEY,
studentID CHAR(8) NOT NULL,
leaseAccommodationType VARCHAR2(10) NOT NULL,
leaseDuration NUMBER NOT NULL,
leaseStartDate DATE NOT NULL,
leaseEndDate DATE,
studentSemesterExcellent CHAR(1) NOT NULL CHECK ((studentSemesterExcellent = 'Y') OR (studentSemesterExcellent = 'N')),
FOREIGN KEY (studentID) REFERENCES student(studentID),
FOREIGN KEY (studentSemesterExcellent) REFERENCES student(studentSemesterExcellent)
);
Am I not allowed to have two foreign keys from the same table? Please can someone explain this error and point me in the right direction. Thank you.
First, the answer from mustaccio is correct.
The column 'studentSemesterExcellent' in table 'student' is no key column. You can not reference it in a foreign key constraint.
And if you make it unique you can only have two rows in the student table, not what you are intending.
Second, you have tagged the question both with MySQL and Oracle. Choose one!
Third, you only need one FK if it is a not null column. Don't make it harder on yourself.
Fourth, if this is Oracle database, the advice is to only use varchar2() for string data. The char and varchar datatypes exist for compatibility reasons.
I have created a table empInfo as follow
CREATE TABLE empInfo (
empid INT(11) PRIMARY KEY AUTO_INCREMENT ,
firstname VARCHAR(255) DEFAULT NULL,
lastname VARCHAR(255) DEFAULT NULL
)
Then I run below Insert statements :-
INSERT INTO empInfo VALUES(NULL , 'SHREE','PATIL');
INSERT INTO empInfo(firstname,lastname) VALUES( 'VIKAS','PATIL');
INSERT INTO empInfo VALUES(NULL , 'SHREEKANT','JOHN');
I thought first or Third SQL will fail as empid is PRIMARY KEY and We are trying to insert NULL for empid .
But MYSQL proved me wrong and all 3 queries ran successfully .
I wanted to know Why it is not failing when trying to insert NULL in empid column ?
Final Data available in table is as below
empid firstname lastname
1 SHREE PATIL
2 VIKAS PATIL
3 SHREEKANT JOHN
I can figure out that it has something releted to AUTO_INCREMENT But I am not able to figure out reason for it . Any pointers on this .
This behaviour is by design, viz inserting 0, NULL, or DEFAULT into an AUTO_INCREMENT column will all trigger the AUTO_INCREMENT behaviour.
INSERT INTO empInfo VALUES(DEFAULT, 'SHREEKANT','JOHN');
INSERT INTO empInfo VALUES(NULL, 'SHREEKANT','JOHN');
INSERT INTO empInfo VALUES(0, 'SHREEKANT','JOHN');
and is commonplace practice
Note however that this wasn't however always the case in versions prior to 4.1.6
Edit
Does that mean AUTO_INCREMENT is taking precedance over PRIMARY KEY?
Yes, since the primary key is dependent on the AUTO_INCREMENT delivering a new sequence prior to constraint checking and record insertion, the AUTO_INCREMENT process (including the above re-purposing of NULL / 0 / DEFAULT) would need to be resolved prior to checking PRIMARY KEY constraint in any case.
If you remove the AUTO_INCREMENT and define the emp_id PK as INT(11) NULL (which is nonsensical, but MySql will create the column this way), as soon as you insert a NULL into the PK you will get the familiar
Error Code: 1048. Column 'emp_id' cannot be null
So it is clear that the AUTO_INCREMENT resolution precedes the primary key constraint checks.
It is exactly because of the auto increment. As you can see, no empid values are null in the db. That is the purpose of auto increment. Usually you would just not include that column in the insert, which is same as assigning null
As per the documentation page:
No value was specified for the AUTO_INCREMENT column, so MySQL assigned sequence numbers automatically. You can also explicitly assign 0 to the column to generate sequence numbers. If the column is declared NOT NULL, it is also possible to assign NULL to the column to generate sequence numbers.
So, because you have an auto increment null-allowed field, it ignores the fact that you're trying to place a NULL in there, and instead gives you a sequenced number.
You could just leave it as is since, even without the not null constraint, you can't get a NULL in there, because it will auto-magically convert that to a sequenced number.
Or you can change the column to be empid INT(11) PRIMARY KEY AUTO_INCREMENT NOT NULL if you wish, but I still think the insert will allow you to specify NULLs, converting them into sequenced numbers in spite of what the documentation states (tested on sqlfiddle in MySQL 5.6.6 m9 and 5.5.32).
In both cases, you can still force the column to a specific (non-zero) number, constraints permitting of course.
CREATE TABLE empInfo (
empid INT(11) PRIMARY KEY AUTO_INCREMENT NOT NULL,
firstname VARCHAR(255) DEFAULT NULL,
lastname VARCHAR(255) DEFAULT NULL
)
Not sure but i think it will work :)
I have created a table with some attributes that have the NOT NULL constraint, then I have tried a INSERT INTO instruction, specifying values only for the fields that don't have the NOT NULL constraint, but the instruction still works. Shouldn't it work and give an error?
CREATE TABLE ciao(
Id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
Nome VARCHAR(30) NOT NULL,
Cognome VARCHAR(30) NOT NULL,
Nickname VARCHAR(30)
);
INSERT INTO ciao(Nickname) VALUES ('prova');
It is inserting empty string as the default value for the columns you didn't supply. That default is not specified in your create statement, so it's probably been created by someone else. If you run your create and insert on a clean DB, it fails.
I wrote schema:
CREATE TABLE user
(
user_id INT UNSIGNED AUTO_INCREMENT NOT NULL,
fname VARCHAR(20) NOT NULL,
lname VARCHAR(20) NOT NULL,
email VARCHAR(30) NOT NULL,
password VARCHAR(60) NOT NULL,
gender ENUM('M', 'F'),
CONSTRAINT pk_user_id PRIMARY KEY (user_id)
)
But when inserting only two values, lets say the users first name and last name, the email and password are left blank, meaning the not null is not working as expected. I do get 2 warnings when I show them, but the behavior is not as expected. Do I have to specifically make constraints to fail an insert to make sure this never happens?
Unfortunately, mysql does not support CHECK constraints.
They are "valid syntax" in mysql only for compatibility reasons, so you can code them, and the create table SQL will execute OK, but they are ignored thereafter.