原文:【SQL Server DBA】维护语句:删除并创建外键约束、获取建表语句


1、删除外键约束,建立外键约束

先建立3个表:


  1. /*
  2. drop table tb
  3. drop table tb_b
  4. drop table tb_c
  5. */
  6. --建立3个关联的表
  7. create table tb(id int primary key ,vv varchar(10))
  8. create table tb_b(
  9. idd int primary key,
  10. id int foreign key references tb(id)
  11. )
  12. create table tb_c(
  13. iddd int primary key,
  14. idd int foreign key references tb_b(idd)
  15. )
  16. go

可以生成删除外键的语句,需要复制出来,然后放到再执行:


  1. ;WITH FK --外键约束
  2. AS
  3. (
  4. SELECT
  5. SCH.name as foreign_schema_name, --外键schema名
  6. FK.name as foreign_name, --外键名
  7. FK.is_disabled , --是否禁用
  8. FK.delete_referential_action_desc as delete_action,
  9. FK.update_referential_action_desc as update_action,
  10. FKC.constraint_column_id, --约束列的id
  11. FKC.parent_object_id, --父对象的id
  12. FKC.parent_column_id, --父对象列的id
  13. FKC.referenced_object_id, --被引用的对象
  14. FKC.referenced_column_id --被引用的对象中的列
  15. FROM sys.foreign_keys FK
  16. INNER JOIN sys.foreign_key_columns FKC
  17. ON FK.object_id = FKC.constraint_object_id
  18. INNER JOIN sys.schemas SCH
  19. ON FK.schema_id = SCH.schema_id
  20. ),
  21. TB --表和列
  22. AS
  23. (
  24. SELECT
  25. TB.object_id,
  26. SCH.name as schema_name,
  27. TB.name as table_name,
  28. C.column_id as column_id,
  29. C.name as column_name
  30. FROM sys.tables TB WITH(NOLOCK)
  31. INNER JOIN sys.columns C WITH(NOLOCK)
  32. ON TB.object_id = C.object_id
  33. INNER JOIN sys.schemas SCH WITH(NOLOCK)
  34. ON TB.schema_id = SCH.schema_id
  35. WHERE TB.is_ms_shipped = 0 -- 此条件表示仅查询不是由内部 SQL Server 组件创建对象
  36. )
  37. SELECT
  38. 'alter table ['+TBP.schema_name+'].['+TBP.table_name+
  39. '] drop constraint ['+FK.foreign_name+'];' as '删除外键的语句,复制出来后运行'
  40. FROM FK
  41. INNER JOIN TB TBP
  42. ON FK.parent_object_id = TBP.object_id
  43. AND FK.parent_column_id = TBP.column_id
  44. INNER JOIN TB TBR
  45. ON FK.referenced_object_id = TBR.object_id
  46. AND FK.referenced_column_id = TBR.column_id
  47. /*
  48. 删除外键的语句,复制出来后运行
  49. alter table [dbo].[tb_b] drop constraint [FK__tb_b__id__6754599E];
  50. alter table [dbo].[tb_c] drop constraint [FK__tb_c__idd__6C190EBB];
  51. */

另外,删除主键后,插入数据,然后再建立外键:


  1. ;WITH FK --外键约束
  2. AS
  3. (
  4. SELECT
  5. SCH.name as foreign_schema_name, --外键schema名
  6. FK.name as foreign_name, --外键名
  7. FK.is_disabled , --是否禁用
  8. FK.delete_referential_action_desc as delete_action,
  9. FK.update_referential_action_desc as update_action,
  10. FKC.constraint_column_id, --约束列的id
  11. FKC.parent_object_id, --父对象的id
  12. FKC.parent_column_id, --父对象列的id
  13. FKC.referenced_object_id, --被引用的对象
  14. FKC.referenced_column_id --被引用的对象中的列
  15. FROM sys.foreign_keys FK
  16. INNER JOIN sys.foreign_key_columns FKC
  17. ON FK.object_id = FKC.constraint_object_id
  18. INNER JOIN sys.schemas SCH
  19. ON FK.schema_id = SCH.schema_id
  20. ),
  21. TB --表和列
  22. AS
  23. (
  24. SELECT
  25. TB.object_id,
  26. SCH.name as schema_name,
  27. TB.name as table_name,
  28. C.column_id as column_id,
  29. C.name as column_name
  30. FROM sys.tables TB WITH(NOLOCK)
  31. INNER JOIN sys.columns C WITH(NOLOCK)
  32. ON TB.object_id = C.object_id
  33. INNER JOIN sys.schemas SCH WITH(NOLOCK)
  34. ON TB.schema_id = SCH.schema_id
  35. WHERE TB.is_ms_shipped = 0 -- 此条件表示仅查询不是由内部 SQL Server 组件创建对象
  36. )
  37. SELECT
  38. 'alter table ['+TBP.schema_name+'].['+TBP.table_name+
  39. '] add constraint ['+FK.foreign_name+'] '+
  40. ' foreign key('+TBP.column_name+') references [' +
  41. TBR.schema_name +'].['+ TBR.table_name +']('+TBR.column_name+')'
  42. as '新建外键索引,复制然后在运行'
  43. FROM FK
  44. INNER JOIN TB TBP
  45. ON FK.parent_object_id = TBP.object_id
  46. AND FK.parent_column_id = TBP.column_id
  47. INNER JOIN TB TBR
  48. ON FK.referenced_object_id = TBR.object_id
  49. AND FK.referenced_column_id = TBR.column_id
  50. /*
  51. 新建外键索引,复制然后在运行
  52. alter table [dbo].[tb_c] add constraint [FK__tb_c__idd__0A9D95DB] foreign key(idd) references [dbo].[tb_b](idd)
  53. alter table [dbo].[tb_b] add constraint [FK__tb_b__id__05D8E0BE] foreign key(id) references [dbo].[tb](id)
  54. */

