I have 2 tables:
university:
university_id(p.k) | university_name
and user:
uid | name | university_id(f.k)
How to keep university_id NULL in user table?
I am writting only 1 query, my query is:
INSERT INTO user (name, university_id) VALUES ($name, $university_id);
Here $university_id can be null from front end.
university table will be set bydefault by me.
In the front end, student will select the university name, according to that the university_id will pass to user table, but if student is not selecting any university name then is should pass null value to the user table for university_id field.
Just allow column university_id of table user to allow NULL value so you can save nulls.
CREATE TABLE user
(
uid INT NOT NULL,
Name VARCHAR(30) NOT NULL,
university_ID INT NULL, -- <<== this will allow field to accept NULL
CONSTRAINT user_fk FOREIGN KEY (university_ID)
REFERENCES university(university_ID)
)
UPDATE 1
based on your comment, you should be inserting NULL and not ''.
insert into user (name,university_id) values ('harjeet', NULL)
UPDATE 2
$university_id = !empty($university_id) ? "'$university_id'" : "NULL";
insert into user (name,university_id) values ('harjeet', $university_id);
As a sidenote, the query is vulnerable with SQL Injection if the value(s) of the variables came from the outside. Please take a look at the article below to learn how to prevent from it. By using PreparedStatements you can get rid of using single quotes around values.
How to prevent SQL injection in PHP?
Here suppose i have foreign key user_id and i want to insert null value for that.
Checkbox must be checked for insert null value for foreign key.
I was using MySQL InnoDB and even allowing NULL in the FK column and using NULL as default I was getting an error.
So I used the SET syntax:
INSERT INTO (table) SET value1=X...
And I just don't set the FK column.
Related
I have a database with multiple tables, and I want to add a column to one table that will be populated with different strings based on the contents of another table.
Below are the tables of interest.
CREATE TABLE Locations(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Location VARCHAR(17) NOT NULL,
Is_Property BOOLEAN NOT NULL
);
CREATE TABLE Players(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Player_Name VARCHAR(17) NOT NULL,
Token VARCHAR(17) NOT NULL,
FOREIGN KEY (Token) REFERENCES Tokens(Token),
P_Location VARCHAR(17) NOT NULL,
FOREIGN KEY (P_Location) REFERENCES Locations(Location),
Bank_Balance INT NOT NULL DEFAULT 200);
ALTER TABLE Locations ADD INDEX `Location` (`Location`);
CREATE TABLE Properties AS SELECT id,Location FROM Locations
WHERE Is_Property = 1;
ALTER TABLE Properties
ADD CONSTRAINT PK_Properties PRIMARY KEY (id),
ADD COLUMN Colour VARCHAR(6),
ADD COLUMN Cost_And_Rent INT,
ADD COLUMN Owned VARCHAR(3);
CREATE TABLE Properties_Owned(
Player_id INT NOT NULL,
Prop_id INT NOT NULL,
PRIMARY KEY(Player_id, Prop_id),
FOREIGN KEY (Player_id) REFERENCES Players(id),
FOREIGN KEY (Prop_id) REFERENCES Properties(id));
The Properties and Properties_Owned tables are of interest in this case. I want to create a column called Owned in Properties and populate it with "Yes" or "No" based on if the primary key appears under Prop_id in Properties_Owned. Ergo if it does, Properties.Owned will show "Yes", and if not, "No".
I've tried using the CASE function, but I'm unsure of if it can be used without calling a SELECT query. Below is my last attempt to do so, but the syntax is wrong somewhere or just misguided altogether.
CASE
WHEN id IS IN properties_owned.Prop_id THEN Properties.Owned = "Yes"
ELSE "No" ;
It generates the error code:
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE WHEN id IS IN properties_owned.Prop_id THEN Properties.Owned = "Yes" ELSE ' at line 1
Edit: As there was a request for sample data, here it is:
INSERT INTO Locations(Location,Is_Property) VALUES ("GO", 0),
("London", 1),
("Paris", 0),
("China", 1),
("New Zealand", 0),
("Sydney", 1),;
INSERT INTO Players(Player_Name,Token,P_Location,Bank_Balance) VALUES
("Mary","Battleship","London",190),
("Bill","Dog","Paris",500),
("Jane","Car","China",150),
("Norman","Thimble","London",250);
INSERT INTO Properties_Owned(Player_id,Prop_id) VALUES
(1,1),
(2,2),
(3,3),
(4,4),
(4,5);
Thus the Properties_Owned table will look like this:
Player_id | Prop_id
----------|---------
1 |1
2 |2
3 |3
4 |4
4 |5
And so in the Properties table under Owned, if Properties.id appears in Prop_id above, the Owned column should yield "Yes".
The table Properties_Owned reflects an (n:n)-relation (many-to-many). But according to your comment, a property cannot be owned by multiple players at the same time. And that would be an (n:1)-relation (many-to-one). In that case you do not need the Properties_Owned table and can just add a column Player_id (or owned_by_player_id) to the Properties table as foreign key referencing the Players table.
alter table Properties
add column Player_id int default null,
add foreign key (Player_id) references Players(id);
Then the information required for the Owned column will be already in the same table. You just need to "manipulate" it in your SELECT statements. For example with:
select
p.*,
case when Player_id is null then 'No' else 'Yes' end as Owned
from Properties p;
No need to store the same information redundantly. That would "bite" you sooner or later. Avoid redundancy when possible.
If your MySQL version (5.7+ required) supports Generated Columns you can also let the database maintain the redundancy.
alter table Properties
drop column Owned,
add column Owned varchar(3)
as (case when Player_id is null then 'No' else 'Yes' end) virtual;
Now the (genrated) column is dependent on Player_id column and you don't need (and cannot) store anything there but can select it. virtual means that it is not stored but generated (on the fly) when it's needed. Now you can read it in your queries as if it is normal column.
See example on db-fiddle.com
And again: Avoid redundant data when possible. At least use foreign keys to avoid data inconsistency.
You could create a view that extends your table by the column you want. There you can use a CASE statement.
CASE WHEN id IN SELECT Prop_id FROM properties_owned THEN 'Yes' ELSE 'No'
If this is not what you want, you could possibly use triggers on both tables that fill/update the column on on create/on delete
Initially you could fill the column with something like this:
UPDATE Prop_id SET properties_owned = CASE WHEN id IN SELECT Prop_id FROM properties_owned THEN 'Yes' ELSE 'No' WHERE
I have the following query:
"INSERT INTO `occ_apps` (`occ_date`, `service_tag`, `counter`) VALUES (?, ?, '1') ON DUPLICATE KEY UPDATE `counter` = (`counter`+1)"
Currently it's incrementing the counter when either occ_date or service_tag is matching in a row.
Where occ_date and service_tag are unique fields, and I can't set primary key to both unique fields.
I ran the following:
ALTER TABLE occ_apps
DROP PRIMARY KEY,
ADD PRIMARY KEY (occ_date, service_tag);
And I get, the error:
`#1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key`
I want it to update (increment) the counter only when occ_date and service_tag both matches (already exists) in a single row, otherwise it should insert a new row.
Software version: 5.5.53-MariaDB-1~wheezy - mariadb.org binary distribution
when I ran DESC occ_apps I get:
Field Type Null Key Default Extra
serial_no int(255) NO PRI NULL auto_increment
occ_date varchar(255) NO UNI NULL
counter int(255) NO NULL
service_tag varchar(255) YES UNI NULL
I don't think you even need a counter field in your table. It looks like your counter is merely holding how many times a given value occurs. And that's something that can be generated easily using a GROUP BY
SELECT occ_date, COUNT(*) FROM occ_apps GROUP BY `occ_date`;
So you want to filter the query so that you get only items with at least 5 counts?
SELECT occ_date, COUNT(*) FROM occ_apps WHERE service_tag = 'service-1'
GROUP BY `occ_date` HAVING COUNT(*) > 5
These sorts of problems have been solved millions of times using GROUP BY. This is just the tip of the ice berge as far as what SQL query aggregation can do. Please take a moment to read up on it.
I have a table 'user' already in db with fields
create Table user (
id INT(6) NOT NULL AUTO_INCREMENT PRIMARY KEY,
username varchar(20) NOT NULL,
password varchar(20) NOT NULL,
profilename varchar(20) NOT NULL,
email varchar(40) NOT NULL,
socialemail varchar(40) NOT NULL)engine=InnoDB;
The stated columns also contain values
I altered the table and added some more columns
ALTER TABLE user
ADD COLUMN enabled varchar(1),
ADD COLUMN accountnonexpired varchar(1),
ADD COLUMN credentialsnonexpired varchar(1),
ADD COLUMN accountnonlocked varchar(1);
Now when I am inserting values into new columns with the below command in MYSQL.
insert into user
(id,enabled,accountnonexpired,credentialsnonexpired,accountnonlocked) values ('1','Y','Y','Y','Y'),('2','Y','Y','Y','Y');
I am getting an error
Error Code: 1364. Field 'username' doesn't have a default value
Can anyone tell me why?
What should be the correct way to insert values in new columns?
INSERT adds new rows to your table, and those rows would have to have a non-null username for the INSERT to succeed It's not 100% clear but I think you are saying that you want to set the values of these new columns for all your existing rows. To do that you need UPDATE not INSERT:
UPDATE user SET id='1', enabled = 'Y', accountnonexpired = 'Y' WHERE 1
I omitted a few of your columns for brevity but you get the idea. You may also want to alter the table to make these values the DEFAULT for new rows inserted in the future.
Your table has NOT NULL set for the [username], [password], [profilename], [email] and [socialemail] fields. You will need to provide values while NOT NULL has been set and there is no default value.
Unless your intention is to insert data into pre-existing columns, then use the Update statement.
update user
set enabled = 'Y', accountnonexpired='Y', credentialsnonexpired='Y', accountnonlocked='Y'
from user
where id = 1
An INSERT is creating NEW records. You have a username field that is marked as NOT NULL But in your sql you are not including username and other NOT NULL fields in your statement.
Your insert would need to include all the NOT NULL fields.
insert into user(id,username,password,profilename,email,socialemail,enabled,accountnonexpired,credentialsnonexpired,accountnonlocked)
values ('1',<username>,<password>,<profilename>,<email>,<socialemail>'Y','Y','Y','Y'),('2',<username>,<password>,<profilename>,<email>,<socialemail>'Y','Y','Y','Y');
I suspect you actually want to UPDATE here instead of insert.
An update would look like this:
UPDATE user set enabled = 'Y', accountnonexpired='Y', credentialsnonexpired='Y', accountnonlocked='Y'
FROM user
WHERE id = 1
Give value for 'username' field. it has no default value and default is not null as per your table definition. This will work
In your insert procedure, there is no value assigned for username field, Since username varchar(20) is NOT NULLable, you need to set a default value for that col or alter the col property to accept null values.
Okay so this question has been asked to death on here but I still haven't found the actual MySql statement answer. Just a lot of reasons why it doesn't work. For someone that is new to SQL that doesn't really help me, I need an example. This is what I have:
**Table One**
key bigint(4) UNSIGNED auto_increment
username varchar(10) utf8_general_ci
score bigint(5) UNSIGNED
password varchar(60) utf8_general_ci NULL
PRIMARY PRIMARY 15 key
username UNIQUE 15 username
**Table Two**
key bigint(4) No auto_increment
username varchar(10) utf8_general_ci No
score_old bigint(11) No
score_high bigint(11) No .
PRIMARY PRIMARY 16 key
username UNIQUE 16 username
Both tables have data in them. I want to populate Table Two score_high with Table One score column.
When I try
INSERT INTO Table2( score_high )
SELECT score
FROM Table1
I get
> > MySQL said:
> #1062 - Duplicate entry '' for key 2
A clear, layman, explanation would be appreciated. Thank you.
UPDATE Smuckers_Users SET score_high = (SELECT score FROM Smuckers_Info WHERE Smuckers_Users.username = Smuckers_Info.username)
Let's start with
INSERT INTO Table2( score_high )
SELECT score
FROM Table1
You are inserting score from Table1 into Table2, populating only the score_high column
Question : What unique column is getting in the way ?
Look at the definition of table2. It has two UNIQUE KEYs
PRIMARY KEY
username
Since the PRIMARY KEY is an auto_increment column, that is ruled out.
How is UNIQUE KEY on username getting in the way ?
When you insert just a score (say 100,000) into the score_high column, what will the value of username? Most likely a blank field. One row can get in with NULL username. What happens when you attempt to insert another row when you place another score into table? Another row with a blank username. Two rows with blank usernames cannot coexist in table2.
Looking back at what MySQL said
1062 - Duplicate entry '' for key 2
Key 2 is the UNIQUE KEY on username
The entry is '' (an empty string)
Mystery solved ( Q.E.D. )
Question : How can you populate table2 ?
INSERT INTO Table2( username,score_high )
SELECT username,score
FROM Table1
This should work just fine because username is unique in table1. Rows from table1 should go into table2 without any incidents.
I'm trying to make the statement that inserts or updates the record depending on its presence in the table. If the record in the "drug_name_pl" field is present, it will increase its "vote_sum" value by 1.
The problem is that the statement creates evey time the a record while trying to update already existing field.
Here is the table structure:
Field Type Null Key Default Extra
id int(11) NO PRI NULL auto_increment
drug_name_pl varchar(11)NO MUL NULL
vote_sum int(11) NO NULL
And the query:
$query = "INSERT INTO lek_podstawowe(drug_name_pl) VALUES ('$drug_name_pl')
ON DUPLICATE KEY UPDATE vote_sum=vote_sum+1";
you need to add unique key on drug_name_pl
something like:
CREATE UNIQUE INDEX drug_name_pl_unique ON table_name (drug_name_pl)
do not forget to change table_name to the real name of your table. Please also make sure you escape $drug_name_pl properly to protect application form sql injection