truncate table 遇到的外键被使用问题解决方案。
2010-10-23 00:08
429 查看
在asp.net中操纵数据库,有时候要清空某张或者某些的表,但是这些表使用了外键,而且有的还用到了自增字段,希望清空之后能从1开始。百度谷歌之后小结一下,为以后理解和重复使用保留材料。
解决方案一:
1. 清空数据
2. 有外键也可以, 因为是逆向删除, 从最后一张表删除. 且使用的是delete, 因为truncate不能对有外键的表
3. 种子问题, 如果表存在种子重设为0, 如不存在就不操作
4. 加了事务, 中间报错, 有后悔机会
5. 截断日志功能, 因为使用delete, 删除后日志文件会增大, 可以不使用
以上代码只要在select rtrim(name) from sysobjects where type = 'U' order by crdate desc中添加过滤条件即可过滤一些表,我是改成,where type = 'U' and rtrim(name) in('IPControl','Student','Teacher_Course','Score','Paper','PaperDetail') order by crdate desc 这样使得in里面的表被清空,而数据库中其他表内容被保留下来。
==============================
在ASP.net中要直接使用这段代码会出问题,我猜想主要原因在于go这个词上。
解决方法就是将这一大片的代码分为若干个sql语句,然后顺次执行。另外,个人觉得也无需将所有的语句段都复制使用,选择自己需要的就可以了。
=============================
解决方案二:
都看不太懂,但是都挺有用的。以后如果有进步,再回头来好好理解。这当中也有一个对表进行过滤的地方,@command1= 'truncate table ?', @whereand=' and name not in(''Users'')' 我就设置了一个name not in(''Users'')' ,结果运行之后只有Users表被保留下来,其他全部被清空。
解决方案一:
1. 清空数据
2. 有外键也可以, 因为是逆向删除, 从最后一张表删除. 且使用的是delete, 因为truncate不能对有外键的表
3. 种子问题, 如果表存在种子重设为0, 如不存在就不操作
4. 加了事务, 中间报错, 有后悔机会
5. 截断日志功能, 因为使用delete, 删除后日志文件会增大, 可以不使用
if( object_id('pr_DataClear') is not null ) drop procedure pr_DataClear go create procedure pr_DataClear as begin transaction declare @cTblName varchar(128) declare cur_Clear cursor for select rtrim(name) from sysobjects where type = 'U' order by crdate desc open cur_Clear declare @cSQL varchar(255) fetch next from cur_Clear into @cTblName while( @@fetch_status = 0) begin set @cSQL = 'delete from ' + @cTblName print @cSQL exec( @cSQL ) if( ident_seed(@cTblName) is not null ) begin dbcc checkident( @cTblName, reseed, 0 ) print '有种子且成功重置为1' end fetch next from cur_Clear into @cTblName end close cur_Clear deallocate cur_Clear commit go -- 清空所有表数据 exec pr_DataClear -- 截断日志 backup log LZ的数据库 with no_log dbcc shrinkdatabase( LZ的数据库 ) dbcc updateusage( LZ的数据库 ) -- 查看表空间(概数) select object_name(id) as 表名, (rtrim(8*reserved/1024) + 'MB') as 总量, (rtrim(8*dpages/1024) + 'MB') as 已使用, (rtrim(8*(reserved-dpages)/1024) + 'MB') as 未使用, (rtrim(8*dpages/1024-rows/1024*minlen/1024) + 'MB' ) as 空隙 from sysindexes where indid=1 order by reserved desc
以上代码只要在select rtrim(name) from sysobjects where type = 'U' order by crdate desc中添加过滤条件即可过滤一些表,我是改成,where type = 'U' and rtrim(name) in('IPControl','Student','Teacher_Course','Score','Paper','PaperDetail') order by crdate desc 这样使得in里面的表被清空,而数据库中其他表内容被保留下来。
==============================
在ASP.net中要直接使用这段代码会出问题,我猜想主要原因在于go这个词上。
解决方法就是将这一大片的代码分为若干个sql语句,然后顺次执行。另外,个人觉得也无需将所有的语句段都复制使用,选择自己需要的就可以了。
=============================
解决方案二:
declare @name varchar(200),@tmp1 varchar(500),@tmp2 varchar(500) create table #tmp ( string varchar(8000) ) SELECT 表名称=object_name(b.fkeyid) ,外键名称=a.name ,引用的列名=(SELECT name FROM syscolumns WHERE colid=b.fkey AND id=b.fkeyid) ,引用的表名=object_name(b.rkeyid) ,已引用的列名=(SELECT name FROM syscolumns WHERE colid=b.rkey AND id=b.rkeyid) into #t FROM sysobjects a join sysforeignkeys b on a.id=b.constid join sysobjects c on a.parent_obj=c.id where a.xtype='f' AND c.xtype='U' declare cur_test cursor for select a.name from sysobjects a join sysobjects c on a.parent_obj=c.id where a.xtype='f' and c.xtype='U' open cur_test FETCH NEXT FROM cur_test INTO @name WHILE (@@fetch_status <> -1) BEGIN IF (@@fetch_status <> -2) BEGIN select @tmp1='',@tmp2='' select @tmp1=@tmp1+'['+引用的列名+'],',@tmp2=@tmp2+'['+已引用的列名+'],' from #t where 外键名称=@name insert into #tmp select top 1 'ALTER TABLE [DBO].['+表名称+'] ADD CONSTRAINT ['+@name+'] FOREIGN KEY ( '+left(@tmp1,len(@tmp1)-1)+' ) REFERENCES ['+引用的表名+'] ( '+left(@tmp2,len(@tmp2)-1)+' )' from #t where 外键名称=@name END FETCH NEXT FROM cur_test INTO @name END CLOSE cur_test DEALLOCATE cur_test drop table #t DECLARE @STRING VARCHAR(8000) WHILE EXISTS(SELECT NAME FROM SYSOBJECTS WHERE TYPE='F') BEGIN SELECT @STRING='ALTER TABLE '+<mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js"></mce:script><mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js"></mce:script>B.NAME+' DROP CONSTRAINT '+A.NAME+CHAR(13) FROM (SELECT PARENT_OBJ,NAME FROM SYSOBJECTS WHERE TYPE='F') A, (SELECT ID,NAME FROM SYSOBJECTS WHERE OBJECTPROPERTY(ID, N'ISUSERTABLE') = 1) B WHERE A.PARENT_OBJ=B.ID EXEC(@STRING) END exec sp_msforeachtable @command1= 'truncate table ?', @whereand=' and name not in(''Users''<mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/themes/advanced/langs/zh.js"></mce:script><mce:script type="text/javascript" src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js" mce_src="http://hi.images.csdn.net/js/blog/tiny_mce/plugins/syntaxhl/langs/zh.js"></mce:script>)' declare cur_test2 cursor for select string from #tmp open cur_test2 FETCH NEXT FROM cur_test2 INTO @string WHILE (@@fetch_status <> -1) BEGIN IF (@@fetch_status <> -2) BEGIN exec(@string) PRINT @STRING END FETCH NEXT FROM cur_test2 INTO @string END CLOSE cur_test2 DEALLOCATE cur_test2 drop table #tmp
都看不太懂,但是都挺有用的。以后如果有进步,再回头来好好理解。这当中也有一个对表进行过滤的地方,@command1= 'truncate table ?', @whereand=' and name not in(''Users'')' 我就设置了一个name not in(''Users'')' ,结果运行之后只有Users表被保留下来,其他全部被清空。
相关文章推荐
- Dynamics CRM-Word Template Feature 的使用和实际遇到问题解决方案
- 初学Flex,在使用Webservice时遇到Xml数据绑定的一个问题,试了N个方案,均没解决。
- jaxb 使用遇到的问题解决的方案
- 在使用 Spring Boot 和 MyBatis 动态切换数据源时遇到的问题以及解决方法
- 使用Navicat Premium将Oracle数据库中的表和数据迁移到MySQL数据库中,遇到的Date类型出现精度问题及解决方法
- Git使用遇到的问题--merge冲突解决
- 使用innobackupex备份遇到的问题和解决方法
- Linux上使用Tomcat遇到的难以解决的问题
- vue 2.0中使用axios遇到问题的解决方法
- Windows下使用python-nmap库可能遇到的问题及解决方法(续)
- 使用pbrt 1.03遇到的问题和解决方法
- linux使用过程中遇到的问题和解决方法
- 使用osg中遇到osg::PositionAttitudeTransform的c2512问题的解决
- 使用GridView时遇到的一些小问题及解决方法
- 在使用vue-router遇到的问题以及解决办法
- 在使用BizTalk时遇到一个很郁闷的问题 之解决篇
- MFC--不允许使用继承成员问题解决方案(待补充)
- jQuery使用时遇到的一些问题和解决方法
- 使用Postgresql遇到的一些问题和解决办法
- 使用Orientation Changed Notification遇到的问题及解决办法