另外,还有一个问题:原来两个表之间是有外键的,删除了外键导入数据后,导入的数据记录条数和原表也一致,发现子表有记录不属于主表的,那么原来的外键是怎么建立的?


  1. create table tb(id int primary key ,vv varchar(10))
  2. insert into tb
  3. values(1,'aa')
  4. go
  5. create table tb_b(
  6. idd int primary key,
  7. id int --foreign key references tb(id)
  8. )
  9. insert into tb_b
  10. values(1,2) --id不在主表中
  11. go
  12. --新增外键约束,不会报错,with nocheck对于之前已经存在的数据,不会进行检测
  13. ALTER TABLE [dbo].[tb_b] WITH noCHECK ADD FOREIGN KEY([id])
  14. REFERENCES [dbo].[tb] ([id])
  15. GO
  16. --会报错 ,在建立上面的约束后,再次插入,就会报错了
  17. insert into tb_b
  18. values(2,2) --id不在主表中

2、如何根据表名查询出创建该表的代码


  1. --当用以下代码创建一个表后,如何根据表名查询出创建该表的代码(也就是以下代码)?
  2. CREATE TABLE [dbo].[a1](
  3. [c2] [decimal](10, 2) NULL,
  4. [c3] [decimal](10, 3) NULL CONSTRAINT [DF_a1_c3] DEFAULT ((0)),
  5. [re] [bigint] IDENTITY(1,1) NOT NULL,
  6. CONSTRAINT [PK_a1] PRIMARY KEY CLUSTERED
  7. (
  8. [re] ASC
  9. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  10. ) ON [PRIMARY]
  11. go


  1. declare @sql varchar(8000),@tablename varchar(100)
  2. set @tablename ='a1'--这里输入表名
  3. set @sql = 'create table ['+@tablename+']
  4. (
  5. '
  6. select @sql = @sql + b.name + ' '+
  7. c.name+
  8. case when c.collation_name is not null then '('+
  9. case when b.max_length <>-1 then convert(varchar(100),b.max_length)
  10. else 'MAX'
  11. end +') '
  12. else ''
  13. end +
  14. case when b.is_identity = 1 then ' identity('+convert(varchar(100),IDENT_SEED(@tablename))+','+convert(varchar(100),IDENT_INCR(@tablename))+')' else '' end +
  15. case when d.definition is not null then ' default('+d.definition +')' else '' end +
  16. case when b.is_nullable = 0 then ' not null' else ' null' end +
  17. ',
  18. '
  19. from sys.objects a join sys.columns b
  20. on a.object_id = b.object_id
  21. join sys.types c
  22. on b.system_type_id = c.system_type_id and b.user_type_id = c.user_type_id
  23. left join sys.default_constraints d
  24. on b.default_object_id = d.object_id
  25. where a.name=@tablename
  26. order by b.column_id
  27. if exists(select * from sys.indexes where object_id =object_id(@tablename) and is_primary_key =1 )
  28. begin
  29. select @sql = @sql + 'CONSTRAINT ['+name+'] PRIMARY KEY '+type_desc+'
  30. (
  31. ' from sys.indexes where object_id =object_id(@tablename) and is_primary_key =1
  32. select @sql = @sql + b.name + case when a.is_descending_key =1 then ' DESC' else ' ASC' end +',
  33. ' from sys.index_columns a join sys.columns b
  34. on a.object_id= b.object_id and a.column_id = b.column_id
  35. where a.object_id =object_id(@tablename)
  36. select @sql = left(@sql,len(@sql)-3)+'
  37. )'
  38. select @sql = @sql+'
  39. ) ON [PRIMARY] '
  40. end
  41. else
  42. begin
  43. select @sql = left(@sql,len(@sql)-1)+'
  44. ) ON [PRIMARY] '
  45. end
  46. print @sql
  47. /*
  48. create table [a1]
  49. (
  50. c2 decimal null,
  51. c3 decimal default(((0))) null,
  52. re bigint identity(1,1) not null,
  53. CONSTRAINT [PK_a1] PRIMARY KEY CLUSTERED
  54. (
  55. re ASC
  56. )
  57. ) ON [PRIMARY]
  58. */

