Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 71 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
71
Dung lượng
620,43 KB
Nội dung
Chapter 7. Enforcing Data Integrity 269 1 1 2000-11-12 23:55:00 2 1 2000-11-12 23:55:00 6 3 2000-11-12 23:55:00 7 3 2000-11-12 23:55:00 Cascading Updates To define a FOREIGN KEY constraint as a cascaded UPDATE action, you must use the ON UPDATE CASCADE in the REFERENCES clause of the FOREIGN KEY definition on the CREATE TABLE or ALTER TABLE statements. Listing 7.18 is based in the same example as in Listing 7.17. You create the Customers table and the Orders table. You define a FOREIGN KEY constraint between these two tables with the ON UPDATE CASCADE option. You want to change the ID of customer 3 to 30. Customer 3 has two related rows in the Orders table. The UPDATE operation changes the CustomerID from 3 to 30 in both tables automatically. Caution It is not recommended to change PRIMARY KEY values. This can produce identity integrity problems in your applications. Listing 7.18 Cascade Changes on Primary Keys to Related Foreign Keys with FOREIGN KEY Constraints Defined As ON UPDATE CASCADE Create Customers and Orders tables CREATE TABLE Customers( CustomerID int PRIMARY KEY, CustomerName varchar(20) NOT NULL) CREATE TABLE Orders( OrderID int IDENTITY(1,1) PRIMARY KEY, CustomerID int NOT NULL, OrderDate smalldatetime NOT NULL DEFAULT CURRENT_TIMESTAMP) GO Create the FOREIGN KEY constraint with CASCADE ALTER TABLE Orders ADD CONSTRAINT FK_Orders FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID) ON DELETE CASCADE This is optional ON UPDATE CASCADE Microsoft SQL Server 2000 Programming by Example 270 GO Insert some Customers INSERT Customers VALUES (1, 'MyComp corp.') INSERT Customers VALUES (2, 'ACME Inc.') INSERT Customers VALUES (3, 'NewDotCompany Ltd.') Insert some Orders with the default Date INSERT Orders (CustomerID) VALUES (1) INSERT Orders (CustomerID) VALUES (1) INSERT Orders (CustomerID) VALUES (2) INSERT Orders (CustomerID) VALUES (2) INSERT Orders (CustomerID) VALUES (2) INSERT Orders (CustomerID) VALUES (3) INSERT Orders (CustomerID) VALUES (3) Show the data PRINT CHAR(10) + 'Original Customers table'+ CHAR(10) SELECT * FROM Customers PRINT CHAR(10) + 'Original Orders table'+ CHAR(10) SELECT * FROM Orders GO Update Customer 3 Change CustomerID from 3 for 30 UPDATE Customers SET CustomerID = 30 WHERE CustomerID = 3 PRINT CHAR(10) + 'Customers table after update Customer 3'+ CHAR(10) SELECT * FROM Customers Chapter 7. Enforcing Data Integrity 271 PRINT CHAR(10) + 'Orders table after update Customer 3'+ CHAR(10) SELECT * FROM Orders GO DROP TABLE Orders DROP TABLE Customers Original Customers table CustomerID CustomerName 1 MyComp corp. 2 ACME Inc. 3 NewDotCompany Ltd. Original Orders table OrderID CustomerID OrderDate 1 1 2000-11-12 23:59:00 2 1 2000-11-12 23:59:00 3 2 2000-11-12 23:59:00 4 2 2000-11-12 23:59:00 5 2 2000-11-12 23:59:00 6 3 2000-11-12 23:59:00 7 3 2000-11-12 23:59:00 Customers table after update Customer 3 CustomerID CustomerName 1 MyComp corp. 2 ACME Inc. 30 NewDotCompany Ltd. Orders table after update Customer 3 OrderID CustomerID OrderDate 1 1 2000-11-12 23:59:00 2 1 2000-11-12 23:59:00 3 2 2000-11-12 23:59:00 4 2 2000-11-12 23:59:00 5 2 2000-11-12 23:59:00 6 30 2000-11-12 23:59:00 7 30 2000-11-12 23:59:00 Microsoft SQL Server 2000 Programming by Example 272 Transact-SQL–Specific Integrity Structures Transact-SQL language provides an alternative to the CHECK and DEFAULT constraints with the RULE and DEFAULT objects. RULE and DEFAULT objects are not ANSI standard, so it is advisable to use constraints as a general way to provide the same functionality. One of the reasons to use these Transact-SQL objects is to create self- contained user-defined data types, including not only the data type, but also the DEFAULT value and the RULE to check for domain integrity. If a column uses one of these self-contained user-defined data types as a data type, this column will inherit the DEFAULT definition and the RULE definition as well. User-defined data types were covered in Chapter 2. Using DEFAULT and RULE objects can help during the development process, if the same condition must be applied to multiple columns. However, remember that they are not ANSI compliant. DEFAULT Objects DEFAULT objects are similar to the DEFAULT definition of a column, but you can create a DEFAULT object independently of any column and bind it to specific columns or user-defined data types later. To create a DEFAULT object, you use the CREATE DEFAULT statement, providing a unique name for the DEFAULT object and defining the object as a constant, built-in function or any valid scalar expression. To delete a DEFAULT object, you must use the DROP DEFAULT statement. You cannot drop a DEFAULT object if it is used anywhere in your database. Caution The only way to modify a DEFAULT or RULE object definition is by dropping and re- creating the object. Before dropping the object, you must unbind the object from any field and user-defined data type. To bind a DEFAULT object to a field or user-defined data type, you must use the sp_bindefault system stored procedure, and the sp_unbindefault disconnects a bound DEFAULT object from a field or user- defined data type. Only one DEFAULT definition or DEFAULT object can be defined per column; binding a new DEFAULT object to a column overrides the existing one. Note DEFAULT and RULE objects are local to a database. Therefore, DEFAULT and RULE objects created in the Master database can be used only in the Master database. You can see a complete example of how to use DEFAULT objects in Listing 7.19. Listing 7.19 Create Independent DEFAULT Objects and Bind Them Later to Any Field or User-Defined Data Type Chapter 7. Enforcing Data Integrity 273 Create a DEFAULT object using a constant CREATE DEFAULT NoSales AS 0 GO Create DEFAULT objects using expressions based on built-in functions CREATE DEFAULT ThisMonth AS Month(CURRENT_TIMESTAMP) GO CREATE DEFAULT UserDB AS SYSTEM_USER + '- '+ DB_NAME(DB_ID()) GO Create two User-Defined Data Types EXEC sp_addtype 'UDDTLoginDB', 'nvarchar(256)', 'NULL' EXEC sp_addtype 'UDDTSales', 'money', 'NULL' GO Create a table to test the DEFAULT objects and the User-Defined Data Types CREATE TABLE TestDefaults( ID int NOT NULL IDENTITY(1,1) PRIMARY KEY, TotalSales money NULL, SalesMonth tinyint NULL, WhoWhere UDDTLoginDB) GO Insert a new empty row in the table INSERT TestDefaults DEFAULT VALUES PRINT char(10) + 'No defaults defined'+ CHAR(10) SELECT * FROM TestDefaults GO Bind the NoSales DEFAULT object to the TotalSales field in the TestDefaults table EXEC sp_bindefault 'NoSales', 'TestDefaults.TotalSales' GO Microsoft SQL Server 2000 Programming by Example 274 Insert a new empty row in the table INSERT TestDefaults DEFAULT VALUES PRINT CHAR(10) + 'Only DEFAULT on TotalSales defined'+ CHAR(10) SELECT * FROM TestDefaults GO Bind the ThisMonth DEFAULT object to the SalesMonth field in the TestDefaults table EXEC sp_bindefault 'ThisMonth', 'TestDefaults.SalesMonth' GO Insert a new empty row in the table INSERT TestDefaults DEFAULT VALUES PRINT CHAR(10) + 'DEFAULT defined on TotalSales and SalesMonth'+ CHAR(10) SELECT * FROM TestDefaults GO Bind the UserDB DEFAULT object to the UDDTLginDB User-Defined Data Type EXEC sp_bindefault 'UserDB', 'UDDTLoginDB' GO Insert a new empty row in the table INSERT TestDefaults DEFAULT VALUES PRINT CHAR(10) + 'DEFAULT defined on TotalSales, SalesMonth' PRINT 'and the UDDTLoginDB User-Defined Data Type'+ CHAR(10) SELECT * FROM TestDefaults GO Add a new column to the TestDefaults table Using the UDDTSales data type ALTER TABLE TestDefaults ADD ProjectedSales UDDTSales GO PRINT CHAR(10) + 'Add an empty field using the UDDTSales data type'+ CHAR(10) SELECT * FROM TestDefaults GO Bind the NoSales DEFAULT object to the UDDTSales User-Defined Data Type Chapter 7. Enforcing Data Integrity 275 for future columns only EXEC sp_bindefault 'NoSales', 'UDDTSales', 'futureonly' GO Insert a new empty row in the table INSERT TestDefaults DEFAULT VALUES PRINT CHAR(10) + 'DEFAULT defined on UDDTSales data type as futureonly' PRINT 'does not affect the existing fields using this UDDT'+ CHAR(10) SELECT * FROM TestDefaults GO Drop everything in order Table first UDDT next DEFAULT last DROP TABLE TestDefaults EXEC sp_droptype 'UDDTSales' EXEC sp_droptype 'UDDTLoginDB' DROP DEFAULT NoSales DROP DEFAULT ThisMonth DROP DEFAULT UserDB Type added. Type added. No defaults defined ID TotalSales SalesMonth WhoWhere 1 NULL NULL NULL Default bound to column. Only DEFAULT on TotalSales defined ID TotalSales SalesMonth WhoWhere 1 NULL NULL NULL 2 .0000 NULL NULL Microsoft SQL Server 2000 Programming by Example 276 Default bound to column. DEFAULT defined on TotalSales and SalesMonth ID TotalSales SalesMonth WhoWhere 1 NULL NULL NULL 2 .0000 NULL NULL 3 .0000 11 NULL Default bound to data type. The new default has been bound to columns(s) of the specified user data type. DEFAULT defined on TotalSales, SalesMonth and the UDDTLoginDB User-Defined Data Type ID TotalSales SalesMonth WhoWhere 1 NULL NULL NULL 2 .0000 NULL NULL 3 .0000 11 NULL 4 .0000 11 sa - ByExample Add an empty field using the UDDTSales data type ID TotalSales SalesMonth WhoWhere ProjectedSales 1 NULL NULL NULL NULL 2 .0000 NULL NULL NULL 3 .0000 11 NULL NULL 4 .0000 11 sa - ByExample NULL Default bound to data type. DEFAULT defined on UDDTSales data type as future only does not affect the existing fields using this UDDT ID TotalSales SalesMonth WhoWhere ProjectedSales 1 NULL NULL NULL NULL 2 .0000 NULL NULL NULL 3 .0000 11 NULL NULL 4 .0000 11 sa - ByExample NULL 5 .0000 11 sa - ByExample NULL Type has been dropped. Type has been dropped. Rule Objects RULE objects are similar to CHECK constraints. However, you can create a RULE object independently of any column and bind it later to specific columns or user-defined data types. To create a RULE object, you use the CREATE RULE statement, providing a unique name for the RULE object and defining the object as any expression that returns TRUE or FALSE. Caution You can't use user-defined functions as part of a DEFAULT or RULE object definition. Chapter 7. Enforcing Data Integrity 277 To delete a RULE object, you must use the DROP RULE statement. You cannot drop a RULE object if it is used anywhere in your database. To bind a RULE object to a field or user-defined data type, you must use the sp_bindrule system stored procedure, and the sp_unbindrule disconnects a bound RULE object from a field or user-defined data type. You can bind only one rule to a user-defined data type or a table field. However, a rule can coexist with one or more CHECK constraints in a field; in this case, all the conditions will be checked. If you bind a new rule to a field or user-defined data type, the old rule will be unbound automatically. You can see an example of how to use RULE objects in Listing 7.20. Listing 7.20 Create Independent RULE Objects and Bind Them Later to Any Field or User-Defined Data Type Define a Table to test RULE Creation CREATE TABLE NewEmployees ( EmployeeID int NOT NULL, EmployeeName varchar(50) NOT NULL, PostCode char(5) NOT NULL ) GO Create the RULE object CREATE RULE RUPostCode AS (@PCode LIKE '[0-9][0-9][0-9][0-9][0-9]') GO Bind the RULE to the PostCode column EXEC sp_bindrule 'RUPostCode', 'NewEmployees.PostCode' GO Insert data in the table to test the RULE INSERT NewEmployees VALUES (1, 'Paul', 'GL513') INSERT NewEmployees VALUES (2, 'Eladio', '01380') SELECT * Microsoft SQL Server 2000 Programming by Example 278 FROM NewEmployees GO DROP TABLE NewEmployees GO DROP RULE RUPostCode GO Rule bound to table column. Server: Msg 513, Level 16, State 1, Line 1 A column insert or update conflicts with a rule imposed by a previous CREATE RULE statement. The statement was terminated. The conflict occurred in database 'ByExample', table 'NewEmployees', column 'PostCode'. The statement has been terminated. EmployeeID EmployeeName PostCode 2 Eladio 01380 Note The definition of the RULE object contains a variable. The name of this variable is not relevant; it just represents the column to where the RULE object will be bound. Note Remember to keep it simple. Overengineering a database will produce execution overhead and a difficult maintenance. What's Next? This chapter covered the creation and use of structures to enforce data integrity. Chapter 8 covers the creation of stored procedures, where you can test the integrity of the data before attempting any modification, having extra data control and access to more complex condition checking. Chapter 9 covers triggers, which is another way to enforce data integrity. In that chapter, you will see how to create triggers to enforce domain integrity and referential integrity. User-defined functions are covered in Chapter 10. It is possible to use UDF as part of constraint definitions. This new feature gives you tremendous flexibility in the definition of DEFAULT and CHECK constraints. [...]... which will create the Sqlstatus table and the insertsqlstatus stored procedure, and then set this stored procedure to run automatically whenever SQL Server is started Close any applications that might be using SQL Server (Query Analyzer, Enterprise Manager, and so on) Stop and restart SQL Server Connect to SQL Server using Query Analyzer, and issue a SELECT query against the Sqlstatus table To verify... that SQL Server allocates for its use (the other part of the memory, the data cache, is used to store the data pages that SQL Server manipulates) Figure 8.1 shows this three-step process (parse, name resolution, and optimization) Figure 8.1 Creation and execution of stored procedures in SQL Server The execution plan of a stored procedure will remain in memory until SQL Server is stopped or when SQL Server. .. CREATE TABLE dbo.Sqlstatus ( lasttime DATETIME ) GO CREATE PROC dbo.insertsqlstatus AS INSERT Sqlstatus (lasttime) VALUES (CURRENT_TIMESTAMP) GO 286 EXEC sp_procoption 'insertsqlstatus','startup','true' To test this example, follow the next steps: 1 2 3 4 5 Using Query Analyzer, connect to SQL Server as sa, or if using integrated authentication, with a member of the System Administrators server role Run... owner dbid created compatibility_level - - - master 12.19 MB sa 1 Aug 6 2000 80 model 1.13 MB sa 3 Aug 6 2000 80 msdb 13 .50 MB sa 4 Aug 6 2000 80 Northwind 3.94 MB sa 6 Aug 6 2000 80 pubs 2.13 MB sa 5 Aug 6 2000 80 tempdb 8 .50 MB sa 2 Jan 22 2001 80 Transact -SQL provides a system function, OBJECTPROPERTY,that is usedto check for a variety of object properties Specifically,... from the user database This is because when SQL Server executes any stored procedure that contains the sp_ prefix, SQL Server looks for it first in the current database, and then in master if it doesn't find it in the current database Be aware that Books Online incorrectly states that SQL Server looks for it first in master and then in the current database For example, you can create a user-defined stored... finished Tip 283 A temporary stored procedure, once created (and stored in tempdb automatically by SQL Server) , can be called from any database Extended Stored Procedures Extended stored procedures are DLL programs written in C++ that extend the capabilities of SQL Server They are located in the master database SQL Server has its own set of extended stored procedures whose name begins with xp_, which are... Created_datetime - - - getcurrenttime dbo stored procedure 2000- 09-18 01: 35: 06. 257 Text -CREATE PROC getcurrenttime AS SELECT CURRENT_TIMESTAMP There are three steps that SQL Server performs with stored procedures: parsing, name resolution, and optimization SQL Server parses a stored procedure when it is created to check for correct syntax Then, the stored... system table (all SQL Server error messages are stored in Sysmessages) You can add your own messages to this system table through the sp_addmessage system stored procedure, and to delete messages, through sp_dropmessage Notice that when creating a user-defined message with 302 sp_addmessage, you must specify a message ID greater than 50 ,001 (message IDs less than 50 ,000 are reserved by SQL Server) This... from recompiling the stored procedure while it is executed In SQL Server 6 .5 and earlier, the only way to create an access plan was by using stored procedures In version 7.0 and later, the query processor can store execution plans in the procedure cache for all TransactSQL statements (including ad hoc queries) When reexecuting a Transact -SQL statement, if the query processor detects that it can reuse... execute automatically when the SQL Server service is started Because they won't have any interaction with any application, they can't have any input parameters The stored procedure must be created by the system administrator in the master database, and then the system stored procedure sp_procoption must be used to set it to execute when the SQL Server service is started For example, suppose that you want . 1 2000- 11-12 23 :59 :00 2 1 2000- 11-12 23 :59 :00 3 2 2000- 11-12 23 :59 :00 4 2 2000- 11-12 23 :59 :00 5 2 2000- 11-12 23 :59 :00 6 30 2000- 11-12 23 :59 :00 7 30 2000- 11-12 23 :59 :00 Microsoft SQL Server. OrderDate 1 1 2000- 11-12 23 :59 :00 2 1 2000- 11-12 23 :59 :00 3 2 2000- 11-12 23 :59 :00 4 2 2000- 11-12 23 :59 :00 5 2 2000- 11-12 23 :59 :00 6 3 2000- 11-12 23 :59 :00 7 3 2000- 11-12 23 :59 :00 Customers. Chapter 7. Enforcing Data Integrity 269 1 1 2000- 11-12 23 :55 :00 2 1 2000- 11-12 23 :55 :00 6 3 2000- 11-12 23 :55 :00 7 3 2000- 11-12 23 :55 :00 Cascading Updates To define a FOREIGN KEY constraint