SQL PRIMARY KEY Constraint
SQL PRIMARY KEY Constraint
Primary keys must contain UNIQUE values, and cannot contain NULL values.
A table can have only one primary key, which may consist of single or multiple
fields.
MySQL:
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
PRIMARY KEY (ID)
);
CREATE TABLE Persons (
ID int NOT NULL PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
CONSTRAINT PK_Person PRIMARY KEY (ID,LastName)
);
Note: In the example above there is only ONE PRIMARY KEY (PK_Person).
However, the VALUE of the primary key is made up of TWO COLUMNS (ID +
LastName).
To create a PRIMARY KEY constraint on the "ID" column when the table is
already created, use the following SQL:
ALTER TABLE Persons
ADD PRIMARY KEY (ID);
ALTER TABLE Persons
ADD CONSTRAINT PK_Person PRIMARY KEY (ID,LastName);
Note: If you use the ALTER TABLE statement to add a primary key, the
primary key column(s) must already have been declared to not contain NULL
values (when the table was first created).
MySQL:
ALTER TABLE Persons
DROP PRIMARY KEY;
SQL Server / Oracle / MS Access:
ALTER TABLE Persons
DROP CONSTRAINT PK_Person;
A FOREIGN KEY is a field (or collection of fields) in one table that refers to
the PRIMARY KEY in another table.
Note: The table containing the foreign key is called the child table, and the
table containing the candidate key is called the referenced or parent table.
"Persons" table:
1 Hansen Ola 30
2 Svendson Tove 23
3 Pettersen Kari 20
"Orders" table:
1 77895 3
2 44678 3
3 22456 2
4 24562 1
Notice that the "PersonID" column in the "Orders" table points to the
"PersonID" column in the "Persons" table.
The "PersonID" column in the "Persons" table is the PRIMARY KEY in the
"Persons" table.
The FOREIGN KEY constraint is used to prevent actions that would destroy
links between tables.
The FOREIGN KEY constraint also prevents invalid data from being
inserted into the foreign key column, because it has to be one of the
values contained in the table it points to.
If you define a CHECK constraint on a table it can limit the values in certain
columns based on values in other columns in the row.
The following SQL creates a CHECK constraint on the "Age" column when
the "Persons" table is created. The CHECK constraint ensures that you can
not have any person below 18 years:
MySQL:
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
CHECK (Age>=18)
);
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int CHECK (Age>=18)
);
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
City varchar(255),
CONSTRAINT CHK_Person CHECK (Age>=18 AND City='Sandnes')
);
To create a CHECK constraint on the "Age" column when the table is already
created, use the following SQL:
ALTER TABLE Persons
ADD CHECK (Age>=18);
ALTER TABLE Persons
ADD CONSTRAINT CHK_PersonAge CHECK (Age>=18 AND City='Sandnes'
);
ALTER TABLE Persons
DROP CONSTRAINT CHK_PersonAge;
MySQL:
ALTER TABLE Persons
DROP CHECK CHK_PersonAge;
The default value will be added to all new records IF no other value is
specified.
The following SQL sets a DEFAULT value for the "City" column when the
"Persons" table is created:
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
City varchar(255) DEFAULT 'Sandnes'
);
The DEFAULT constraint can also be used to insert system values, by using
functions like GETDATE():
CREATE TABLE Orders (
ID int NOT NULL,
OrderNumber int NOT NULL,
OrderDate date DEFAULT GETDATE()
);
MySQL:
ALTER TABLE Persons
ALTER City SET DEFAULT 'Sandnes';
SQL Server:
ALTER TABLE Persons
ADD CONSTRAINT df_City
DEFAULT 'Sandnes' FOR City;
MS Access:
ALTER TABLE Persons
ALTER COLUMN City SET DEFAULT 'Sandnes';
Oracle:
ALTER TABLE Persons
MODIFY City DEFAULT 'Sandnes';
MySQL:
ALTER TABLE Persons
ALTER City DROP DEFAULT;
ALTER TABLE Persons
ALTER COLUMN City DROP DEFAULT;
Indexes are used to retrieve data from the database very fast. The users
cannot see the indexes, they are just used to speed up searches/queries.
Note: Updating a table with indexes takes more time than updating a table
without (because the indexes also need an update). So, only create indexes
on columns that will be frequently searched against.
CREATE INDEX index_name
ON table_name (column1, column2, ...);
CREATE INDEX idx_lastname
ON Persons (LastName);
If you want to create an index on a combination of columns, you can list the
column names within the parentheses, separated by commas:
CREATE INDEX idx_pname
ON Persons (LastName, FirstName);
MS Access:
DROP INDEX index_name ON table_name;
SQL Server:
DROP INDEX table_name.index_name;
MySQL:
ALTER TABLE table_name
DROP INDEX index_name;
SQL AUTO INCREMENT Field
Auto-increment allows a unique number to be generated automatically when a
new record is inserted into a table.
Often this is the primary key field that we would like to be created
automatically every time a new record is inserted.
CREATE TABLE Persons (
ID int NOT NULL AUTO_INCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
PRIMARY KEY (ID)
);
To let the AUTO_INCREMENT sequence start with another value, use the
following SQL statement:
ALTER TABLE Persons AUTO_INCREMENT=100;
To insert a new record into the "Persons" table, we will NOT have to specify a
value for the "ID" column (a unique value will be added automatically):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Lars','Monsen');
The SQL statement above would insert a new record into the "Persons" table.
The "ID" column would be assigned a unique value. The "FirstName" column
would be set to "Lars" and the "LastName" column would be set to "Monsen".
In the example above, the starting value for IDENTITY is 1, and it will
increment by 1 for each new record.
Tip: To specify that the "ID" column should start at value 10 and increment by
5, change it to IDENTITY(10,5).
To insert a new record into the "Persons" table, we will NOT have to specify a
value for the "ID" column (a unique value will be added automatically):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Lars','Monsen');
The SQL statement above would insert a new record into the "Persons" table.
The "ID" column would be assigned a unique value. The "FirstName" column
would be set to "Lars" and the "LastName" column would be set to "Monsen".
CREATE TABLE Persons (
ID Integer PRIMARY KEY AUTOINCREMENT,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
Tip: To specify that the "ID" column should start at value 10 and increment by
5, change the autoincrement to AUTOINCREMENT(10,5).
To insert a new record into the "Persons" table, we will NOT have to specify a
value for the "ID" column (a unique value will be added automatically):
INSERT INTO Persons (FirstName,LastName)
VALUES ('Lars','Monsen');
The SQL statement above would insert a new record into the "Persons" table.
The "P_Id" column would be assigned a unique value. The "FirstName"
column would be set to "Lars" and the "LastName" column would be set to
"Monsen".
You will have to create an auto-increment field with the sequence object (this
object generates a number sequence).
CREATE SEQUENCE seq_person
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10;
The code above creates a sequence object called seq_person, that starts with
1 and will increment by 1. It will also cache up to 10 values for performance.
The cache option specifies how many sequence values will be stored in
memory for faster access.
To insert a new record into the "Persons" table, we will have to use the
nextval function (this function retrieves the next value from seq_person
sequence):
INSERT INTO Persons (ID,FirstName,LastName)
VALUES (seq_person.nextval,'Lars','Monsen');
The SQL statement above would insert a new record into the "Persons" table.
The "ID" column would be assigned the next number from the seq_person
sequence. The "FirstName" column would be set to "Lars" and the
"LastName" column would be set to "Monsen".
SQL Dates
The most difficult part when working with dates is to be sure that the format of
the date you are trying to insert, matches the format of the date column in the
database.
As long as your data contains only the date portion, your queries will work as
expected. However, if a time portion is involved, it gets more complicated.
SQL Date Data Types
MySQL comes with the following data types for storing a date or a date/time
value in the database:
SQL Server comes with the following data types for storing a date or a
date/time value in the database:
Note: The date types are chosen for a column when you create a new table in
your database!
You can compare two dates easily if there is no time component involved!
1 Geitost 2008-11-11
1 Geitost 2008-11-11
Now, assume that the "Orders" table looks like this (notice the time
component in the "OrderDate" column):
SELECT * FROM Orders WHERE OrderDate='2008-11-11'
we will get no result! This is because the query is looking only for dates with
no time portion.
Tip: To keep your queries simple and easy to maintain, do not allow time
components in your dates!
SQL Views
SQL CREATE VIEW Statement
In SQL, a view is a virtual table based on the result-set of an SQL statement.
A view contains rows and columns, just like a real table. The fields in a view
are fields from one or more real tables in the database.
You can add SQL functions, WHERE, and JOIN statements to a view and
present the data as if the data were coming from one single table.
Note: A view always shows up-to-date data! The database engine recreates
the data, using the view's SQL statement, every time a user queries a view.
The following SQL creates a view that shows all customers from Brazil:
Example
CREATE VIEW [Brazil Customers] AS
SELECT CustomerName, ContactName
FROM Customers
WHERE Country = "Brazil";
Example
SELECT * FROM [Brazil Customers];
The following SQL creates a view that selects every product in the "Products"
table with a price higher than the average price:
Example
CREATE VIEW [Products Above Average Price] AS
SELECT ProductName, Price
FROM Products
WHERE Price > (SELECT AVG(Price) FROM Products);
Example
The following SQL adds the "City" column to the "Brazil Customers" view:
Example
CREATE OR REPLACE VIEW [Brazil Customers] AS
SELECT CustomerName, ContactName, City
FROM Customers
WHERE Country = "Brazil";
DROP VIEW [Brazil Customers];
SQL Injection
SQL injection is a code injection technique that might destroy your database.
SQL injection is the placement of malicious code in SQL statements, via web
page input.
SQL injection usually occurs when you ask a user for input, like their
username/userid, and instead of a name/id, the user gives you an SQL
statement that you will unknowingly run on your database.
Example
txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;
Look at the example above again. The original purpose of the code was to
create an SQL statement to select a user, with a given user id.
If there is nothing to prevent a user from entering "wrong" input, the user can
enter some "smart" input like this:
UserId:
SELECT * FROM Users WHERE UserId = 105 OR 1=1;
The SQL above is valid and will return ALL rows from the "Users" table,
since OR 1=1 is always TRUE.
Does the example above look dangerous? What if the "Users" table contains
names and passwords?
A hacker might get access to all the user names and passwords in a
database, by simply inserting 105 OR 1=1 into the input field.
Password: myPass
Example
uName = getRequestString("username");
uPass = getRequestString("userpassword");
sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="'
+ uPass + '"'
Result
The code at the server will create a valid SQL statement like this:
Result
The SQL above is valid and will return all rows from the "Users" table,
since OR ""="" is always TRUE.
The SQL statement below will return all rows from the "Users" table, then
delete the "Suppliers" table.
Example
SELECT * FROM Users; DROP TABLE Suppliers
Example:
txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;
And the following input:
Result
SELECT * FROM Users WHERE UserId = 105; DROP TABLE Suppliers;
SQL Hosting
If you want your web site to be able to store and retrieve data from a
database, your web server should have access to a database-system that
uses the SQL language.
If your web server is hosted by an Internet Service Provider (ISP), you will
have to look for SQL hosting plans.
The most common SQL hosting databases are MS SQL Server, Oracle,
MySQL, and MS Access.
MS SQL Server
SQL Server is a very powerful, robust and full featured SQL database system.
Oracle
Oracle is also a popular database software for database-driven web sites with
high traffic.
Oracle is a very powerful, robust and full featured SQL database system.
MySQL
MySQL is a very powerful, robust and full featured SQL database system.
Access
When a web site requires only a simple database, Microsoft Access can be a
solution.
Access is not well suited for very high-traffic, and not as powerful as MySQL,
SQL Server, or Oracle.