<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sybase数据库技术，数据库恢复专家 &#187; 外键引用</title>
	<atom:link href="http://www.dbainfo.net/tag/%e5%a4%96%e9%94%ae%e5%bc%95%e7%94%a8/feed" rel="self" type="application/rss+xml" />
	<link>https://www.dbainfo.net</link>
	<description>提供Sybase ASE及Sybase SQL Anywhere数据库修复服务，电话：13811580958(微信)，QQ：289965371！We have many years of experience in recovering data from damanged Sybase devices. Contact us by Phone: +86 13811580958 Wechat: 13811580958 Email: 289965371@qq.com</description>
	<lastBuildDate>Sat, 14 Jun 2025 16:28:02 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>迁移ASE数据库的表之间存在引用时脚本执行情况</title>
		<link>https://www.dbainfo.net/imgrate-ase-database-referencial-table-scripts-execute-twice.htm</link>
		<comments>https://www.dbainfo.net/imgrate-ase-database-referencial-table-scripts-execute-twice.htm#comments</comments>
		<pubDate>Sun, 19 Dec 2010 08:14:07 +0000</pubDate>
		<dc:creator>dbainfo</dc:creator>
				<category><![CDATA[Sybase ASE]]></category>
		<category><![CDATA[外键引用]]></category>
		<category><![CDATA[脚本]]></category>

		<guid isPermaLink="false">http://www.dbainfo.net/?p=608</guid>
		<description><![CDATA[迁移ASE数据库的表结构时，需要注意表DDL的顺序，否则有些对象会因为其所引用的对象不存在而导致创建不成功。 解决的方法：将同样的脚本执行两次。 据我所知，sybase central或者ddlgen导出的语法中是没有很好的处理好对象之间的引用先后顺序的，所以，很有可能你的脚本需要执行两次才能保证所有的对象都成功创建上。 下面举个简单的例子，两张表，一张外键引用另一张。 sybase ASE中要求被外键引用的表的被引用列上有唯一约束。 在移植对象DDL的时候，举个例子：表A外键引用表B，如果导出的DLL语句中表A的定义语句在前面，而表B的DDL在后面。那么在创建表A的时候会因为外键引用的表B不存在而导致表A创建不成功。表B是能够成功创建的。 第二次执行上面相同的脚本时，首先会成功创建表A，因为其所引用的表B已经创建上了。而表B不会再次创建因为上次执行的时候已建上，会给出一个错误信息。这在isql是个错误信息，可能在sybase central中会是一个让人讨厌的弹出窗口。 总之，如果数据库内表之间定义了引用关系，那么同样的脚本语句需要执行两边才能成功完成工作。下面举一个外键引用的例子，分两种情况： 不带if exitsts .... drop table ... 带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, &#160; dept_id int not null,constraint fk_students_dept_id foreign [...]]]></description>
			<content:encoded><![CDATA[<p>迁移ASE数据库的表结构时，需要注意表DDL的顺序，否则有些对象会因为其所引用的对象不存在而导致创建不成功。</p>
<p><span style="font-size: 14px;"><strong>解决的方法：</strong></span>将同样的脚本执行两次。</p>
<p>据我所知，sybase central或者ddlgen导出的语法中是没有很好的处理好对象之间的引用先后顺序的，所以，很有可能你的脚本需要执行两次才能保证所有的对象都成功创建上。</p>
<p>下面举个简单的例子，两张表，一张外键引用另一张。</p>
<p><strong>sybase ASE中要求被外键引用的表的被引用列上有唯一约束。<br />
	</strong></p>
<p>在移植对象DDL的时候，举个例子：表A外键引用表B，如果导出的DLL语句中表A的定义语句在前面，而表B的DDL在后面。那么在创建表A的时候会因为外键引用的表B不存在而导致表A创建不成功。表B是能够成功创建的。</p>
<p>	第二次执行上面相同的脚本时，首先会成功创建表A，因为其所引用的表B已经创建上了。而表B不会再次创建因为上次执行的时候已建上，会给出一个错误信息。这在isql是个错误信息，可能在sybase central中会是一个让人讨厌的弹出窗口。<span id="more-608"></span></p>
<p>	总之，如果数据库内表之间定义了引用关系，那么同样的脚本语句需要执行两边才能成功完成工作。下面举一个外键引用的例子，分两种情况：</p>
<ol>
<li>不带if exitsts .... drop table ...</li>
<li>带if exitsts .... drop table ...</li>
</ol>
<p>有两种表：部门信息表dept，学生信息表students，学生表中的部门编号列引用表dept的dept_id列。正常的表定义语法如下：</p>
<blockquote>
<p>use tempdb<br />
		go</p>
<p>create table dept(dept_id int unique not null, dept_name varchar(100) null)<br />
		go<br />
		create table students ( id int not null,name varchar(30) null,<br />
		&nbsp; dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )<br />
		go<br />
		&nbsp;</p>
</blockquote>
<h3>下面的测试假设进行表结构迁移时，用工具导出的表定义语法的顺序不正确。<br />
	第一种情况：不带if exitsts .... drop table ...</h3>
<blockquote>
<p>执行第一遍语句<br />
		1&gt; create table students ( id int not null,name varchar(30) null,<br />
		2&gt;&nbsp;&nbsp; dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )<br />
		3&gt; go<br />
		Msg 1710, Level 16, State 3:<br />
		Server &#39;NMR&#39;, Line 1:<br />
		Referenced table &#39;dept&#39; specified in a referential constraint declared on<br />
		&#39;students&#39; does not exist in the database &#39;tempdb&#39;.<br />
		Msg 2761, Level 16, State 4:<br />
		Server &#39;NMR&#39;, Line 1:<br />
		Failed to create declarative constraints on table &#39;students&#39; in database<br />
		&#39;tempdb&#39;.<br />
		1&gt; create table dept(dept_id int unique not null, dept_name varchar(100) null)<br />
		2&gt; go<br />
		因为学生信息表students没有成功创建，执行第二遍语句，<br />
		1&gt;<br />
		2&gt;<br />
		3&gt;<br />
		4&gt; use tempdb<br />
		5&gt; go<br />
		1&gt; create table students ( id int not null,name varchar(30) null,<br />
		2&gt;&nbsp;&nbsp; dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )<br />
		3&gt; go<br />
		1&gt; create table dept(dept_id int unique not null, dept_name varchar(100) null)<br />
		2&gt; go<br />
		Msg 2714, Level 16, State 1:<br />
		Server &#39;NMR&#39;, Line 1:<br />
		There is already an object named &#39;dept&#39; in the database.<br />
		第二遍执行语句的时候，报部门信息表已经存在的错误。</p>
</blockquote>
<h3>
	第二种情况：带if exitsts .... drop table ...</h3>
<blockquote>
<p>
		执行效果如下：<br />
		1&gt; use tempdb<br />
		2&gt; go<br />
		1&gt; if exists(select 1 from sysobjects where type=&#39;U&#39; and name=&#39;student&#39;)<br />
		2&gt;&nbsp;&nbsp; drop table students<br />
		3&gt; go<br />
		1&gt; create table students ( id int not null,name varchar(30) null,<br />
		2&gt;&nbsp;&nbsp; dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )<br />
		3&gt; go<br />
		Msg 1710, Level 16, State 3:<br />
		Server &#39;NMR&#39;, Line 1:<br />
		Referenced table &#39;dept&#39; specified in a referential constraint declared on<br />
		&#39;students&#39; does not exist in the database &#39;tempdb&#39;.<br />
		Msg 2761, Level 16, State 4:<br />
		Server &#39;NMR&#39;, Line 1:<br />
		Failed to create declarative constraints on table &#39;students&#39; in database<br />
		&#39;tempdb&#39;.<br />
		1&gt;<br />
		2&gt; if exists(select 1 from sysobjects where type=&#39;U&#39; and name=&#39;dept&#39;)<br />
		3&gt;&nbsp;&nbsp;&nbsp;&nbsp; drop table dept<br />
		4&gt; go<br />
		1&gt; create table dept(dept_id int unique not null, dept_name varchar(100) null)<br />
		2&gt; go<br />
		1&gt;<br />
		2&gt;<br />
		3&gt;下面是第二遍执行同样的语句<br />
		4&gt;<br />
		5&gt; use tempdb<br />
		6&gt; go<br />
		1&gt; if exists(select 1 from sysobjects where type=&#39;U&#39; and name=&#39;student&#39;)<br />
		2&gt;&nbsp;&nbsp; drop table students<br />
		3&gt; go<br />
		1&gt; create table students ( id int not null,name varchar(30) null,<br />
		2&gt;&nbsp;&nbsp; dept_id int not null,constraint fk_students_dept_id foreign key(dept_id) references dept(dept_id) )<br />
		3&gt; go<br />
		1&gt;<br />
		2&gt; if exists(select 1 from sysobjects where type=&#39;U&#39; and name=&#39;dept&#39;)<br />
		3&gt;&nbsp;&nbsp;&nbsp;&nbsp; drop table dept<br />
		4&gt; go<br />
		Msg 3712, Level 16, State 1:<br />
		Server &#39;NMR&#39;, Line 3:<br />
		Cannot drop table &#39;dept&#39; because it still has referential integrity<br />
		constraints.<br />
		1&gt; create table dept(dept_id int unique not null, dept_name varchar(100) null)<br />
		2&gt; go<br />
		Msg 2714, Level 16, State 1:<br />
		Server &#39;NMR&#39;, Line 1:<br />
		There is already an object named &#39;dept&#39; in the database.<br />
		第一遍同样students不能成功创建，第二遍dept不能删除，因为存在引用它的表students，继而也不能再次创建。</p>
</blockquote>
<p>
	PS：如果存在表之间的引用，且表之间的顺序不正确的话，需要将脚本执行两便才能保证对象都成功创建上。</p>
<p>	&nbsp;</p>
<div style="clear: both; margin: 10px 0pt; border: 1px dashed rgb(153, 153, 153); font-size: 12px; padding: 5px 10px;">
<li>本文链接地址：<a href="https://www.dbainfo.net/imgrate-ase-database-referencial-table-scripts-execute-twice.htm">https://www.dbainfo.net/imgrate-ase-database-referencial-table-scripts-execute-twice.htm</a>；</li>
<li>本文为dbainfo个人原创，请在尊重作者劳动成果的前提下进行转载；</li>
<li>转载务必注明原始出处 : <a href="https://www.dbainfo.net/">Sybase数据库技术，数据库恢复专家</a>；</li>
<li>对《<a href="https://www.dbainfo.net/imgrate-ase-database-referencial-table-scripts-execute-twice.htm">迁移ASE数据库的表之间存在引用时脚本执行情况</a>》有何疑问或见解，请在本文下方发表；</li>
<li>对网站还有其他问题或建议，请提交在<a href="https://www.dbainfo.net/messages" target="_blank">留言板</a>，谢谢！</li>
</div>
<h2  class="related_post_title">相关文章</h2><ul class="related_post"><li>2010-10-19 -- <a href="https://www.dbainfo.net/database-backup-strategy-delete-n-days-ago-files-for.htm" title="数据库备份策略中删除N天前的备份文件">数据库备份策略中删除N天前的备份文件</a> (0)</li><li>2010-09-12 -- <a href="https://www.dbainfo.net/sybase-ase-auto-create-database-login-user-scripts.htm" title="Sybase ASE自动创建数据库、登录以及用户的脚本">Sybase ASE自动创建数据库、登录以及用户的脚本</a> (0)</li><li>2010-08-11 -- <a href="https://www.dbainfo.net/sybase-ase-auto-backup-shell-scripts-at-unix-linux.htm" title="sybase ASE在unix&#038;linux上的自动备份脚本">sybase ASE在unix&#038;linux上的自动备份脚本</a> (1)</li><li>2009-11-18 -- <a href="https://www.dbainfo.net/script-backup-db-many-times.htm" title="实现连续N次备份数据库的脚本">实现连续N次备份数据库的脚本</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>https://www.dbainfo.net/imgrate-ase-database-referencial-table-scripts-execute-twice.htm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
