- 浏览: 179694 次
- 来自: ...
文章分类
最新评论
-
fsword:
同事拿着试了一下,说是把第五步放到第二步之前就可以了
在windows下安装ruby1.9.2,rails3.0.3和DevKit--转 -
dothwinds:
[flash=200,200][/flash][url][/u ...
打包ruby or rails成exe(英文)
This document describes the support for SQL foreign key constraints introduced in SQLite version 3.6.19. The first section introduces the concept of an SQL foreign key by example and defines the terminology used for the remainder of the document. Section 2 describes the steps an application must take in order to enable foreign key constraints in SQLite (it is disabled by default). The next section, section 3, describes the indexes that the user must create in order to use foreign key constraints, and those that should be created in order for foreign key constraints to function efficiently. Section 4 describes the advanced foreign key related features supported by SQLite and section 5 describes the way the ALTER andDROP TABLE commands are enhanced to support foreign key constraints. Finally, section 6 enumerates the missing features and limits of the current implementation. This document does not contain a full description of the syntax used to create foreign key constraints in SQLite. This may be found as part of the documentation for the CREATE TABLE statement. SQL foreign key constraints are used to enforce "exists" relationships between tables. For example, consider a database schema created using the following SQL commands: The applications using this database are entitled to assume that for each row in the track table there exists a corresponding row in the artist table. After all, the comment in the declaration says so. Unfortunately, if a user edits the database using an external tool or if there is a bug in an application, rows might be inserted into the track table that do not correspond to any row in the artisttable. Or rows might be deleted from the artist table, leaving orphaned rows in the track table that do not correspond to any of the remaining rows in artist. This might cause the application or applications to malfunction later on, or at least make coding the application more difficult. One solution is to add an SQL foreign key constraint to the database schema to enforce the relationship between the artist and track table. To do so, a foreign key definition may be added by modifying the declaration of the track table to the following: This way, the constraint is enforced by SQLite. Attempting to insert a row into the track table that does not correspond to any row in the artist table will fail, as will attempting to delete a row from the artist table when there exist dependent rows in the track table There is one exception: if the foreign key column in the track table is NULL, then no corresponding entry in the artist table is required. Expressed in SQL, this means that for every row in the track table, the following expression evaluates to true: Tip: If the application requires a stricter relationship between artist and track, where NULL values are not permitted in the trackartist column, simply add the appropriate "NOT NULL" constraint to the schema. There are several other ways to add an equivalent foreign key declaration to aCREATE TABLE statement. Refer to the CREATE TABLE documentation for details. The following SQLite command-line session illustrates the effect of the foreign key constraint added to the track table: As you would expect, it is not possible to manipulate the database to a state that violates the foreign key constraint by deleting or updating rows in the artisttable either: SQLite uses the following terminology: The parent table is the table that a foreign key constraint refers to. The parent table in the example in this section is the artist table. Some books and articles refer to this as the referenced table, which is arguably more correct, but tends to lead to confusion. The child table is the table that a foreign key constraint is applied to and the table that contains the REFERENCES clause. The example in this section uses the track table as the child table. Other books and articles refer to this as the referencing table. The parent key is the column or set of columns in the parent table that the foreign key constraint refers to. This is normally, but not always, the primary key of the parent table. The parent key must be a named column or columns in the parent table, not the rowid. The child key is the column or set of columns in the child table that are constrained by the foreign key constraint and which hold the REFERENCES clause. The foreign key constraint is satisfied if for each row in the child table either one or more of the child key columns are NULL, or there exists a row in the parent table for which each parent key column contains a value equal to the value in its associated child key column. In the above paragraph, the term "equal" means equal when values are compared using the rules specified here. The following clarifications apply: When comparing text values, the collating sequence associated with the parent key column is always used. When comparing values, if the parent key column has an affinity, then that affinity is applied to the child key value before the comparison is performed. In order to use foreign key constraints in SQLite, the library must be compiled with neither SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined. If SQLITE_OMIT_TRIGGER is defined but SQLITE_OMIT_FOREIGN_KEY is not, then SQLite behaves as it did prior to version 3.6.19 - foreign key definitions are parsed and may be queried using PRAGMA foreign_key_list, but foreign key constraints are not enforced. The PRAGMA foreign_keys command is a no-op in this configuration. If OMIT_FOREIGN_KEY is defined, then foreign key definitions cannot even be parsed (attempting to specify a foreign key definition is a syntax error). Assuming the library is compiled with foreign key constraints enabled, it must still be enabled by the application at runtime, using the PRAGMA foreign_keyscommand. For example: Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database connection separately. (Note, however, that future releases of SQLite might change so that foreign key constraints enabled by default. Careful developers will not make any assumptions about whether or not foreign keys are enabled by default but will instead enable or disable them as necessary.) The application can can also use a PRAGMA foreign_keys statement to determine if foreign keys are currently enabled. The following command-line session demonstrates this: Tip: If the command "PRAGMA foreign_keys" returns no data instead of a single row containing "0" or "1", then the version of SQLite you are using does not support foreign keys (either because it is older than 3.6.19 or because it was compiled with SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined). It is not possible to enable or disable foreign key constraints in the middle of amulti-statement transaction (when SQLite is not in autocommit mode). Attempting to do so does not return an error; it simply has no effect. Usually, the parent key of a foreign key constraint is the primary key of the parent table. If they are not the primary key, then the parent key columns must be collectively subject to a UNIQUE constraint or have a UNIQUE index. If the parent key columns have a UNIQUE index, then that index must use the collation sequences that are specified in the CREATE TABLE statement for the parent table. For example, The foreign key constraints created as part of tables child1, child2 and child3are all fine. The foreign key declared as part of table child4 is an error because even though the parent key column is indexed, the index is not UNIQUE. The foreign key for table child5 is an error because even though the parent key column has a unique index, the index uses a different collating sequence. Tables child6 and child7 are incorrect because while both have UNIQUE indices on their parent keys, the keys are not an exact match to the columns of a single UNIQUE index. If the database schema contains foreign key errors that require looking at more than one table definition to identify, then those errors are not detected when the tables are created. Instead, such errors prevent the application from preparing SQL statements that modify the content of the child or parent tables in ways that use the foreign keys. Errors reported when content is changed are "DML errors" and errors reported when the schema is changed are "DDL errors". So, in other words, misconfigured foreign key constraints that require looking at both the child and parent are DML errors. The English language error message for foreign key DML errors is usually "foreign key mismatch" but can also be "no such table" if the parent table does not exist. Foreign key DML errors are may be reported if: The last bullet above is illustrated by the following: By contrast, if foreign key errors can be recognized simply by looking at the definition of the child table and without having to consult the parent table definition, then the CREATE TABLE statement for the child table fails. Because the error occurs during a schema change, this is a DDL error. Foreign key DDL errors are reported regardless of whether or not foreign key constraints are enabled when the table is created. Indices are not required for child key columns but they are almost always beneficial. Returning to the example in section 1, each time an application deletes a row from the artist table (the parent table), it performs the equivalent of the following SELECT statement to search for referencing rows in the tracktable (the child table). where ? in the above is replaced with the value of the artistid column of the record being deleted from the artist table (recall that the trackartist column is the child key and the artistid column is the parent key). Or, more generally: If this SELECT returns any rows at all, then SQLite concludes that deleting the row from the parent table would violate the foreign key constraint and returns an error. Similar queries may be run if the content of the parent key is modified or a new row is inserted into the parent table. If these queries cannot use an index, they are forced to do a linear scan of the entire child table. In a non-trivial database, this may be prohibitively expensive. So, in most real systems, an index should be created on the child key columns of each foreign key constraint. The child key index does not have to be (and usually will not be) a UNIQUE index. Returning again to the example in section 1, the complete database schema for efficient implementation of the foreign key constraint might be: The block above uses a shorthand form to create the foreign key constraint. Attaching a "REFERENCES <parent-table>" clause to a column definition creates a foreign key constraint that maps the column to the primary key of <parent-table>. Refer to the CREATE TABLE documentation for further details. A composite foreign key constraint is one where the child and parent keys are both composite keys. For example, consider the following database schema: In this system, each entry in the song table is required to map to an entry in the album table with the same combination of artist and album. Parent and child keys must have the same cardinality. In SQLite, if any of the child key columns (in this case songartist and songalbum) are NULL, then there is no requirement for a corresponding row in the parent table. Each foreign key constraint in SQLite is classified as either immediate or deferred. Foreign key constraints are immediate by default. All the foreign key examples presented so far have been of immediate foreign key constraints. If a statement modifies the contents of the database so that an immediate foreign key constraint is in violation at the conclusion the statement, an exception is thrown and the effects of the statement are reverted. By contrast, if a statement modifies the contents of the database such that a deferred foreign key constraint is violated, the violation is not reported immediately. Deferred foreign key constraints are not checked until the transaction tries toCOMMIT. For as long as the user has an open transaction, the database is allowed to exist in a state that violates any number of deferred foreign key constraints. However, COMMIT will fail as long as foreign key constraints remain in violation. If the current statement is not inside an explicit transaction (aBEGIN/COMMIT/ROLLBACK block), then an implicit transaction is committed as soon as the statement has finished executing. In this case deferred constraints behave the same as immediate constraints. To mark a foreign key constraint as deferred, its declaration must include the following clause: The full syntax for specifying foreign key constraints is available as part of theCREATE TABLE documentation. Replacing the phrase above with any of the following creates an immediate foreign key constraint. The following example illustrates the effect of using a deferred foreign key constraint. A nested savepoint transaction may be RELEASEd while the database is in a state that does not satisfy a deferred foreign key constraint. A transaction savepoint (a non-nested savepoint that was opened while there was not currently an open transaction), on the other hand, is subject to the same restrictions as a COMMIT - attempting to RELEASE it while the database is in such a state will fail. If a COMMIT statement (or the RELEASE of a transaction SAVEPOINT) fails because the database is currently in a state that violates a deferred foreign key constraint and there are currently nested savepoints, the nested savepoints remain open. Foreign key ON DELETE and ON UPDATE clauses are used to configure actions that take place when deleting rows from the parent table (ON DELETE), or modifying the parent key values of existing rows (ON UPDATE). A single foreign key constraint may have different actions configured for ON DELETE and ON UPDATE. Foreign key actions are similar to triggers in many ways. The ON DELETE and ON UPDATE action associated with each foreign key in an SQLite database is one of "NO ACTION", "RESTRICT", "SET NULL", "SET DEFAULT" or "CASCADE". If an action is not explicitly specified, it defaults to "NO ACTION". NO ACTION: Configuring "NO ACTION" means just that: when a parent key is modified or deleted from the database, no special action is taken. RESTRICT: The "RESTRICT" action means that the application is prohibited from deleting (for ON DELETE RESTRICT) or modifying (for ON UPDATE RESTRICT) a parent key when there exists one or more child keys mapped to it. The difference between the effect of a RESTRICT action and normal foreign key constraint enforcement is that the RESTRICT action processing happens as soon as the field is updated - not at the end of the current statement as it would with an immediate constraint, or at the end of the current transaction as it would with a deferred constraint. Even if the foreign key constraint it is attached to is deferred, configuring a RESTRICT action causes SQLite to return an error immediately if a parent key with dependent child keys is deleted or modified. SET NULL: If the configured action is "SET NULL", then when a parent key is deleted (for ON DELETE SET NULL) or modified (for ON UPDATE SET NULL), the child key columns of all rows in the child table that mapped to the parent key are set to contain SQL NULL values. SET DEFAULT: The "SET DEFAULT" actions are similar to "SET NULL", except that each of the child key columns is set to contain the columns default value instead of NULL. Refer to the CREATE TABLE documentation for details on how default values are assigned to table columns. CASCADE: A "CASCADE" action propagates the delete or update operation on the parent key to each dependent child key. For an "ON DELETE CASCADE" action, this means that each row in the child table that was associated with the deleted parent row is also deleted. For an "ON UPDATE CASCADE" action, it means that the values stored in each dependent child key are modified to match the new parent key values. For example, adding an "ON UPDATE CASCADE" clause to the foreign key as shown below enhances the example schema from section 1 to allow the user to update the artistid (the parent key of the foreign key constraint) column without breaking referential integrity: Configuring an ON UPDATE or ON DELETE action does not mean that the foreign key constraint does not need to be satisfied. For example, if an "ON DELETE SET DEFAULT" action is configured, but there is no row in the parent table that corresponds to the default values of the child key columns, deleting a parent key while dependent child keys exist still causes a foreign key violation. For example: Those familiar with SQLite triggers will have noticed that the "ON DELETE SET DEFAULT" action demonstrated in the example above is similar in effect to the following AFTER DELETE trigger: Whenever a row in the parent table of a foreign key constraint is deleted, or when the values stored in the parent key column or columns are modified, the logical sequence of events is: There is one important difference between ON UPDATE foreign key actions and SQL triggers. An ON UPDATE action is only taken if the values of the parent key are modified so that the new parent key values are not equal to the old. For example: This section describes the way the CREATE TABLE, ALTER TABLE, and DROP TABLE commands interact with SQLite's foreign keys. A CREATE TABLE command operates the same whether or not foreign key constraints are enabled. The parent key definitions of foreign key constraints are not checked when a table is created. There is nothing stopping the user from creating a foreign key definition that refers to a parent table that does not exist, or to parent key columns that do not exist or are not collectively bound by a PRIMARY KEY or UNIQUE constraint. The ALTER TABLE command works differently in two respects when foreign key constraints are enabled: It is not possible to use the "ALTER TABLE ... ADD COLUMN" syntax to add a column that includes a REFERENCES clause, unless the default value of the new column is NULL. Attempting to do so returns an error. If an "ALTER TABLE ... RENAME TO" command is used to rename a table that is the parent table of one or more foreign key constraints, the definitions of the foreign key constraints are modified to refer to the parent table by its new name. The text of the child CREATE TABLE statement or statements stored in the sqlite_master table are modified to reflect the new parent table name. If foreign key constraints are enabled when it is prepared, the DROP TABLEcommand performs an implicit DELETE to remove all rows from the table before dropping it. The implicit DELETE does not cause any SQL triggers to fire, but may invoke foreign key actions or constraint violations. If an immediate foreign key constraint is violated, the DROP TABLE statement fails and the table is not dropped. If a deferred foreign key constraint is violated, then an error is reported when the user attempts to commit the transaction if the foreign key constraint violations still exist at that point. Any "foreign key mismatch" errors encountered as part of an implicit DELETE are ignored. The intent of these enhancements to the ALTER TABLE and DROP TABLEcommands is to ensure that they cannot be used to create a database that contains foreign key violations, at least while foreign key constraints are enabled. There is one exception to this rule though. If a parent key is not subject to a PRIMARY KEY or UNIQUE constraint created as part of the parent table definition, but is subject to a UNIQUE constraint by virtue of an index created using the CREATE INDEX command, then the child table may be populated without causing a "foreign key mismatch" error. If the UNIQUE index is dropped from the database schema, then the parent table itself is dropped, no error will be reported. However the database may be left in a state where the child table of the foreign key constraint contains rows that do not refer to any parent table row. This case can be avoided if all parent keys in the database schema are constrained by PRIMARY KEY or UNIQUE constraints added as part of the parent table definition, not by external UNIQUE indexes. The properties of the DROP TABLE and ALTER TABLE commands described above only apply if foreign keys are enabled. If the user considers them undesirable, then the workaround is to use PRAGMA foreign_keys to disable foreign key constraints before executing the DROP or ALTER TABLE command. Of course, while foreign key constraints are disabled, there is nothing to stop the user from violating foreign key constraints and thus creating an internally inconsistent database. This section lists a few limitations and omitted features that are not mentioned elsewhere. No support for the MATCH clause. According to SQL92, a MATCH clause may be attached to a composite foreign key definition to modify the way NULL values that occur in child keys are handled. If "MATCH SIMPLE" is specified, then a child key is not required to correspond to any row of the parent table if one or more of the child key values are NULL. If "MATCH FULL" is specified, then if any of the child key values is NULL, no corresponding row in the parent table is required, but all child key values must be NULL. Finally, if the foreign key constraint is declared as "MATCH PARTIAL" and one of the child key values is NULL, there must exist at least one row in the parent table for which the non-NULL child key values match the parent key values. SQLite parses MATCH clauses (i.e. does not report a syntax error if you specify one), but does not enforce them. All foreign key constraints in SQLite are handled as if MATCH SIMPLE were specified. No support for switching constraints between deferred and immediate mode. Many systems allow the user to toggle individual foreign key constraints between deferred and immediate mode at runtime (for example using the Oracle "SET CONSTRAINT" command). SQLite does not support this. In SQLite, a foreign key constraint is permanently marked as deferred or immediate when it is created. Recursion limit on foreign key actions. The SQLITE_MAX_TRIGGER_DEPTHand SQLITE_LIMIT_TRIGGER_DEPTH settings determine the maximum allowable depth of trigger program recursion. For the purposes of these limits, foreign key actions are considered trigger programs. The PRAGMA recursive_triggers setting does not not affect the operation of foreign key actions. It is not possible to disable recursive foreign key actions.Overview
1. Introduction to Foreign Key Constraints
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER -- Must map to an artist.artistid!
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER,
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
);
trackartist IS NULL OR EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)
sqlite> SELECT * FROM artist;
artistid artistname
-------- -----------------
1 Dean Martin
2 Frank Sinatra
sqlite> SELECT * FROM track;
trackid trackname trackartist
------- ----------------- -----------
11 That's Amore 1
12 Christmas Blues 1
13 My Way 2
sqlite> -- This fails because the value inserted into the trackartist column (3)
sqlite> -- does not correspond to row in the artist table.
sqlite> INSERT INTO track VALUES(14, 'Mr. Bojangles', 3);
SQL error: foreign key constraint failed
sqlite> -- This succeeds because a NULL is inserted into trackartist. A
sqlite> -- corresponding row in the artist table is not required in this case.
sqlite> INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL);
sqlite> -- Trying to modify the trackartist field of the record after it has
sqlite> -- been inserted does not work either, since the new value of trackartist (3)
sqlite> -- Still does not correspond to any row in the artist table.
sqlite> UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
SQL error: foreign key constraint failed
sqlite> -- Insert the required row into the artist table. It is then possible to
sqlite> -- update the inserted row to set trackartist to 3 (since a corresponding
sqlite> -- row in the artist table now exists).
sqlite> INSERT INTO artist VALUES(3, 'Sammy Davis Jr.');
sqlite> UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
sqlite> -- Now that "Sammy Davis Jr." (artistid = 3) has been added to the database,
sqlite> -- it is possible to INSERT new tracks using this artist without violating
sqlite> -- the foreign key constraint:
sqlite> INSERT INTO track VALUES(15, 'Boogie Woogie', 3);
sqlite> -- Attempting to delete the artist record for "Frank Sinatra" fails, since
sqlite> -- the track table contains a row that refer to it.
sqlite> DELETE FROM artist WHERE artistname = 'Frank Sinatra';
SQL error: foreign key constraint failed
sqlite> -- Delete all the records from the track table that refer to the artist
sqlite> -- "Frank Sinatra". Only then is it possible to delete the artist.
sqlite> DELETE FROM track WHERE trackname = 'My Way';
sqlite> DELETE FROM artist WHERE artistname = 'Frank Sinatra';
sqlite> -- Try to update the artistid of a row in the artist table while there
sqlite> -- exists records in the track table that refer to it.
sqlite> UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
SQL error: foreign key constraint failed
sqlite> -- Once all the records that refer to a row in the artist table have
sqlite> -- been deleted, it is possible to modify the artistid of the row.
sqlite> DELETE FROM track WHERE trackname IN('That''s Amore', 'Christmas Blues');
sqlite> UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
2. Enabling Foreign Key Support
sqlite> PRAGMA foreign_keys = ON;
sqlite> PRAGMA foreign_keys;
0
sqlite> PRAGMA foreign_keys = ON;
sqlite> PRAGMA foreign_keys;
1
sqlite> PRAGMA foreign_keys = OFF;
sqlite> PRAGMA foreign_keys;
0
3. Required and Suggested Database Indexes
CREATE TABLE parent(a PRIMARY KEY, b UNIQUE, c, d, e, f);
CREATE UNIQUE INDEX i1 ON parent(c, d);
CREATE INDEX i2 ON parent(e);
CREATE UNIQUE INDEX i3 ON parent(f COLLATE nocase);
CREATE TABLE child1(f, g REFERENCES parent(a)); -- Ok
CREATE TABLE child2(h, i REFERENCES parent(b)); -- Ok
CREATE TABLE child3(j, k, FOREIGN KEY(j, k) REFERENCES parent(c, d)); -- Ok
CREATE TABLE child4(l, m REFERENCES parent(e)); -- Error!
CREATE TABLE child5(n, o REFERENCES parent(f)); -- Error!
CREATE TABLE child6(p, q, FOREIGN KEY(p, q) REFERENCES parent(b, c)); -- Error!
CREATE TABLE child7(r REFERENCES parent(c)); -- Error!
CREATE TABLE parent2(a, b, PRIMARY KEY(a,b));
CREATE TABLE child8(x, y, FOREIGN KEY(x,y) REFERENCES parent2); -- Ok
CREATE TABLE child9(x REFERENCES parent2); -- Error!
CREATE TABLE child10(x,y,z, FOREIGN KEY(x,y,z) REFERENCES parent2); -- Error!
SELECT rowid FROM track WHERE trackartist = ?
SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER REFERENCES artist
);
CREATE INDEX trackindex ON track(trackartist);
4. Advanced Foreign Key Constraint Features
4.1. Composite Foreign Key Constraints
CREATE TABLE album(
albumartist TEXT,
albumname TEXT,
albumcover BINARY,
PRIMARY KEY(albumartist, albumname)
);
CREATE TABLE song(
songid INTEGER,
songartist TEXT,
songalbum TEXT,
songname TEXT,
FOREIGN KEY(songartist, songalbum) REFERENCES album(albumartist, albumname)
);
4.2. Deferred Foreign Key Constraints
DEFERRABLE INITIALLY DEFERRED -- A deferred foreign key constraint
NOT DEFERRABLE INITIALLY DEFERRED -- An immediate foreign key constraint
NOT DEFERRABLE INITIALLY IMMEDIATE -- An immediate foreign key constraint
NOT DEFERRABLE -- An immediate foreign key constraint
DEFERRABLE INITIALLY IMMEDIATE -- An immediate foreign key constraint
DEFERRABLE -- An immediate foreign key constraint
-- Database schema. Both tables are initially empty.
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER REFERENCES artist(artistid) DEFERRABLE INITIALLY DEFERRED
);
sqlite3> -- If the foreign key constraint were immediate, this INSERT would
sqlite3> -- cause an error (since as there is no row in table artist with
sqlite3> -- artistid=5). But as the constraint is deferred and there is an
sqlite3> -- open transaction, no error occurs.
sqlite3> BEGIN;
sqlite3> INSERT INTO track VALUES(1, 'White Christmas', 5);
sqlite3> -- The following COMMIT fails, as the database is in a state that
sqlite3> -- does not satisfy the deferred foreign key constraint. The
sqlite3> -- transaction remains open.
sqlite3> COMMIT;
SQL error: foreign key constraint failed
sqlite3> -- After inserting a row into the artist table with artistid=5, the
sqlite3> -- deferred foreign key constraint is satisfied. It is then possible
sqlite3> -- to commit the transaction without error.
sqlite3> INSERT INTO artist VALUES(5, 'Bing Crosby');
sqlite3> COMMIT;
4.3. ON DELETE and ON UPDATE Actions
-- Database schema
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER REFERENCES artist(artistid) ON UPDATE CASCADE
);
sqlite> SELECT * FROM artist;
artistid artistname
-------- -----------------
1 Dean Martin
2 Frank Sinatra
sqlite> SELECT * FROM track;
trackid trackname trackartist
------- ----------------- -----------
11 That's Amore 1
12 Christmas Blues 1
13 My Way 2
sqlite> -- Update the artistid column of the artist record for "Dean Martin".
sqlite> -- Normally, this would raise a constraint, as it would orphan the two
sqlite> -- dependent records in the track table. However, the ON UPDATE CASCADE clause
sqlite> -- attached to the foreign key definition causes the update to "cascade"
sqlite> -- to the child table, preventing the foreign key constraint violation.
sqlite> UPDATE artist SET artistid = 100 WHERE artistname = 'Dean Martin';
sqlite> SELECT * FROM artist;
artistid artistname
-------- -----------------
2 Frank Sinatra
100 Dean Martin
sqlite> SELECT * FROM track;
trackid trackname trackartist
------- ----------------- -----------
11 That's Amore 100
12 Christmas Blues 100
13 My Way 2
-- Database schema
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER DEFAULT 0 REFERENCES artist(artistid) ON DELETE SET DEFAULT
);
sqlite> SELECT * FROM artist;
artistid artistname
-------- -----------------
3 Sammy Davis Jr.
sqlite> SELECT * FROM track;
trackid trackname trackartist
------- ----------------- -----------
14 Mr. Bojangles 3
sqlite> -- Deleting the row from the parent table causes the child key
sqlite> -- value of the dependent row to be set to integer value 0. However, this
sqlite> -- value does not correspond to any row in the parent table. Therefore
sqlite> -- the foreign key constraint is violated and an is exception thrown.
sqlite> DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.';
SQL error: foreign key constraint failed
sqlite> -- This time, the value 0 does correspond to a parent table row. And
sqlite> -- so the DELETE statement does not violate the foreign key constraint
sqlite> -- and no exception is thrown.
sqlite> INSERT INTO artist VALUES(0, 'Unknown Artist');
sqlite> DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.';
sqlite> SELECT * FROM artist;
artistid artistname
-------- -----------------
0 Unknown Artist
sqlite> SELECT * FROM track;
trackid trackname trackartist
------- ----------------- -----------
14 Mr. Bojangles 0
CREATE TRIGGER on_delete_set_default AFTER DELETE ON artist BEGIN
UPDATE child SET trackartist = 0 WHERE trackartist = old.artistid;
END;
-- Database schema
CREATE TABLE parent(x PRIMARY KEY);
CREATE TABLE child(y REFERENCES parent ON UPDATE SET NULL);
sqlite> SELECT * FROM parent;
x
----
key
sqlite> SELECT * FROM child;
y
----
key
sqlite> -- Since the following UPDATE statement does not actually modify
sqlite> -- the parent key value, the ON UPDATE action is not performed and
sqlite> -- the child key value is not set to NULL.
sqlite> UPDATE parent SET x = 'key';
sqlite> SELECT IFNULL(y, 'null') FROM child;
y
----
key
sqlite> -- This time, since the UPDATE statement does modify the parent key
sqlite> -- value, the ON UPDATE action is performed and the child key is set
sqlite> -- to NULL.
sqlite> UPDATE parent SET x = 'key2';
sqlite> SELECT IFNULL(y, 'null') FROM child;
y
----
null
5. CREATE, ALTER and DROP TABLE commands
6. Limits and Unsupported Features
发表评论
-
DBDesigner使用笔记 --转,改
2011-08-18 10:26 1426DBDesigner使用笔记 表格之间的关系 ... -
DBDesigner4连接mysql出错的处理
2011-08-18 10:12 1360DBDesigner自mysql4.0之后没有更新对新版mys ... -
数据库设计经验谈-- 转
2011-08-01 17:42 783一个成功的管理系统,是由:[50% 的业务 + 50% ... -
两个数据库设计实例--转
2011-08-01 16:58 4352(注:摘自 http://blog. ... -
数据库设计三大范式应用实例剖析--转
2011-08-01 13:04 878引言 数据库的设计范式是数据库设计所需要满足的规范,满 ... -
sqlite3 --sql命令简单介绍(zt)--转
2011-04-23 22:46 1720sqlite3 --sql命 ... -
SQLite3 C/C++ 开发接口简介(API函数)1(zt)--转
2011-04-23 22:44 1163SQLite3 C/C++ 开发接 ... -
SQLite3 C/C++ 开发接口简介(API函数) 二(zt)--转
2011-04-23 22:43 1457SQLite3 C/C++ 开发接口简介(API函数 ... -
SQLite适用的范围(zt)-转
2011-04-23 22:40 834SQLite适用的范围(zt) (2007-12- ... -
SQLite的体系结构简介(zt)--转
2011-04-23 22:39 1109SQLite的体系结构简 ... -
SQLite 第三版总览(简介)--转
2011-04-23 22:38 1317SQLite 第三版总览 SQLite 第三版主要 ... -
董淳光SQLITE3 使用总结(1)--转
2011-04-23 22:36 1032董淳光SQLITE3 使用总结(1) 转载 ... -
董淳光SQLITE3 使用总结(2)--转
2011-04-23 22:34 1342董淳光SQLITE3 使用 ... -
董淳光SQLITE3 使用总结(3)-转
2011-04-23 22:30 1031董淳光SQLITE3 使用总结(3) 转载 ... -
董淳光SQLITE3 使用总结(4)--转
2011-04-23 22:26 1221董淳光SQLITE3 使用总结(4) 转载 ... -
董淳光SQLITE3 使用总结(5)--转
2011-04-23 22:17 1444董淳光SQLITE3 使用总结(5) 转载 ... -
SQLite中如何用触发器执行取消和重做逻辑--转
2011-04-23 22:14 2041SQLite中如何用触发器执行取消和重做逻辑 转载 ... -
Oracle 常用函数
2008-12-04 12:08 783SQL中的单记录函数 1.ASCII 返回与指定的字符对应 ...
相关推荐
Maven坐标:org.xerial:sqlite-jdbc:3.34.0; 标签:xerial、sqlite、jdbc、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的...
sqlite-netFx40-setup-bundle-x86-2010-1.0.113.0.exe
标题中的"sqlite-netFx451-static-binary-bundle-x64-2013-1.0.112.0.zip"表明这是一个针对.NET Framework 4.5.1、64位(x64)平台的SQLite静态二进制捆绑包,版本号为1.0.112.0。SQLite是一款开源的关系型数据库管理...
标题中的"sqlite-netFx40-binary-Win32_2010-1.0.94.0.zip"指的是SQLite数据库的一个特定版本,适用于.NET Framework 4.0环境,面向Windows 32位操作系统,版本号为1.0.94.0。这个压缩包是为了解决在开发或运行过程...
sqlite-jdbc-3.36.0.3.jar 最新吧2021 8月底更新
sqlite-devel-3.7.17-8.el7.x86_64.rpm
sqlite-netFx40-setup-bundle-x64-2010-1.0.113.0
DB.Browser.for.SQLite-3.12.2-win64 这是一款由多位开发者共同开发的工具,最初由 Mauricio Piacentini 设计并发布到公共领域。该工具主要用于浏览和编辑 SQLite 数据库,它兼容标准的 SQLite 2.x 和 3.x 数据库...
DB.Browser.for.SQLite-3.12.1-win64-v2.msi
标题"sqlite-netFx46-setup-bundle SQlLite驱动下载"指的是SQLite针对.NET Framework 4.6的安装包。这个安装包包含了SQLite驱动程序,使得.NET开发者可以在他们的应用程序中无缝地集成SQLite数据库。这适用于那些...
该工具支持Windows、Linux以及macOS等操作系统,其中"DB.Browser.for.SQLite-3.10.1-win64.exe"是适用于64位Windows环境的版本。 SQLite3是一种轻量级的嵌入式关系型数据库管理系统,广泛应用于移动应用、服务器...
SQLite数据库是文档型数据库,其具备体积小移动方便等特点;以下jar包:sqlite-jdbc-3.30.1.jar文件为SQLite数据库对应的数据库驱动jar包;
标题中的"sqlite-netFx40-static-binary-x64-2010-1.0.112.0.zip"揭示了这个压缩包是SQLite针对.NET Framework 4.0平台的静态编译版本,适用于64位操作系统。这里的“static”意味着它包含了所有必要的依赖,使得...
标题 "sqlite-netFx40-binary-x64-2010-1.0.106.0" 指的是一个针对 .NET Framework 4.0 平台的 SQLite 驱动程序的特定版本,适用于64位(x64)系统。这个版本号1.0.106.0表明这是一个更新稳定版。SQLite 是一个轻量...
python3.8在import sqlite3时报错误:ImportError: No module named '_sqlite3'。
解决运行diango时报错No module named '_sqlite3’,需要把此文件放到服务器安装的python目录下的lib-dynload中
标题中的"sqlite-netFx46-binary-x64-2015-1.0.113.0.zip"表明这是一个针对.NET Framework 4.6平台的SQLite数据库引擎的64位版本,版本号为1.0.113.0。SQLite是一个开源的、自包含的、无服务器的、零配置的、事务性...
SQLiteStudio是一款功能强大的SQLite数据库管理工具,专为Windows操作系统设计。SQLite本身是一个开源、轻量级的嵌入式SQL数据库引擎,广泛应用于各种桌面应用程序、移动设备和服务器环境,尤其适合那些对数据库性能...
下载文件包括:sqlite-netFx45-binary-Win32-2012-1.0.98.0.zip和sqlite-netFx45-binary-x64-2012-1.0.98.0.zip两个文件(均系官网下载)。 含net环境下使用SQLite所需dll,System.Data.SQLite.dll、SQLite.Interop....
python3.8在import sqlite3时报错误:ImportError: No module named '_sqlite3'。 将该文件解压后,放到python3.8目录下的lib-dynload目录下。 比如我的服务器路径:/usr/local/bin/python3/lib/python3.8/lib-...