Mandatory field mysql - mysql

How to make sure that field is mandatory ? Here is what I mean
I have the following mysql table structure:
CREATE TABLE `new` (
`id` int(11) DEFAULT NULL,
`name` int(11) DEFAULT NULL,
`phone` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Here is query with no data for phone
insert into new values(1, 'm', '');
But the query runs fine. What should be done so that mysql returns an error if there is no data for phone field? I can do that validation by php, but I'm curious how to do that in mysql.

Possibly setting the default value of the 'phone' column to NULL would make it fail insertion because it would end up null if you did not specify it.
Otherwise you're going to need to omit the phone column for the default to kick in, say in php you'd use empty($phone) ? null : $phone; or something along those lines.

INSERT INTO new VALUES(1,'m',NULL)
will cause error.
If you want to check whether is the phone number field is a blank string,
you can use a trigger in MySQL.

I haven't tested this, but I have a feeling the '' != null. What happens if you run
insert into new(id, name) values (1, 'test');
I bet you get an insert error...
Anyway, I think its probably better to be validating in PHP than waiting till you get to the database... inserts are expensive...

'' as the 3rd option doesnt make the value of phone null.. It is just equal to a blank string thats all.
if you want to see an error, replace '' with NULL.

Related

Error on INSERT statement: "VALUE is not valid at this position"

VALUE is not valid at this position
The error is on VALUES within the INSERT statement. It states it is not supported within this version. Does that mean i require an update or is my syntax wrong?
create schema Cleudo;
USE CLEUDO;
create table Victim(
Vic_ID INT NOT NULL AUTO_INCREMENT,
Vic_Title VARCHAR(10) NOT NULL,
Vic_Name VARCHAR(30) NOT NULL,
Vic_Room VARCHAR(30) NULL,
Vic_TOD VARCHAR(5) NULL,
Vic_Weapon VARCHAR(30) NULL,
PRIMARY KEY ( VIC_ID )
);
INSERT INTO Victim VALUES ('Miss','Scarlet','Library','10:45','candle-Stick');
When I run your code, I get the following error:
Column count doesn't match value count at row 1
This is happening because you are not giving a value to table Vic_ID (which makes sense, because it is auto-incremented). To avoid the error, you need to enumerate the target columns, like so:
INSERT INTO Victim (Vic_Title, Vic_Name, Vic_Room, Vic_TOD, Vic_Weapon)
VALUES ('Miss','Scarlet','Library','10:45','candle-Stick');
Demo on DB Fiddle
You are getting this error because the number of columns are not the same, so you need to change your query to this:
INSERT INTO Victim(Vic_Title,Vic_Name,Vic_Room,Vic_TOD,Vic_Weapon) VALUES ('Miss','Scarlet','Library','10:45','candle-Stick');
In case you want to specify the Vic_ID value you can try this query below instead:
INSERT INTO Victim VALUES (NULL,'Miss','Scarlet','Library','10:45','candle-Stick')

Mysql Not Null Field on Insert

This is my query:
INSERT INTO tabla (campo1,campo2,campo3) VALUES ('$campo1','$campo2','$campo3')
Since 'tabla' has many more columns and some of them are not null and neither have a default value, I'm getting the mysql message: "Fiel 'column4' doesn't have a default value".
I'm running that on my local server, tried it out at online server and it does insert the row with no issues.
Does anyone knows if this has to do with some sort of configuration of the mysql.ini file or something like that? There are too many columns like that on my db, so changing columns to 'null' or set them a default value would take a lot of time. I think it could be fixed as it works perfect on the server.
Thanks.
UPDATE:
It is the SQL mode. I queried SELECT ##GLOBAL.sql_mode;
My local server returned: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
The remote server returned an empty row.
Where can I change that setting on my localhost?
If you are sure that you are using the same schema both locally and on the remote server, it's probably the SQL mode of the remote server that's set different than the local SQL mode, you can check it with one of those:
SELECT ##GLOBAL.sql_mode;
SELECT ##SESSION.sql_mode;
This will reproduce the problem:
CREATE TABLE tabla (
campo1 VARCHAR(255) NOT NULL,
campo2 VARCHAR(255) NOT NULL,
campo3 VARCHAR(255) NOT NULL,
campo4 VARCHAR(255) NOT NULL);
SET ##SESSION.sql_mode= 'STRICT_TRANS_TABLES';
INSERT INTO table (campo1, campo2, campo3) VALUES ('a', 'b', 'c');
and this will work, even if there's a column costraint on campo4:
CREATE TABLE tabla (
campo1 VARCHAR(255) NOT NULL,
campo2 VARCHAR(255) NOT NULL,
campo3 VARCHAR(255) NOT NULL,
campo4 VARCHAR(255) NOT NULL);
SET ##SESSION.sql_mode= '';
INSERT INTO table (campo1, campo2, campo3) VALUES ('a', 'b', 'c');
Please see fiddle here.
Have a look at the manual at the Server SQL Modes page.
This weird behavior might depend on "sql_mode" system variable - it controls vast amount of quirks and settings.
So, check the mode by running select ##sql_mode; command on your both servers - it must output different values, so you know what mode is used on your local server.
If the column is not null you must provide its value when inserting record. There is no other way - it is not null just for forcing ANY data in it (even if its just EMPTY string. But you must provide it in the insert query.
You may add default value for the column.
Try importing remote table to your local one - that will minimize future problems with schema.

Inserting a value into one table based on insert from another table

I have this table for users that stores their usernames and other data, thats done like this (stripped down):
CREATE TABLE `prod_users` (
`p_user_id` INT(11) NOT NULL AUTO_INCREMENT,
`p_user_name` VARCHAR(200) NOT NULL DEFAULT ''
`p_comp_name` VARCHAR(300) NOT NULL DEFAULT '',
PRIMARY KEY (`p_user_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
Each time a user signs up, he'll provide a company name as well.
There's another table called prod_profiles, which stores profile details like phone nos. fax nos. etc.
CREATE TABLE `prod_profiles` (
`pf_gen_id` INT(11) NOT NULL AUTO_INCREMENT,
`pf_user_id` INT(11) NOT NULL DEFAULT '0',
`pf_user_name` VARCHAR(200) NOT NULL DEFAULT ''
`pf_comp_name` VARCHAR(300) NOT NULL DEFAULT '',
PRIMARY KEY (`pf_gen_id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
When a new user signs up and his details are added to prod_users, is it possible to automatically add his new user_id, user_name and comp_name details to prod_profile using MySql itself? Since each user will have a new p_user_id and we wont know it, it'll be difficult using php. Can this be achieved inside MySql itself without any problems?
It isn't difficult using PHP, since you have the LAST_INSERT_ID() available for use, be it via mysql_insert_id() or mysqli::$insert_id, PDO::lastInsertId() or whatever your API provides. As long as you call the two INSERT statements in immediate succession on the same script (it is connection dependent), MySQL will supply the correct p_user_id.
However, you can use an AFTER INSERT trigger to force MySQL to create the new row automatically:
CREATE TRIGGER build_profile AFTER INSERT ON prod_users
FOR EACH ROW
BEGIN
INSERT INTO prod_profiles
(pf_user_id, pf_user_name, pf_comp_name)
VALUES (NEW.p_user_id, NEW.p_user_name, NEW.p_comp_name)
END
Review the MySQL CREATE TRIGGER syntax reference for full details and options.
You can use the next mysql function: LAST_INSERT_ID(); which returns the last auto increased id.
Therefore , add a user and then add a prod_profile , while pf_user_id value will be the returned value of last_insert_id().
INSERT INTO `prod_users`(`p_user_name`,`p_comp_name`) VALUES('Dan' , 'Stackover')
INSERT INTO `prod_profiles`(`pf_user_id`,`pf_user_name`,`pf_comp_name`) VALUES(LAST_INSERT_ID(),'Dan','Stackover')
Please notice: I have to say , that storing the username and company_name twice for the same user in two different tables is a reall waste...
Consider re-thinking about your DB structre and logic.

Mandatory fields in database

I have created a database table like this:
CREATE TABLE test(
name VARCHAR(30) NOT NULL,
password VARCHAR(40) NOT NULL);
I then added to it like this, which failed as expected.
INSERT INTO test(name, password) VALUES ('test', NULL);
But then when I tried this it inserted without a problem:
INSERT INTO test(name) VALUES ('test');
I tried to create the table differently but it didn't create:
CREATE TABLE test(
name VARCHAR(30) NOT NULL,
password VARCHAR(40) NOT NULL DEFAULT NULL );
So is there a way to get that to create an error when inserting?
Perhaps associated I think I will need to do something else to be able to validate data input into the database anyway and I think I saw something about constraints but I don't think these are supported in mysql? So is the null check and validation something I can't do the database with mysql?
By default, MySQL replaces implicit NULL values with zeroes (or empty strings for string datatypes).
You can work around this by enabling strict mode for your session or server:
SET sql_mode='STRICT_ALL_TABLES'
or add
sql_mode='STRICT_ALL_TABLES'
under [mysqld] in your my.cnf.

MySQL insert query with missing not null fields

I currently trying to use an Object Relational Mapper for CodeIgniter and I'm experiencing something I did not expect.
I have a table with a couple of fields, some of which are NOT NULL. An insert query is which is missing of the NOT NULL fields is generated -- a new row is added but with blanks for those fields.
I did not know MySQL would disregard the NOT NULL fields that aren't present in the query and insert the row anyways. Is there a way to restrict this?
-Edit-
Let me add a few more details and try to explain it a bit more
Here is a sample table:
CREATE TABLE `test` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`color` varchar(40) COLLATE utf8_bin DEFAULT '',
`shape` varchar(40) COLLATE utf8_bin NOT NULL,
`size` varchar(40) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
Here is a sample query:
INSERT INTO `test` (`shape`) VALUES ('foo')
I don't have size in my query yet it still adds the row - is this expected?
(The sample query was run in phpMyAdmin)
I believe the accepted answer is incorrect, given the question's test INSERT statement. It looks to me like MySQL's "strict mode" is turned off for this table or database. From the docs:
Strict mode controls how MySQL handles input values that are invalid or missing... A value is missing when a new row to be inserted does not contain a value for a non-NULL column that has no explicit DEFAULT clause in its definition...
If you are not using strict mode (that is, neither STRICT_TRANS_TABLES nor STRICT_ALL_TABLES is enabled), MySQL inserts adjusted values for invalid or missing values and produces warnings.
You can find out how your database is running with these queries:
SELECT ##global.sql_mode;
SELECT ##session.sql_mode;
Changing these values is discussed here: https://stackoverflow.com/a/5273824/27846
Empty string is not the same thing as NULL. Perhaps ORM inserts just '' for those fields.
Not a codeigniter dev, but I would hazard a guess that the issue is your ORM is passing blank values on to the database, I would check your logs to verify this and if its the case, check your ORM if it has some validation options.