发布了416 篇原创文章 · 获赞 135 · 访问量 94万+

【SQL Server DBA】维护语句:删除并创建外键约束、获取建表语句的更多相关文章

  1. sql server drop talbe 自动删除关联的外键 ,权限体系(二)

    alter table dbo.Sys_PowerTeamForUser add constraint FK_Sys_User_Sys_PowerTeamForUser foreign key (Sy ...

  2. sql server drop talbe 自动删除关联的外键 ,权限体系(一)

    if object_id('Proc_DropTableWithFK') is not null begin drop proc dbo.Proc_DropTableWithFK end GO ) a ...

  3. sql操作数据库(3)-->外键约束、数据库表之间的关系、三大范式、多表查询、事务

    外键约束 在新表中添加外键约束语法: constraint 外键约束名称 foreign key(外键的字段名称) references 主表表名(主键字段名) 在已有表中添加外键约束:alter t ...

  4. SQL-46 在audit表上创建外键约束,其emp_no对应employees_test表的主键id。

    题目描述 在audit表上创建外键约束,其emp_no对应employees_test表的主键id.CREATE TABLE employees_test(ID INT PRIMARY KEY NOT ...

  5. C# 如何物理删除有主外键约束的记录?存储过程实现

    十年河东,十年河西,莫欺少年穷 本篇主旨是如何物理删除有主外键约束的记录!那么,我们从主外键走起! 下面新建三张有主外键约束的表,分别为:系/学院表,专业班表,学生表,如下: CREATE TABLE ...

  6. SQL语句删除和添加外键、主键的方法

    --删除外键 语法:alter table 表名 drop constraint 外键约束名 如: alter table Stu_PkFk_Sc drop constraint FK_s alter ...

  7. 【转】SQL语句删除和添加外键、主键

    --删除外键 语法:alter table 表名 drop constraint 外键约束名 如: alter table Stu_PkFk_Sc drop constraint FK_s alter ...

  8. MySQL数据库 : 查询语句,连接查询及外键约束

    查询指定字段        select 字段1,字段2 from 表名; 消除重复行(重复指的是结果集中的所有完全重复行)             select distinct 字段1,字段2.. ...

  9. MySQL创建外键约束的报错Error : Can't create table '#sql-534_185' (errno: 150)

    总得来说是因为两个表的字段类型不一致,例如: 两个字段的类型或大小不严格匹配,一个为tinyint,另一个为char:或一个为int(10)另一个为int(9)也是不行的,即使都为int(10),但一 ...

随机推荐

  1. ArcPy地理处理工具案例教程—批量添加栅格数据

    ArcPy地理处理工具案例教程-批量添加栅格数据 商务合作,科技咨询,版权转让:向日葵,135-4855__4328,xiexiaokui#qq.com 关键字: Arcpy,python,地理处理工 ...

  2. python 设计模式之单例模式 Singleton Pattern

    #引入 一个类被设计出来,就意味着它具有某种行为(方法),属性(成员变量).一般情况下,当我们想使用这个类时,会使用new 关键字,这时候jvm会帮我们构造一个该类的实例.这么做会比较耗费资源. 如果 ...

  3. 文章后面的QA或FAQ

    QA:question&answer FAQ: Frequently Asked Questions的缩写,中文意思就是“经常问到的问题”

  4. C#nameof用法

    1.实现代码 using System; namespace NameofUsage { /// <summary> /// C# nameof用法 /// </summary> ...

  5. 使用log4j将日志输送到控制台、文件或数据库中

    转: 使用log4j将日志输送到控制台.文件或数据库中 2018-09-07 00:45:08 keep@ 阅读数 2880更多 分类专栏: 其它   版权声明:本文为博主原创文章,遵循CC 4.0 ...

  6. 深入学习c++--容器

    1. 简介 1. 序列式容器: array, vector, deque, list, forward_list --- 数组 或者 指针实现 2. 关联容器: set, map, multiset, ...

  7. Qt bug

    1.Qt5.2.1不支持QQuickwidget来承载qml 2.Qt5.12以及以上,不支持跨线程调用数据库连接 3.线程A不断产生sql语句,需要让两个数据库分别执行这个sql语句.所以在线程A中 ...

  8. Flink 实现指定时长或消息条数的触发器

    Flink 中窗口是很重要的一个功能,而窗口又经常配合触发器一起使用. Flink 自带的触发器大概有: CountTrigger: 指定条数触发 ContinuousEventTimeTrigger ...

  9. 【Leetcode_easy】1042. Flower Planting With No Adjacent

    problem 1042. Flower Planting With No Adjacent 参考 1. Leetcode_easy_1042. Flower Planting With No Adj ...

  10. swift 导入第三方库

    现在的项目也是做了几个,每个都会导入几个优秀的第三方…… 这里写下导入的步骤,方便查询:::: 1.手动导入 首先要知道,是需要文件,还是框架 比如 Alamofire.SnapKit,都需要导入框架 ...