System and method for constraint checking bulk data in a database5706494Abstract In a relational database management system (RDMS), a method and system for constraint checking of bulk data after storage in a base table. This invention generates a "dummy" INSERT inquiry to cause the compiler constraint rule engine to generate code for checking for constraint violations. After construction of a Query Graph Model by the compiler, a logic module replaces the INSERT inquiry with a SELECT inquiry to create code that when executed will select records from the bulk data table. Constraint violations are handled in several ways by this invention, including merely reporting that a constraint error exists or listing those records that violate constraint conditions. The logic also enforces referential integrity constraints by applying the SQL CASCADE command to the violating records to expand the violation list to include children records that would be orphaned when their parent records are later removed. Claims What is claimed is: Description BACKGROUND OF THE INVENTION
TABLE S-1
______________________________________
Symbol Definition
______________________________________
R.sub.(T.sbsb.i .sub.,j)
Referential Constraint
.sup.z R.sub.(T.sbsb.i .sub.,j)
Number of Columns of Referential Constraint
T.sub.i Table
T.sub.i.R.sub.(T.sbsb.i .sub.,j) k!
Column in T.sub.i corresponding to k.sup.th Column of
Referential Constraint R(T.sbsb.i.sub.,j) (foreign key)
P.sub.(T.sbsb.i .sub.,j)
Parent Table in Referential Constraint
P.sub.(T.sbsb.i .sub.,j).R.sub.(T.sbsb.i .sub.,j) k!
Column in Parent Table corresponding to k.sup.th
column of unique key (i.e., corresponding to
Referential Constraint R.sub.(T.sbsb.i .sub.,j))
______________________________________
Formalisms A raise error function raises a given error and rolls back the statement whenever it is invoked. In addition to deleting (or inserting) the selected rows from (or into) the first table listed in the FROM (or INTO) clause, a DELETE (or INSERT) operator can also flow data into other operators just like a select. For example: select c.sub.1, 2 from (delete c.sub.1, 5 FROM T where c.sub.1 >5); selects a record with two columns for each record deleted from T. The first column is the value of the c.sub.1 column of the deleted record and the second column is always 5. This is used in generated queries to insert the values of the deleted records along with some computed information about which constraints are violated into exception tables. For example, the following query deletes all records from T and inserts columns c.sub.1, c.sub.2, and c.sub.3 of each deleted record into table E. insert into E (delete c.sub.1, c.sub.2, c.sub.3 FROM T) The existence of a COMPOUND SQL allows a grouping of a set of SQL statements together, and allows them to share common subexpressions. For example: begin insert into T.sub.1 select * from T.sub.1 ; create temporary table DT as (delete from T.sub.2) insert into E.sub.2 select * from DT; end This query first replicates the contents of T1, then deletes all records from T2 and inserts the deleted records into table E2. Implementation of the Method Referring to FIG. 4, the process is implicitly started by the bulk loading of one or more tables {T.sub.i } in mass store 82, as shown in step 130. Such a table T.sub.i will be placed in a pending state until constraints are checked. Table T.sub.i can be represented by either table 86 or 88 (FIG. 3). The SELECT CONSTRAINTS process is initiated by an invocation command, for example, "SELECT COMMAND ON", as shown in step 132. The invocation command may be performed as an SQL query or may be automatically passed to processor 70. The invocation command causes the SELECT CONSTRAINTS module to generate an INSERT query denoted as Q.sub.MAIN that is really a "dummy" insert of records that purportedly are to be inserted in the table T.sub.i as shown in step 134. A pseudocode representation of a general case preferred embodiment of such a dummy INSERT query is shown below in Table 1. Regarding the pseudocode represented in Tables 1-5, it will be apparent to one skilled in the art that the combination of the pseudocode shown in Tables 1-5 with the flow charts of FIGS. 4-9 enables the practicing of the method of this invention. To further explain the invention, a specific example employing the general case pseudocode of Tables 1-5 is discussed below in Tables 6-11.
TABLE 1
______________________________________
1. begin
2. insert into T.sub.1 select * from T.sub.1 ;
3. insert into T.sub.2 select * from T.sub.2 ;
4. . . .
5. insert into T.sub.n select * from T.sub.n ;
6. end
______________________________________
Referring again to FIG. 4, when the dummy INSERT inquiry is generated, then the processor calls the constraint compiler 24 (FIG. 3) to compile the INSERT commands and check for constraint violations according to the constraint role engine, as shown in step 136. The compiler 24 compiles Q.sub.MAIN and produces a query that has been modified to provide the code for checking constraints. An example of the modification of the query, Q.sub.MAIN, from Table 1 is provided below in Table 2:
TABLE 2
______________________________________
1. begin
2. with I.sub.1 as insert into T.sub.1 select * from T.sub.1
3. select 1
4. from I.sub.1
5. where 1=case
6. when I.sub.1.R.sub.(T.sbsb.1 .sub.,1) 1! is not null and
7. . . .
8. I.sub.1.R.sub.(T.sbsb.1 .sub.,1) .sup.z R.sub.(T.sbsb.1
.sub.,1) !is not null and
9. not exists
10. (select 1 from P.sub.(T.sbsb.1 .sub.,1)
11. where P.sub.(T.sbsb.1 .sub.,1).R.sub.(T.sbsb.1 .sub.,1)
1!=I.sub.1.R.sub.(T.sbsb.1 .sub.,1) 1!
12. and P.sub.(T.sbsb.1 .sub.,1).R.sub.(T.sbsb.1 .sub.,1)
2!=I.sub.1.R.sub.(T.sbsb.1 .sub.,1) 2!
13. . . .
14. and P.sub.(T.sbsb.1 .sub.,1).R.sub.(T.sbsb.1 .sub.,1)
.sup.z R.sub.(T.sbsb.1 .sub.,1) !=
I.sub.1.R.sub.(T.sbsb.1 .sub.,1) .sup.z R.sub.(T.sbsb.1
.sub.,1) !)
15. then raise.sub.-- error(`-3603`, R.sub.(T.sbsb.1 .sub.,1).name)
16. . . .
17. when .sup.I 1.sup..R (T.sub.1,x.sub.T.sbsb.1)1! is not null and
18. . . .
19. .sup.I 1.sup..R (T.sub.1,x.sub.T.sbsb.1).sup..spsp.z .sup.R
(T.sub.1,x.sub.T.sbsb.1).sup.!
is not null and
20. not exists
21. (select 1 from.sup..P (T.sub.1,x.sub.T.sbsb.1)
22. where .sup..P (T.sub.1,x.sub.T.sbsb.1).sup..R (T.sub.1,x.sub.T.sbs
b.1)1!=
.sup.I 1.sup..R (T.sub.1,x.sub.T.sbsb.1)1!
23. and .sup..P (T.sub.1,x.sub.T.sbsb.1).sup..R (T.sub.1,x.sub.T.sbsb.
1)2!=
.sup.I 1.sup..R (T.sub.1,x.sub.T.sbsb.1)2!
24. . . .
25. and.sup..P (T.sub.1,x.sub.T.sbsb.1).sup..R (T.sub.1,x.sub.T.sbsb.1
).sup..spsp.z .sup.R (T.sub.1,x.sub.T.sbsb.1).sup.! =
.sup.I 1.sup..R (T.sub.1,x.sub.T.sbsb.1).sup..spsp.z .sup.R
(T.sub.1,x.sub.T.sbsb.1).sup.!)
26 then raise.sub.-- error(`-3603`, .sup..R (T.sub.1,x.sub.T.sbsb.1).
name)
27. when not C.sub.(T.sbsb.1 .sub.,1) (I.sub.1.C.sub.(T.sbsb.1
.sub.,1) 1!, . . . ,
I.sub.1.C.sub.(T.sbsb.1 .sub.,1) .sup.z C.sub.(T.sbsb.1 .sub.,1)
!)
28. then raise.sub.-- error(`-3603`, C.sub.(T.sbsb.1 .sub.,1).name)
29. . . .
30. when not .sup..C (T.sub.1,y.sub.T.sbsb.1).sup.I 1.sup..C (T.sub.1,
y.sub.T.sbsb.1)1!, . . . ,
.sup.I 1.sup..C (T.sub.1,y.sub.T.sbsb.1).sup..spsp.z .sup.R
(T.sub.1,y.sub.T.sbsb.1).sup.!)
31. then raise.sub.-- error(`-3603`, .sup..C (T.sub.1,x.sub.T.sbsb.1).
name)
32. else 2
33. with I.sub.n as insert into T.sub.n select * from T.sub.n
34. select 1
35. from I.sub.n
36. where 1=case
37. when I.sub.n.R.sub.(T.sbsb.n .sub.,1) 1!is not null and
38. . . .
39. I.sub.n.R.sub.(T.sbsb.n .sub.,1) .sup.z R.sub.(T.sbsb.n
.sub.,1) !is not null and
40. not exists
41. (select 1 from P.sub.(T.sbsb.n .sub.,1)
42. where P.sub.(T.sbsb.n .sub.,1).R.sub.(T.sbsb.n .sub.,1)
1!=
I.sub.n.R.sub.(T.sbsb.n .sub.,1) 1!
43. and P.sub.(T.sbsb.n .sub.,1).R.sub.(T.sbsb.n .sub.,1) 2!=
I.sub.n.R.sub.(T.sbsb.n .sub.,1) 2!
44. . . .
45. and P..sub.(T.sbsb.n .sub.,1).R.sub.(T.sbsb.n .sub.,1)
.sup.z R.sub.(T.sbsb.1 .sub.,1) !=
I.sub.n.R.sub.(T.sbsb.n .sub.,1) .sup.z R.sub.(T.sbsb.1
.sub.,1) !)
46. then raise.sub.-- error(`-3603`, R.sub.(T.sbsb.n .sub.,1).name)
47. . . .
48. when .sup.I n.sup..R (T.sub.n,x.sub.T.sbsb.n)1! is not null and
49. . . .
50. .sup.I n.sup..R (T.sub.n,x.sub.T.sbsb.n).sup..spsp.z .sup.R
(T.sub.n,x.sub.T.sbsb.n).sup.!
is not null and
51. not exists
52. (select 1 from .sup..P (T.sub.n,x.sub.T.sbsb.n)
53. where .sup..P (T.sub.n,x.sub.T.sbsb.n).sup..R (T.sub.n,x.sub
.T.sbsb.n)1!=
.sup.I n.sup..R (T.sub.n,x.sub.T.sbsb.n)1!
54. and .sup.P (T.sub.n,x.sub.T.sbsb.n).sup..R (T.sub.n,x.sub.T.
sbsb.n)2!=
.sup.I n.sup..R (T.sub.n,x.sub.T.sbsb.n)2!
55. . . .
56. and .sup.P (T.sub.n,x.sub.T.sbsb.n).sup..R (T.sub.n,x.sub.T.
sbsb.n).sup..spsp.z .sup.R (T.sub.n,x.sub.T.sbsb.n).sup.!=
.sup.I n.sup..R (T.sub.n,x.sub.T.sbsb.n).sup..spsp.z
.sup.R (T.sub.n,x.sub.T.sbsb.n).sup.!)
57. then raise.sub.-- error(`-3603`, .sup.R (T.sub.n,x.sub.T.sbsb.n).n
ame)
58. when not C.sub.(T.sbsb.n .sub.,1) (I.sub.n.C.sub.(T.sbsb.n
.sub.,1) 1!, . . . ,
I.sub.n.C.sub.(T.sbsb.n .sub.,1) .sup.z C.sub.(T.sbsb.n .sub.,1)
!)
59. then raise.sub.-- error(`-3603`, C.sub.(T.sbsb.n .sub.,1).name)
60. . . .
61. when not .sup.C (T.sub.n,y.sub.T.sbsb.n).sup.I n.sup..C (T.sub.n,y
.sub.T.sbsb.n .sub.) 1!, . . . ,
.sup.I n.sup..C (T.sub.n,y.sub.T.sbsb.n).sup..spsp.z .sup.R
(T.sub.n,y.sub.T.sbsb.n .sub.) .sup.!)
62. then raise.sub.-- error(`-3603`, .sup..C (T.sub.n,y.sub.T.sbsb.n
.sub.).name)
63. else 2
64. end
65. end
______________________________________
With reference to FIGS. 1, 4, and Table 2, the steps of SELECT CONSTRAINT processing are further explained. In the above Table 2, the "raise.sub.-- error('-3603" . . . ) syntax is an example of a certain error having code number "3603". It is understood that any error code could be reported, not just the exemplary "3603" error code. The WHERE and CASE statements are used to check for constraint violations, as described above. Upon completion of step 136 (FIG. 4), execution of the query shown in Table 2 results in the checking of each record to be inserted for constraint violations. However, the SELECT CONSTRAINT module takes advantage of this situation by interrupting the normal query processing, as described with reference to FIG. 1 above, by modifying the query of Table 2 to effectively replace the INSERT statements with SELECT statements, as shown in step 138. In this way a new query is produced that can be used for constraint checking of bulk-loaded data, such as that stored in one or more tables, T.sub.i. The process of step 138 of FIG. 4 is provided below in Table 3 in a preferred pseudocode embodiment of this invention, wherein any INSERT statement is replaced with a SELECT statement.
TABLE 3
______________________________________
1. begin
2. select 1
3. from T.sub.1
4. where 1=CASE
5. when T.sub.1.R.sub.(T.sbsb.1 .sub.,1) 1! is not null and
6. . . .
7. T.sub.1.R.sub.(T.sbsb.1 .sub.,1) .sup.z R.sub.(T.sbsb.1
.sub.,1) !is not null and
8. not exists
9. (select 1 from P.sub.(T.sbsb.1 .sub.,1)
10. where P.sub.(T.sbsb.1 .sub.,1).R.sub.(T.sbsb.1 .sub.,1)
1!=T.sub.1.R.sub.(T.sbsb.1 .sub.,1) 1!
11. and P.sub.(T.sbsb.1 .sub.,1).R.sub.(T.sbsb.1 .sub.,1)
2!=T.sub.1.R.sub.(T.sbsb.1 .sub.,1) 2!
12. . . .
13. and P.sub.(T.sbsb.1 .sub.,1).R.sub.(T.sbsb.1 .sub.,1)
.sup.z R.sub.(T.sbsb.1 .sub.,1) !=
T.sub.1.R.sub.(T.sbsb.1 .sub.,1) .sup.z R.sub.(T.sbsb.1
.sub.,1) !)
14. then raise.sub.-- error(`-3603`, R.sub.(T.sbsb.1 .sub.,1).name)
15. . . .
16. when .sup.T 1.sup..R (T.sub.1,x.sub.T.sbsb.1)1! is not null and
17. . . .
18. .sup.T 1.sup..R (T.sub.1,x.sub.T.sbsb.1).sup..spsp.z .sup.R
(T.sub.1,x.sub.T.sbsb.1).sup.! is not null and
19. not exists
20. (select 1 from .sup.P (T.sub.1,x.sub.T.sbsb.1)
21. where .sup.P (T.sub.1,x.sub.T.sbsb.1).sup..R (T.sub.1,x.sub.T.sbsb
.1)1!=
.sup.T 1.sup..R (T.sub.1,x.sub.T.sbsb.1)1!
22. and .sup.P (T.sub.1,x.sub.T.sbsb.1).sup..R (T.sub.1,x.sub.T.sbsb.1
)2!=
.sup.T 1.sup..R (T.sub.1,x.sub.T.sbsb.1)2!
23. . . .
24. and .sup.P (T.sub.1,x.sub.T.sbsb.1).sup..R (T.sub.1,x.sub.T.sbsb.1
).sup..spsp.z .sup.R (T.sub.1,x.sub.T.sbsb.1).sup.! =
.sup.T 1.sup..R (T.sub.1,x.sub.T.sbsb.1).sup..spsp.z .sup.R
(T.sub.1,x.sub.T.sbsb.1).sup.!)
25. then raise.sub.-- error(`-3603`, .sup.R (T.sub.1,x.sub.T.sbsb.1).n
ame)
26. when not C.sub.(T.sbsb.1 .sub.,1) (T.sub.1.C.sub.(T.sbsb.1
.sub.,1) 1!, . . . ,
T.sub.1.C.sub.(T.sbsb.1 .sub.,1) .sup.z C.sub.(T.sbsb.1 .sub.,1)
!)
27. then raise.sub.-- error(`-3603`, C.sub.(T.sbsb.1 .sub.,1).name)
28. . . .
29. when not .sup..C (T.sub.1,y.sub.T.sbsb.1).sup.(T 1.sup..C
(T.sub.1,y.sub.T.sbsb.1)1!, . . . ,
.sup.T 1.sup..C (T.sub.1,y.sub.T.sbsb.1).sup..spsp.z .sup.C
(T.sub.1,y.sub.T.sbsb.1).sup.!)
30. then raise.sub.-- error(`-3603`, .sup.C (T.sub.1,y.sub.T.sbsb.1).n
ame)
31. else 2
32. . . .
33. select 1
34. from T.sub.n
35. where 1=case
36. when T.sub.n.R.sub.(T.sbsb.n .sub.,1) 1!is not null and
37. . . .
38. T.sub.n.R.sub.(T.sbsb.n .sub.,1) .sup.z R.sub.(T.sbsb.n
.sub.,1) !is not null and
39. not exists
40. (select 1 from P.sub.(T.sbsb.n .sub.,1)
41. where P.sub.(T.sbsb.n .sub.,1).R.sub.(T.sbsb.n .sub.,1)
1!=T.sub.n.R.sub.(T.sbsb.n .sub.,1) 1!
42. and P.sub.(T.sbsb.n .sub.,1).R.sub.(T.sbsb.n .sub.,1)
2!=T.sub.n.R.sub.(T.sbsb.n .sub.,1) 2!
43. . . .
44. and P.sub.(T.sbsb.n .sub.,1).R.sub.(T.sbsb.n .sub.,1)
.sup.z R.sub.(T.sbsb.n .sub.,1) !)=
T.sub.n.R.sub.(T.sbsb.n .sub.,1) .sup.z R.sub.(T.sbsb.n
.sub.,1) !
45. then raise.sub.-- error(`-3603`, R.sub.(T.sbsb.n .sub.,1).name
46. . . .
47. when .sup.T n.sup..R (T.sub.n,x.sub.T.sbsb.n)1!is not null and
48. . . .
49. .sup.T n.sup..R (T.sub.n,x.sub.T.sbsb.n).sup..spsp.z .sup.R
(T.sub.n,x.sub.T.sbsb.n).sup.! is not null and
50. not exists
51. (select 1 from .sup.P (T.sub.n,x.sub.T.sbsb.n)
52. where .sup.P (T.sub.n,x.sub.T.sbsb.n).sup..R (T.sub.n,x.sub.
T.sbsb.n)1!=
.sup.T n.sup..R (T.sub.n,x.sub.T.sbsb.n)1!
53. and .sup.P (T.sub.n,x.sub.T.sbsb.n).sup..R (T.sub.n,x.sub.T.
sbsb.n)2!=
.sup.T n.sup..R (T.sub.n,x.sub.T.sbsb.n)2!
54. . . .
55. and .sup.P (T.sub.n,x.sub.T.sbsb.n).sup..R (T.sub.n,x.sub.T.
sbsb.n).sup..spsp.z .sup.R (T.sub.n,x.sub.T.sbsb.n .sub.)
.sup.! =
.sup.T n.sup..R (T.sub.n,x.sub.T.sbsb.n).sup..spsp.z
.sup.R (T.sub.n,x.sub.T.sbsb.n).sup.!)
56. then raise.sub.-- error(`-3603`, .sup..R (T.sub.n,x.sub.T.sbsb.n).
name)
57. when not C.sub.(T.sbsb.n .sub.,1) (T.sub.n.C.sub.(T.sbsb.n
.sub.,1) 1!, . . . ,
T.sub.n.C.sub.(T.sbsb.n .sub.,1) .sup.z R.sub.(T.sbsb.n .sub.,1)
!)
58. then raise.sub.-- error(`-3603`, C.sub.(T.sbsb.n .sub.,1).name)
59. . . .
60. when not .sup..C (T.sub.n,y.sub.T.sbsb.n).sup.(T n.sup..C
(T.sub.n,y.sub.T.sbsb.n)1!, . . . ,
.sup.T n.sup..C (T.sub.n,y.sub.T.sbsb.n).sup..spsp.z .sup.C
(T.sub.n,y.sub.T.sbsb.n).sup.!)
61. then raise.sub.-- error(`-3603`, C.sub.(T.sbsb.n .sub.,1).name
62. else 2
63. end
______________________________________
Referring to FIGS. 4 and 5, the processing of the SET CONSTRAINTS method of this invention continues at step 140, signifying the continuity of flow between FIGS. 4 and 5. A determinative step 142 asks if the control program or a user requires only information that an error has occurred when the first constraint violation is found. If so, then this case is denoted as "check only". If "check only" is performed, then in step 144 the query of the type shown in Table 3 is compiled, optimized and executed, according to normal QGM processing discussed with reference to FIG. 1 above. The error data reporting message generated in step 146 is then communicated. For example, it may be passed to display 76 or recorded in mass storage unit 82 for later retrieval. In step 147, if there are no errors, tables are taken out of the pending state. If level 1 information is sufficient, processing ends at step 148. However, should more than level 1 information be desired, an aspect of this invention for generating further information or deleting the offending records to recover referential integrity may be employed, as described below. Referring again to FIG. 5 and also to Table 4 shown below, if more than "check only" information is required, processing continues as shown at step 150. Pseudocode representations of the steps 150 through 174 are provided in Table 4 and described below. Therefore, it will be helpful for the reader to refer to Table 4 while following the steps in the flow chart. Before compiling a query, it is modified by convening negated existential predicates for referential constraints to subquery form. For example, step 150 corresponds to lines 47-61 in Table 3. At step 152, the subquery is outer-joined with its corresponding tables, as shown at lines 25-35 of Table 4. Table 4 is also discussed below in connection with FIG. 6.
TABLE 4
______________________________________
1. begin
2. create temporary table ONEROW(c.sub.1) as (values (1))
3. insert into E.sub.1
4. select T.sub.1,c.sub.1,T.sub.1,c.sub.2 . . . T.sub.1.c.sub.m.sbsb.T
1 current timestamp,
##STR4##
6. T.sub.1.R.sub.(T.sbsb.1.sub.,1) 1! is not null and
7. . . .
##STR5##
9. then 'R.sub.(T.sbsb.1.sub.,1).name' else "
10. end .parallel.
11. . . .
##STR6##
##STR7##
14. . . .
##STR8##
##STR9##
17. end .parallel.
##STR10##
19. then 'C.sub.(T.sbsb.1.sub.,1).name' else "
20. end .parallel.
21. . . .
##STR11##
##STR12##
##STR13##
24. end
25. from T.sub.1 left outer joint
26. (select 1
27. from ONEROW
28. where
29. not exists
30. (select 1 from P.sub.(T.sbsb.1.sub.,1)
31. where P.sub.(T.sbsb.1.sub.,1).R.sub.(T.sbsb.1.sub.,1) 1! =
T.sub.1.R.sub.(T.sbsb.1.sub.,1) 1!
32. and P.sub.(T.sbsb.1.sub.,1).R.sub.(T.sbsb.1.sub.,1) 2! =
T.sub.1.R.sub.(T.sbsb.1.sub.,1) 2!
33. . . .
##STR14##
##STR15##
36. left outer join . . .
37. (select 1
38. from ONEROW
39. where
40. not exists
##STR16##
##STR17##
43. . . .
##STR18##
##STR19##
##STR20##
##STR21##
47. T.sub.1.R.sub.(T.sbsb.1.sub.,1) 1! is not null and
48. . . .
##STR22##
50. or
51. . . .
##STR23##
##STR24##
54. . . .
##STR25##
56. or
##STR26##
58. . . .
##STR27##
60. . . .
61. insert into E.sub.n
##STR28##
##STR29##
64. T.sub.n.R.sub.(T.sbsb.n.sub.,1) 1! is not null and
65. . . .
##STR30##
67. then 'R.sub.(T.sbsb.n.sub.,1).name' else "
68. end .parallel.
69. . . .
70.
##STR31##
##STR32##
72. . . .
##STR33##
##STR34##
75. end .parallel.
##STR35##
77. then 'C.sub.(T.sbsb.n.sub.,1).name' else "
78. end .parallel.
79. . . .
80.
##STR36##
##STR37##
##STR38##
82. end
83. from T.sub.n left outer join
84. (select 1
85. from ONEROW
86. where
87. not exists
88. (select 1 from P.sub.(T.sbsb.n.sub.,1)
89. where P.sub.(T.sbsb.n.sub.,1).R.sub.(T.sbsb.n.sub.,1) 1! =
T.sub.n.R.sub.(T.sbsb.n.sub.,1) 1!
90. and P.sub.(T.sbsb.n.sub.,1).R.sub.(T.sbsb.n.sub.,1) 2! =
T.sub.n.R.sub.(T.sbsb.n.sub.,1) 2!
91. . . .
##STR39##
##STR40##
94. left outer join . . .
95. (select 1
96. from ONEROW
97. where
98. not exists
##STR41##
100.
##STR42##
101. . . .
102.
##STR43##
103.
##STR44##
104.
##STR45##
105. T.sub.n.R.sub.(T.sbsb.n.sub.,1) 1! is not null and
106. . . .
107.
##STR46##
108. or
109. . . .
110.
##STR47##
111.
##STR48##
112. . . .
113.
##STR49##
114. or
115.
##STR50##
116. or . . .
117.
##STR51##
118. end
______________________________________
Referring to FIGS. 5 and 6, processing continues from step 154 to step 158. Step 158 creates code that identifies all records in the one or more tables T.sub.i that exhibit constraint violations, either by violating a check constraint or by violating referential integrity. In step 162, the SET CONSTRAINTS module generates code that can construct a message for each record in violation that contains all constraint names for all records in violation. The message contains all of the constraint names concatenated in a string. After the code for creating the messages is created, then, in step 164, the SET CONSTRAINTS module constructs an INSERT statement that serves to place information in a new table. The new table will contain columns identifying records that are in violation of constraints, and will include for each identified record a timestamp indicating a reporting time, and the constructed message. This new table is denominated "the exception table" and is denoted herein as E.sub.i. Referring now to FIGS. 6 and Table 4, the above described information is used to automatically flag an error and identify it, such as "Permissible Age Range Exceeded", and will also show the offending record column entry, such as "19 years of age", as well as the other columns in the record. Preferably, the information includes the timestamp to indicate when the error was flagged. Step 166 inquires if it is desirable to "fix-up" the table(s) having violations. "Fix-up" refers to deleting records in violation of constraints, both primary and referential and also requires removing orphaned records from the database. If no fix-up is desired, steps 168, 170 and 174 are executed. The non-fix-up case ends with step 174. In step 168, the constructed modified query is compiled, optimized and executed according to the normal query translation process described above with reference to FIG. 1. Then, the exception table E.sub.i is populated using the INSERT statement generated in step 164. The non-fix-up case ends in step 174. In step 171, if there are no errors, then tables are brought out of pending state. Referring to FIGS. 6 and 7, when repairing the database to erase records with column entry violations, processing continues to step 172. Reference is also made to Table 5 for a pseudocode embodiment of an example implementing the fix-up case described above. In general, a DELETE statement must be applied before the INSERT in order to delete violating records from the database. The deleted records are then inserted into the exception table(s) E.sub.i resulting in the following query:
TABLE 5
______________________________________
1. begin
2. create temporary table ONEROW(c.sub.1) as (values(1)),
##STR52##
##STR53##
##STR54##
6. T.sub.1.R.sub.(T.sbsb.1.sub.,1) 1! is not null and
7. . . .
##STR55##
9. then 'R.sub.(T.sbsb.1.sub.,1).name' else "
10. end .parallel.
11. . . .
##STR56##
##STR57##
14. . . .
##STR58##
##STR59##
17. end .parallel.
##STR60##
19. then 'C.sub.(T.sbsb.1.sub.,1) '.name' else "
20. end .parallel.
21. . . .
##STR61##
##STR62##
##STR63##
24. end
25. from T.sub.1 left outer join
26. (select 1
27. from ONEROW
28. where
29. not exists
30. (select 1 from P.sub.(T.sbsb.1.sub.,1)
31. where P.sub.(T.sbsb.1.sub.,1).R.sub.(T.sbsb.1.sub.,1) 1! =
T.sub.1.R.sub.(T.sbsb.1.sub.,1) 1!
32. and P.sub.(T.sbsb.1.sub.,1).R.sub.(T.sbsb.1.sub.,1) 2! =
T.sub.1.R.sub.(T.sbsb.1.sub.,1) 2!
33. . . .
##STR64##
##STR65##
36. left outer join . . .
37. (select 1
38. from ONEROW
39. where
40. not exists
##STR66##
##STR67##
43. . . .
##STR68##
##STR69##
##STR70##
47. T.sub.1.R.sub.(T.sbsb.1.sub.,1) 1! is not null and
48. . . .
##STR71##
50. or
51. . . .
##STR72##
##STR73##
54. . . .
##STR74##
56. or
##STR75##
58. . . .
##STR76##
60. . . .
##STR77##
##STR78##
##STR79##
64. T.sub.n.R.sub.(T.sbsb.n.sub.,1) 1! is not null and
65. . . .
##STR80##
67. then 'R.sub.(T.sbsb.n.sub.,1).name' else "
68. end .parallel.
69. . . .
70.
##STR81##
##STR82##
72. . . .
##STR83##
##STR84##
75. end .parallel.
##STR85##
77. then 'C.sub.T.sbsb.n.sub.,1) '.name' else"
78. end .parallel.
79. . . .
80.
##STR86##
##STR87##
##STR88##
82. end
83. from T.sub.n left outer join
84. (select 1
85. from ONEROW
86. where
87. not exists
88. (select 1 from P.sub.(T.sbsb.n.sub.,1)
89. where P.sub.(T.sbsb.n.sub.,1).R.sub.(T.sbsb.n.sub.,1) 1! =
T.sub.n.R.sub.(T.sbsb.n.sub.,1) 1!
90. and P.sub.(T.sbsb.n.sub.,1).R.sub.(T.sbsb.n.sub.,1) 2! =
T.sub.1.R.sub.(T.sbsb.n.sub.,1) 2!
91. . . .
##STR89##
##STR90##
94. left outer join . . .
95. (select 1
96. from ONEROW
97. where
98. not exists
##STR91##
100.
##STR92##
101. . . .
102.
##STR93##
103.
##STR94##
104.
##STR95##
105. T.sub.n.R.sub.(T.sbsb.n.sub.,1) 1! is not null and
106. . . .
107.
##STR96##
108. or
109. . . .
110.
##STR97##
111.
##STR98##
112. . . .
113.
##STR99##
114. or
115.
##STR100##
116. or . . .
117.
##STR101##
118. select * from VIOL.sub.1 ;
119. . . .
120. select * from VIOL.sub.n ;
121.
##STR102##
122. (delete VIOL.sub.1.c.sub.1,VIOL.sub.1.c.sub.2,...,
##STR103##
123. from T.sub.1, VIOL.sub.1
124. where T.sub.1.#rid = VIOL.sub.1.rid);
125. . . .
126.
##STR104##
127. (delete VIOL.sub.n.c.sub.1,VIOL.sub.n.c.sub.2,...,
##STR105##
128. from T.sub.n, VIOL.sub.n
129. where T.sub.n.#rid = VIOL.sub.n.rid);
130. insert into E.sub.1
131.
##STR106##
132. from DT.sub.1 ;
133. . . .
134. insert into E.sub.n
135.
##STR107##
136. from DT.sub.n ;
137. end
______________________________________
With reference now to FIG. 7 and also to Table 5, shown above, the processing of the SELECT CONSTRAINT module implementing the fix-up case is described. In step 176, the module selects each record id (rid) for each record having violating entries. In step 178, the module implements a fix-up process, by replacing INSERTS with common table expressions (VIOL.sub.i) to represent violating records. For example, the pseudocode representation of steps 176 and 178 is shown in Table 5 at lines 3-4. In step 180, the module creates a temporary table DT.sub.i that is used later to select violating records to be deleted from the database. The pseudocode representation of step 180 is shown in Table 5 at lines 121-129. Step 182 creates code to insert the deleted records in the exception table by first creating an INSERT statement to perform this activity. An exception table E.sub.i exists for each bulk-loaded table T.sub.i. The pseudocode for carrying out step 182 is shown in Table 5 at lines 130-137. The exception table is essentially a violation table that is used to flag all errors designating violations inherent in the original data before any violating records are deleted. Referring to FIG. 8, processing continues from FIG. 7 as step 184 flows into step 188. The presence of the DELETE from a parent table in the query causes the constraint compiler to naturally compile in the code that eliminates orphan records, as shown in step 188. In this way, the orphaned children records can be inspected before they are erased. In step 190, the system of FIG. 3 carries out the constructed code created in the above steps, wherein the query is compiled, optimized, and executed in normal fashion, as described above with reference to FIG. 1. The tables are brought out of pending state in step 191. Processing of the method of this invention by the system of FIG. 3 ends in step 192. Example of Implementation of the Method Referring to FIGS. 9A-9C, a specific example is shown to illustrate an application of the method of the invention employing general case of the preferred embodiment of the pseudocode of Tables 1-5. The general case pseudocode is shown in a modified state, as the specific example values are substituted in Tables 6-10. In FIG. 9A, three tables 304, 308 and 312 are shown stored on storage unit 300. The empty tables 304 and 308 are created to store employee (EMP) information and project (PROJ) information, respectively. State 302 indicates a pending state, which the tables will be placed in at the time of receiving data that remains to be checked. Table 304 is empty because data 306A is an empty string or simply blank. Data 310A of empty table 308 is also blank. The table 312 contains department (DEPT) information and its data area 313 contains information regarding departments. Tables 304, 308 and 312 are created according to the following definitions:
______________________________________
create table EMP
(empno int not null primary key,
deptno int,
age int,
constraint EMPDEPT foreign key (deptno) refer-
ences DEPT,
constraint MINAGE age > 16);
create table DEPT
(deptno int not null primary key,
name varchar(20),
mgrno int) ; and
create table PROJ
projno int not null primary key,
lead int,
constraint PROJLEAD foreign key (lead) refer-
ences EMP).
______________________________________
Again referring to FIG. 9A, tape unit 314 contains an EMP table 316 having data 318 and a PROJ table 320 having data 322. The data from the tables on the tape is to be bulk-loaded into the empty tables on storage unit 300. The EMP table contains columns 317, denoted as EMP.EMPNO, EMP.DEPTNO, and EMP.AGE, defining in respective order the employee number, department number, and age of each employee. The PROJ table contains columns 319 denoted as PROJ.PROJNO and PROJ.LEAD, defining in respective order the project number and project leader. The project leader is an employee that must also be identified by the EMP table. Referring to FIG. 9B, when a well-known bulk-loading facility is used to download data into the tables, the EMP and PROJ tables are populated with data from the tape and are placed in the pending state. Thus, the EMP table 304 contains new data 306B, and the PROJ table 308 contains new data 310B. However, the tables are in the pending state 302, meaning they cannot be used. Table 312, containing data 313, unaffected by the bulk-loading, remains in a usable (non-pending) state. The DEPT table contains the columns 315 denoted as DEPT.DEPTNO, DEFT.NAME and DEPT.MGRNO, defining respectively the department number, department name, and the department manager's number. Referring to FIG. 9C, after applying the constraint-checking mechanism enabled by this invention, the pending state 302 no longer refers to the EMP and PROJ tables. After constraint checking, the data 306C and 310C of respective tables 304 and 308 is usable. The department table 312 which is used for ensuring referential integrity of its data 313 is also usable. After constraint checking, the following constraint conditions must be met. The EMP.DEPTNO column of table 304 must have referential integrity with a record in the DEPT table 312. Further, the EMP.AGE column must be checked for violation of constraint MINAGE. Assume this constraint is that the minimum employee age must be 16 years (e.g., EMP.AGE.gtoreq.16). The PROJ.LEAD column of the PROJ table must also be checked to ensure referential integrity with an EMP.EMPNO identified in the EMP table. With these constraints in mind, the preferred general case pseudocode shown in Tables 5-9 is illustrated below with substituted values derived from the example case of the tables of FIGS. 9A-9C. Referring to Table 6, a dummy INSERT query is generated with an INSERT statement for each table, as shown below:
TABLE 6
______________________________________
1. begin
2. insert into EMP select * from EMP;
3. insert into PROJ select * from PROJ;
4. end
______________________________________
Referring to Table 7, when the dummy INSERT query is generated, then the processor calls the constraints compiler 24 to compile the INSERT commands and check for constraint violations according to the constraint rules described above with reference to FIGS. 9A-9C. The resulting query is shown below.
TABLE 7
______________________________________
1. begin
2. with I.sub.EMP as insert into EMP select * from EMP
3. select 1
4. from I.sub.EMP
5. where 1=case
6. when I.sub.EMP.deptno is not null and
7. not exists
8. (select 1 from DEPT.deptno
9. where DEPT.deptno = I.sub.EMP.deptno)
10. then raise.sub.-- error(`-3603`, EMPDEPT)
11. when not (I.sub.EMP.age > 16)
12. then raise.sub.-- error(`-3603`, MINAGE)
13. else 2
14. end
15. with I.sub.PROJ as insert into PROJ select * from PROJ
16. select 1
17. from I.sub.PROJ
18. where 1=case
19. when I.sub.PROJ.lead is not null and
20. not exists
21. (select 1 from EMP
22. where EMP.empno = I.sub.PROJ.lead)
23. then raise.sub.-- error(`-3603`, PROJLEAD)
24. else 2
25. end
26. end
______________________________________
Referring to Table 8, the query is modified to replace any INSERT statements with SELECT statements. The resulting query is shown below.
TABLE 8
______________________________________
1. begin
2. select 1
3. from EMP
4. where 1=case
5. when EMP.deptno is not null and
6. not exists
7. (select 1 from DEPT.deptno
8. where DEPT.deptno = EMP.deptno)
9. then raise.sub.-- error(`-3603`, EMPDEPT)
10. when not EMP.age > 16)
11. then raise.sub.-- error(`-3603`, MINAGE)
12. else 2
13. end
14. select 1
15. from PROJ
16. where 1 = case
17. when PROJ.lead is not null and
18. not exists
19. (select 1 from EMP
20. where EMP.empno = PROJ.lead)
21. then raise.sub.-- error(`-3603`, PROJLEAD)
22. else 2
23. end
24. end
______________________________________
This query is compiled, optimized and executed to report that a violation has been found. If it is desired to report all records that violate constraints, and what those constraints are, then it is necessary to create exception tables. Thus, for each record from table EMP or PROJ that violates at least one constraint, it is necessary to insert a record into an exception table E.sub.EMP or E.sub.PROJ (respectively) that contains each column of the violating record. Preferably, the timestamp and an identifying message that is a concatenating name of all constraint violations is also placed in the table. The resulting query is shown below in Table 9.
TABLE 9
______________________________________
1. begin
2. create temporary table ONEROW(c.sub.1) as (values (1));
3. insert into E.sub.EMP
4 select EMP.empno, EMP.deptno, EMP.age, current timestamp,
5. case when TEMP.sub.EMPDEPT.x is not null and
6 EMP.deptno is not null
7. then `EMPDEPT` else "
8. end .parallel.
9. case when not (age > 16)
10. then `MINAGE` else "
11. end
12. from EMP left outer join
13. (select 1
14. from ONEROW
15. where
16. not exists
17. (select 1 from DEPT
18. where DEPT.deptno = EMP.deptno)) as TEMP.sub.EMPDEPT
19. where TEMP.sub.EMPDEPT .x is not null and
20. EMP.deptno is not null
21. or
22. not (age > 16);
23. insert into E.sub.PROJ
24. select PROJ.projno, PROJ.lead, current timestamp,
25. case when TEMP.sub.PROJLEAD.x is not null and
26. PROJ.lead is not null
27. then `PROJLEAD` else "
28. end .parallel.
29. from PROJ left outer join
30. (select 1
31. from ONEROW
32. where
33. not exists
34. (select 1 from EMP
35. where EMP.empno = PROJ.lead)) as TEMP.sub.PROJLEAD
36. where TEMP.sub.PROJLEAD.x is not null and
37. PROJ.lead is not null;
38. end
______________________________________
For the fix-up case, a DELETE statement must be applied before the INSERT statement to delete any violating records from the database. The deleted records are thus inserted into the exception tables. This results in the following query.
TABLE 10
______________________________________
1. begin
2. create temporary table ONEROW(c.sub.1) as (values (1));
3. create temporary table with VIOL.sub.EMP (rid, empno,
deptno, age, ts, msg) as
4. (select EMP.#rid, EMP.empno, EMP.deptno,
EMP.age, current timestamp,
5. case when TEMP.sub.EMPDEPT.x is not null and
6. EMP.deptno is not null
7. then `EMPDEPT` else "
8. end .parallel.
9. case when not (age > 16)
10. then `MINAGE` else "
11. end
12. from EMP left outer join
13. (select 1
14. from ONEROW
15. where
16. not exists
17. (select 1 from DEPT
18. where DEPT.deptno = EMP.deptno))
as TEMP.sub.EMPDEPT
19. where (TEMP.sub.EMPDEPT.x is not null and
20. EMP.deptno is not null)
21. or
22. not (age > 16));
23. create temporary table VIOL.sub.PROJ (rid, projno, lead, ts, msg)
as
24. (select PROJ.projno, PROJ.lead, current timestamp,
25. case when TEMP.sub.PROJLEAD.x is not null and
26. PROJ.lead is not null
27. then `PROJLEAD`else "
28. end
29. from PROJ left outer join
30. (select 1
31. from ONEROW
32. where
33. not exists
34. (select 1 from EMP
35. where EMP.empno = PROJ.lead))
as TEMP.sub.PROJLEAD
36. where TEMP.sub.PROJLEAD.x is not null and
37. PROJ.lead is not null)
38. select * from VIOL.sub.EMP ;
39. select * from VIOL.sub.PROJ ;
40. create temporary table DT.sub.EMP (empno, deptno, age, ts, msg)
as
41. (delete VIOL.sub.EMP.empno, VIOL.sub.EMP.deptno,
VIOL.sub.EMP.age,
VIOL.sub.EMP.ts, VIOL.sub.EMP.msg
42. from EMP, VIOL.sub.EMP
43. where EMP.#rid = VIOL.sub.EMP.rid);
44. create temporary table DT.sub.PROJ (projno, lead, ts, msg) as
45. (delete VIOL.sub.PROJ.projno, VIOL.sub.PROJ.lead,
VIOL.sub.PROJ.ts,
VIOL.sub.PROJ.msg
46. from PROJ, VIOL.sub.PROJ
47. where PROJ.#rid = VIOL.sub.PROJ.rid);
48. insert into E.sub.EMP
49. select empno, deptno, age, ts, msg
50. from DT.sub.EMP ;
51. insert into E.sub.PROJ
52. select projno, lead, ts, msg
53. from DT.sub.PROJ ;
54. end
______________________________________
To enforce the CASCADE function, the constraint processor compiles additional code that modifies the query of Table 10 to DELETE all records from PROJ that are orphaned by deletes of records from EMP. This results in the following query.
TABLE 11
__________________________________________________________________________
begin
2. create temporary table ONEROW(c.sub.1) as (values (1))
3. create temporary table VIOL.sub.EMP (rid, empno, deptno, age, ts,
msg) as
4. (select EMP.#rid, EMP.empno, EMP.deptno, EMP.age, current
timestamp,
5. case when TEMP.sub.EMPDEPT.sup..x is not null and
6. EMP.deptno is not null
7. then `EMPDEPT`else "
8. end .parallel.
9. case when not (age > 16)
10. then `MINAGE` else "
11. end
12. from EMP left outer join
13. (select 1
14. from ONEROW
15. where
16. not exists
17. (select 1 from DEPT
18. where DEPT.deptno = EMP.deptno)) as TEMP.sub.EMPDEPT
19. where (TEMP.sub.EMPDEPT.x is not null and
20. EMP.deptno is not null)
21. or
22. not (age > 16))
23. create temporary table VIOL.sub.PROJ (rid, projno, lead, ts, msg) as
24. (select PROJ.projno, PROJ.lead, current timestamp,
25. case when TEMP.sub.PROJLEAD.x is not null and
26. PROJ.lead is not null
27. then `PROJLEAD` else "
28. end
29. from PROJ left outer join
30. (select 1
31. from ONEROW
32. where
33. not exists
34. (select 1 from EMP
35. where EMP.empno = PROJ.lead)) as TEMP.sub.PROJLEAD
36. where TEMP.sub.PROJLEAD.x is not null and
37. PROJ.lead is not null)
38. select * from VIOL.sub.EMP ;
39. select * from VIOL.sub.PROJ ;
40. create temporary table DT.sub.EMP (empno, deptno, age, ts, msg) as
41. (delete VIOL.sub.EMP.empno, VIOL.sub.EMP.deptno, VIOL.sub.EMP.age,
VIOL.sub.EMP.ts, VIOL.sub.CMP.msg
42. from EMP, VIOL.sub.EMP
43. where EMP.#rid = VIOL.sub.EMP.rid);
44. create temporary table DT.sub.PROJ (projno, lead, ts, msg) as
45. (delete VIOL.sub.PROJ.projno, VIOL.sub.PROJ.lead, VIOL.sub.PROJ.ts,
VIOL.sub.PROJ.msg
46. from PROJ, VIOL.sub.PROJ
47. where PROJ.#rid = VIOL.sub.PROJ.rid);
48. insert into E.sub.EMP
49. select empno, deptno, age, ts, msg
50. from DT.sub.EMP ;
51. insert into E.sub.PROJ
52. select projno, lead, ts, msg
53. from DT.sub.PROJ;
54. delete from PROJ, DT.sub.EMP
55. where PROJ.lead = DT.sub.EMP.empno;
end
__________________________________________________________________________
Set Constraints Syntax Referring to FIG. 10, the following example of a syntax diagram 400 for a SET CONSTRAINTS command is purely exemplary, but should be useful in illustrating the capabilities of the present invention, and will aid one skilled in the art in making and using the invention. The command line 404 contains the required syntactical statement, "SET CONSTRAINTS." This statement combined with "IMMEDIATE CHECKED" can be used to invoke the module. It is also required that a TABLE-NAME be identified for being checked for constraint violations, as illustrated in line 404. The SET CONSTRAINTS command may be invoked with a clause FOR IMMEDIATE CHECKED, that designates the checking is to begin immediately. The FOR-EXCEPTION clause designates that any row that is in violation of a FOREIGN KEY or CHECK key restraint will be copied to an exception table, such as table E.sub.i, and deleted from the original table. The IN TABLE-NAME1 clause specifies the table from which rows that violate constraints are to be copied. The USE TABLE-NAME2 clause specifies the particular exception table into which error rows are to be copied. Other variations of the illustrated syntax may be employed without deviating from the scope or spirit of the invention. While this invention is primarily discussed as a method, it can be understood by a person of ordinary skill in the art that the apparatus discussed above in connection with FIG. 3 may be programmed or otherwise designed to facilitate the practice of the method of this invention. Also, an article of manufacture, such as the prerecorded floppy disk 502 in FIG. 11 or other similar computer program product, for use with a data processing system, could include a storage medium, such as magnetic storage medium 504, and program means recorded thereon, such as the program means 506, 508, 510 and 512 in FIG. 10, for directing the data processing system to facilitate the practice of the method of this invention. It will be understood that such apparatus and articles of manufacture also fall within the spirit and scope of this invention. Other embodiments and modifications of this invention may occur to those of ordinary skill in the art in view of these teachings. Therefore, this invention is limited only by the following claims, which include all such embodiments and modifications when viewed in conjunction with the above specification and accompanying drawing.
|
Same subclass Same class Consider this |
||||||||||
