programmera.net -> mysql -> normal för utskrift | info@programmera.net |
NULL i MySQL
1. NULL 2. NULL i uttryck 3. NULL i aggregeringsfunktioner 4. NULL och DEFAULT 5. Att tilldela NULL explicit |
1. NULL
På denna sida beskrivs hur värdet NULL fungerar i olika situationer. NULL är ett speciellt värde som inte har någon typ, alla datatyper kan innehålla NULL (om de inte är satta till NOT NULL).
Det är lätt att man blandar ihop värdet 0 eller tomma strängen med NULL, men NULL skiljer sig från 0 och tomma strängen på flera sätt. 0 och tomma strängen räknas som värden emedan NULL representerar frånvaro av ett värde. NULL ska tolkas som att databasen avsiktligt eller oavsiktligt saknar ett värde för kolumnen, därför ska de flesta vanliga operationer man vill göra på NULL misslyckas, eftersom man omöjligen kan vilja utföra en operation på ett värde som inte existerar.
2. NULL i uttryck
I många fall returnerar ett uttryck NULL
Nu några exempel:
mysql> SELECT NULL+2, NULL/4, 1/0;
+--------+--------+------+
| NULL+2 | NULL/4 | 1/0 |
+--------+--------+------+
| NULL | NULL | NULL |
+--------+--------+------+
1 row in set (0.01 sec)
SELECT NULL=2, NULL=NULL, 3<NULL;
+--------+-----------+--------+
| NULL=2 | NULL=NULL | 3<NULL |
+--------+-----------+--------+
| NULL | NULL | NULL |
+--------+-----------+--------+
1 row in set (0.01 sec)
SELECT NULL<=>NULL, NULL<=>1, 1<=>1;
+-------------+----------+-------+
| NULL<=>NULL | NULL<=>1 | 1<=>1 |
+-------------+----------+-------+
| 1 | 0 | 1 |
+-------------+----------+-------+
1 row in set (0.00 sec)
3. NULL i aggregeringsfunktioner
Aggregering (som beskrivs
här ) utförs med aggregeringsfunktioner som t.ex. COUNT(), SUM(), AVG(). NULL fungerar bra tillsammans med aggregeringsfunktioner eftersom aggregeringsfunktioner hoppar över NULL i sina beräkningar. Alternativet att använda ett defaultvärde är inte så lockande, låt oss se på ett exempel:
Om kolumnen "salary" däremot deklarerad som NOT NULL kommer Olles lön troligtvis att få värdet 0 (som är det automatiska defaultvärdet för typen INT). I exemplet ovan kommer medelvärdet för utvecklingsavdelningen att bli felaktigt, eftersom Olles lön kommer med i beräkningen och förskjuter medelvärdet nedåt.
mysql> UPDATE employee SET salary=NULL where name="Olle";
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM employee;
+----+-------------+--------+---------------+--------+
| id | department | name | title | salary |
+----+-------------+--------+---------------+--------+
| 1 | Management | Magnus | President | 100000 |
| 2 | Management | Lisa | Secretary | 30000 |
| 3 | Sales | Jan | Sales Manager | 82000 |
| 4 | Sales | Thomas | Sales | 73000 |
| 5 | Sales | Marcus | Accountant | 58000 |
| 6 | Development | Jurgen | CTO | 65000 |
| 7 | Development | Tobbe | Programmer | 54000 |
| 8 | Development | Olle | Programmer | NULL |
| 9 | Development | Sven | Programmer | 43000 |
| 10 | Development | Jocke | Programmer | 47000 |
+----+-------------+--------+---------------+--------+
10 rows in set (0.00 sec)
mysql> SELECT department, COUNT(salary), AVG(salary) FROM employee GROUP BY department;
+-------------+---------------+-------------+
| department | COUNT(salary) | AVG(salary) |
+-------------+---------------+-------------+
| Development | 4 | 52250.0000 |
| Management | 2 | 65000.0000 |
| Sales | 3 | 71000.0000 |
+-------------+---------------+-------------+
3 rows in set (0.03 sec)
4. NULL och DEFAULT
Om man inte skriver ett explicit värde för en kolumn i en INSERT-sats lagras ett defaultvärde. De olika datatyperna följer följande regler när det gäller defaultvärden:
Vi testar defaultvärden för olika fall:
Ovan ser vi att:
mysql> CREATE TABLE default_table(
int_col1 INT DEFAULT 17,
int_col2 INT,
int_col3 INT NOT NULL,
text_col1 VARCHAR(100) DEFAULT 'foo',
text_col2 VARCHAR(100),
text_col3 VARCHAR(100) NOT NULL,
date_col1 DATE DEFAULT "2004-01-01",
date_col2 DATE,
date_col3 DATE NOT NULL
);
Query OK, 0 rows affected (0.05 sec)
INSERT INTO default_table VALUES ();
Query OK, 1 row affected (0.02 sec)
SELECT * FROM default_table\G
*************************** 1. row ***************************
int_col1: 17
int_col2: NULL
int_col3: 0
text_col1: foo
text_col2: NULL
text_col3:
date_col1: 2004-01-01
date_col2: NULL
date_col3: 0000-00-00
1 row in set (0.00 sec)
5. Att tilldela NULL explicit
Om man explicit försöker lagra NULL i en textkolumn har vi följande fall:
Vi testar att göra INSERT med NULL:
Här ser vi att det är först vid "int_col3" då MySQL protesterar. Nu ska vi se om det går att göra UPDATE med NULL på den kolumnen:
mysql> CREATE TABLE number_table(
-> int_col1 INT,
-> int_col2 INT DEFAULT 17,
-> int_col3 INT NOT NULL
);
INSERT INTO number_table (int_col1, int_col2, int_col3) VALUES(NULL, NULL, NULL);
ERROR 1048: Column 'int_col3' cannot be null
Här kommer vi undan med en varning.
mysql> UPDATE number_table SET int_col3=NULL;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 1
SELECT int_col3 FROM number_table;
+----------+
| int_col3 |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)