Except where otherwise noted, the contents of this document are Copyright 2012 Marty Stepp, Jessica Miller, and Victoria Kirst. All rights reserved. Any redistribution, reproduction, transmission, or storage of part or all of the contents in any form is prohibited without the author's expressed written permission.
Most web sites do four general tasks ("CRUD") with data in a database:
SELECT
)In lecture we explored only the "R", but now let's examine the others...
SHOW DATABASES; USE database; SHOW TABLES; DESCRIBE table;
mysql> USE simpsons; mysql> SHOW TABLES; +-----------+ | students | | courses | | grades | | teachers | +-----------+ 4 rows in set
INSERT
statementINSERT INTO table VALUES (value, value, ..., value);
INSERT INTO students VALUES (789, "Nelson", "muntz@fox.com", "haha!");
INSERT
INSERT INTO table (columnName, columnName, ..., columnName) VALUES (value, value, ..., value);
INSERT INTO students (name, email) VALUES ("Lewis", "lewis@fox.com");
REPLACE
statementREPLACE INTO table (columnName, columnName, ..., columnName) VALUES (value, value, ..., value);
REPLACE INTO students VALUES (789, "Martin", "prince@fox.com");
UPDATE
statementUPDATE table SET column = value, ..., column = value WHERE column = value;
UPDATE students SET email = "lisasimpson@gmail.com" WHERE id = 888;
DELETE
statementDELETE FROM table WHERE condition;
DELETE FROM students WHERE id = 888;
CREATE DATABASE name; DROP DATABASE name;
CREATE DATABASE warcraft;
CREATE TABLE name ( columnName type constraints, ... columnName type constraints );
DROP TABLE name;
CREATE TABLE students ( id INTEGER, name VARCHAR(20), email VARCHAR(32), password VARCHAR(16) );
BOOLEAN | either TRUE or FALSE |
INTEGER | 32-bit integer |
DOUBLE | real number |
VARCHAR(length) | a string, up to the given length |
ENUM(value, ..., value) | a fixed set of values |
DATE , TIME , DATETIME | timestamps (common value: NOW() ) |
BLOB | binary data |
CREATE TABLE students ( id INTEGER UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20) NOT NULL, email VARCHAR(32), password VARCHAR(16) NOT NULL DEFAULT "12345" );
NOT NULL
: not allowed to insert a null/empty value in any row for that columnPRIMARY KEY
/ UNIQUE
: no two rows can have the same valueDEFAULT value
: if no value is provided, use the given defaultAUTO_INCREMENT
: default value is the last row's value plus 1 (useful for IDs)UNSIGNED
: don't allow negative numbers (INTEGER
only)ALTER TABLE name RENAME TO newName;
ALTER TABLE students RENAME TO children;
ALTER TABLE name ADD COLUMN columnName type constraints; ALTER TABLE name DROP COLUMN columnName; ALTER TABLE name CHANGE COLUMN oldColumnName newColumnName type constraints;
GRANT permission ON database.table TO 'username'@'server';
GRANT SELECT ON simpsons.grades TO 'homer'@'localhost'; GRANT * ON simpsons.* TO 'daisy'@'localhost';
While programming for the web there is one thing you should constantly keep in mind:
As far as we've, this is how you do a database query. Is this good or bad?
# get email submitted $email = $_POST["email"]; # connect to my database $db = new PDO("mysql:dbname=turnin;host=localhost", "turninsystem", "th3yw1llN3ver9ue5s!"); # Get previous submissions for students $db->query("SELECT * FROM submissions WHERE email = '{$email}';"); ... display submissions ...
'; DROP TABLE submissions;'
as their username, we would loose all submissions!
quote
that will make sure all special characters
are escaped in a string so its safe to use in a query
quote
on a single variable, your query is still vulnerable!
PDO objects can actually take care of most injection cases for us if we are careful
name | description |
---|---|
prepare
|
prepares a statement for execution and returns a statement object |
prepare
is treated as executable.
Using this new method we can fix our previous query
# get email submitted $email = $_POST["email"]; # connect to my database $db = new PDO("mysql:dbname=turnin;host=localhost", "turninsystem", "th3yw1llN3ver9ue5s!"); # prepare query, stop bad people $query = $db->prepare('SELECT * FROM submissions WHERE email = :email;'); # Get previous submissions for students $query->execute(); foreach($query as $row) { ... }
But this will give an error, any guesses why?
If you don't specify all the labels, it will crash!
name | description |
---|---|
bindValue
|
Binds a value to a parameter in the SQL query |
bindParam
|
Binds a variable to a parameter in the SQL query |
execute
|
Execute a prepared statement |
bindValue
and bindParam to specify data for the labels
bindValue
will take whatever value it is given and add it to the query right away
bindParam
will keep track of the variable you pass in and only take the
value when you call execute
PDO::PARAM_STR
- Use for all non-numeric columns (VARCHAR, TEXT, etc)
PDO::PARAM_INT
- Use for all numeric columns (INT, DOUBLE, BOOLEAN, etc)
Now we can have a fully working query!
# get email submitted $email = $_POST["email"]; # connect to my database $db = new PDO("mysql:dbname=turnin;host=localhost", "turninsystem", "th3yw1llN3ver9ue5s!"); # prepare query, stop bad people $query = $db->prepare('SELECT * FROM submissions WHERE email = :email;'); $query->bindValue(':email', $email, PDO::PARAM_STR); # Get previous submissions for students $query->execute(); foreach($query as $row) { ... }
name | course | teacher | grade | |
---|---|---|---|---|
Bart | bart@fox.com | Computer Science 142 | Krabappel | B- |
Bart | bart@fox.com | Computer Science 143 | Hoover | C |
Milhouse | milhouse@fox.com | Computer Science 142 | Krabappel | B+ |
Lisa | lisa@fox.com | Computer Science 143 | Hoover | A+ |
Lisa | lisa@fox.com | Computer Science 190M | Stepp | A+ |
Ralph | ralph@fox.com | Informatics 100 | Krabappel | D+ |
|
|
|
|
grades
with student_id
of 888 are Lisa's grades)Suppose we want to write a web store like Amazon.com. The store sells products that can be purchased by customers online. The customer can add items to their shopping cart and then order them. The customer can also check the order's status, whether it has shipped, etc.