迁移ASE数据库的表之间存在引用时脚本执行情况

迁移ASE数据库的表结构时,需要注意表DDL的顺序,否则有些对象会因为其所引用的对象不存在而导致创建不成功。

解决的方法:将同样的脚本执行两次。

据我所知,sybase central或者ddlgen导出的语法中是没有很好的处理好对象之间的引用先后顺序的,所以,很有可能你的脚本需要执行两次才能保证所有的对象都成功创建上。

下面举个简单的例子,两张表,一张外键引用另一张。

sybase ASE中要求被外键引用的表的被引用列上有唯一约束。

在移植对象DDL的时候,举个例子:表A外键引用表B,如果导出的DLL语句中表A的定义语句在前面,而表B的DDL在后面。那么在创建表A的时候会因为外键引用的表B不存在而导致表A创建不成功。表B是能够成功创建的。

第二次执行上面相同的脚本时,首先会成功创建表A,因为其所引用的表B已经创建上了。而表B不会再次创建因为上次执行的时候已建上,会给出一个错误信息。这在isql是个错误信息,可能在sybase central中会是一个让人讨厌的弹出窗口。

总之,如果数据库内表之间定义了引用关系,那么同样的脚本语句需要执行两边才能成功完成工作。下面举一个外键引用的例子,分两种情况:

  1. 不带if exitsts .... drop table ...
  2. 带if exitsts .... drop table ...

有两种表:部门信息表dept,学生信息表students,学生表中的部门编号列引用表dept的dept_id列。正常的表定义语法如下:

use tempdb
go

create table dept(dept_id int unique not null, dept_name varchar(100) null)
go
create table students ( id int not null,name varchar(30) null,
  dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )
go
 

下面的测试假设进行表结构迁移时,用工具导出的表定义语法的顺序不正确。
第一种情况:不带if exitsts .... drop table ...

执行第一遍语句
1> create table students ( id int not null,name varchar(30) null,
2>   dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )
3> go
Msg 1710, Level 16, State 3:
Server 'NMR', Line 1:
Referenced table 'dept' specified in a referential constraint declared on
'students' does not exist in the database 'tempdb'.
Msg 2761, Level 16, State 4:
Server 'NMR', Line 1:
Failed to create declarative constraints on table 'students' in database
'tempdb'.
1> create table dept(dept_id int unique not null, dept_name varchar(100) null)
2> go
因为学生信息表students没有成功创建,执行第二遍语句,
1>
2>
3>
4> use tempdb
5> go
1> create table students ( id int not null,name varchar(30) null,
2>   dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )
3> go
1> create table dept(dept_id int unique not null, dept_name varchar(100) null)
2> go
Msg 2714, Level 16, State 1:
Server 'NMR', Line 1:
There is already an object named 'dept' in the database.
第二遍执行语句的时候,报部门信息表已经存在的错误。

第二种情况:带if exitsts .... drop table ...

执行效果如下:
1> use tempdb
2> go
1> if exists(select 1 from sysobjects where type='U' and name='student')
2>   drop table students
3> go
1> create table students ( id int not null,name varchar(30) null,
2>   dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )
3> go
Msg 1710, Level 16, State 3:
Server 'NMR', Line 1:
Referenced table 'dept' specified in a referential constraint declared on
'students' does not exist in the database 'tempdb'.
Msg 2761, Level 16, State 4:
Server 'NMR', Line 1:
Failed to create declarative constraints on table 'students' in database
'tempdb'.
1>
2> if exists(select 1 from sysobjects where type='U' and name='dept')
3>     drop table dept
4> go
1> create table dept(dept_id int unique not null, dept_name varchar(100) null)
2> go
1>
2>
3>下面是第二遍执行同样的语句
4>
5> use tempdb
6> go
1> if exists(select 1 from sysobjects where type='U' and name='student')
2>   drop table students
3> go
1> create table students ( id int not null,name varchar(30) null,
2>   dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )
3> go
1>
2> if exists(select 1 from sysobjects where type='U' and name='dept')
3>     drop table dept
4> go
Msg 3712, Level 16, State 1:
Server 'NMR', Line 3:
Cannot drop table 'dept' because it still has referential integrity
constraints.
1> create table dept(dept_id int unique not null, dept_name varchar(100) null)
2> go
Msg 2714, Level 16, State 1:
Server 'NMR', Line 1:
There is already an object named 'dept' in the database.
第一遍同样students不能成功创建,第二遍dept不能删除,因为存在引用它的表students,继而也不能再次创建。

PS:如果存在表之间的引用,且表之间的顺序不正确的话,需要将脚本执行两便才能保证对象都成功创建上。

 

  • 本文链接地址:https://www.dbainfo.net/imgrate-ase-database-referencial-table-scripts-execute-twice.htm
  • 本文为dbainfo个人原创,请在尊重作者劳动成果的前提下进行转载;
  • 转载务必注明原始出处 : Sybase数据库技术,数据库恢复专家
  • 对《迁移ASE数据库的表之间存在引用时脚本执行情况》有何疑问或见解,请在本文下方发表;
  • 对网站还有其他问题或建议,请提交在留言板,谢谢!
  • 目前还没有任何评论.
    :wink: :twisted: :roll: :oops: :mrgreen: :lol: :idea: :evil: :cry: :arrow: :?: :-| :-x :-o :-P :-D :-? :) :( :!: 8-O 8)