【SQL Server DBA】维护语句:删除并创建外键约束、获取建表语句
原文:【SQL Server DBA】维护语句:删除并创建外键约束、获取建表语句
1、删除外键约束,建立外键约束
先建立3个表:
-
/*
-
drop table tb
-
drop table tb_b
-
drop table tb_c
-
*/
-
-
--建立3个关联的表
-
create table tb(id int primary key ,vv varchar(10))
-
-
-
create table tb_b(
-
idd int primary key,
-
id int foreign key references tb(id)
-
)
-
-
create table tb_c(
-
iddd int primary key,
-
idd int foreign key references tb_b(idd)
-
)
-
go
可以生成删除外键的语句,需要复制出来,然后放到再执行:
-
;WITH FK --外键约束
-
AS
-
(
-
SELECT
-
SCH.name as foreign_schema_name, --外键schema名
-
FK.name as foreign_name, --外键名
-
FK.is_disabled , --是否禁用
-
-
FK.delete_referential_action_desc as delete_action,
-
FK.update_referential_action_desc as update_action,
-
-
FKC.constraint_column_id, --约束列的id
-
FKC.parent_object_id, --父对象的id
-
FKC.parent_column_id, --父对象列的id
-
-
-
FKC.referenced_object_id, --被引用的对象
-
FKC.referenced_column_id --被引用的对象中的列
-
FROM sys.foreign_keys FK
-
INNER JOIN sys.foreign_key_columns FKC
-
ON FK.object_id = FKC.constraint_object_id
-
INNER JOIN sys.schemas SCH
-
ON FK.schema_id = SCH.schema_id
-
),
-
-
TB --表和列
-
AS
-
(
-
SELECT
-
TB.object_id,
-
SCH.name as schema_name,
-
TB.name as table_name,
-
C.column_id as column_id,
-
C.name as column_name
-
FROM sys.tables TB WITH(NOLOCK)
-
INNER JOIN sys.columns C WITH(NOLOCK)
-
ON TB.object_id = C.object_id
-
INNER JOIN sys.schemas SCH WITH(NOLOCK)
-
ON TB.schema_id = SCH.schema_id
-
WHERE TB.is_ms_shipped = 0 -- 此条件表示仅查询不是由内部 SQL Server 组件创建对象
-
)
-
-
SELECT
-
'alter table ['+TBP.schema_name+'].['+TBP.table_name+
-
'] drop constraint ['+FK.foreign_name+'];' as '删除外键的语句,复制出来后运行'
-
FROM FK
-
INNER JOIN TB TBP
-
ON FK.parent_object_id = TBP.object_id
-
AND FK.parent_column_id = TBP.column_id
-
-
INNER JOIN TB TBR
-
ON FK.referenced_object_id = TBR.object_id
-
AND FK.referenced_column_id = TBR.column_id
-
/*
-
删除外键的语句,复制出来后运行
-
alter table [dbo].[tb_b] drop constraint [FK__tb_b__id__6754599E];
-
alter table [dbo].[tb_c] drop constraint [FK__tb_c__idd__6C190EBB];
-
*/
另外,删除主键后,插入数据,然后再建立外键:
-
;WITH FK --外键约束
-
AS
-
(
-
SELECT
-
SCH.name as foreign_schema_name, --外键schema名
-
FK.name as foreign_name, --外键名
-
FK.is_disabled , --是否禁用
-
-
FK.delete_referential_action_desc as delete_action,
-
FK.update_referential_action_desc as update_action,
-
-
FKC.constraint_column_id, --约束列的id
-
FKC.parent_object_id, --父对象的id
-
FKC.parent_column_id, --父对象列的id
-
-
-
FKC.referenced_object_id, --被引用的对象
-
FKC.referenced_column_id --被引用的对象中的列
-
FROM sys.foreign_keys FK
-
INNER JOIN sys.foreign_key_columns FKC
-
ON FK.object_id = FKC.constraint_object_id
-
INNER JOIN sys.schemas SCH
-
ON FK.schema_id = SCH.schema_id
-
),
-
-
TB --表和列
-
AS
-
(
-
SELECT
-
TB.object_id,
-
SCH.name as schema_name,
-
TB.name as table_name,
-
C.column_id as column_id,
-
C.name as column_name
-
FROM sys.tables TB WITH(NOLOCK)
-
INNER JOIN sys.columns C WITH(NOLOCK)
-
ON TB.object_id = C.object_id
-
INNER JOIN sys.schemas SCH WITH(NOLOCK)
-
ON TB.schema_id = SCH.schema_id
-
WHERE TB.is_ms_shipped = 0 -- 此条件表示仅查询不是由内部 SQL Server 组件创建对象
-
)
-
-
SELECT
-
'alter table ['+TBP.schema_name+'].['+TBP.table_name+
-
'] add constraint ['+FK.foreign_name+'] '+
-
' foreign key('+TBP.column_name+') references [' +
-
TBR.schema_name +'].['+ TBR.table_name +']('+TBR.column_name+')'
-
as '新建外键索引,复制然后在运行'
-
FROM FK
-
INNER JOIN TB TBP
-
ON FK.parent_object_id = TBP.object_id
-
AND FK.parent_column_id = TBP.column_id
-
-
INNER JOIN TB TBR
-
ON FK.referenced_object_id = TBR.object_id
-
AND FK.referenced_column_id = TBR.column_id
-
/*
-
新建外键索引,复制然后在运行
-
alter table [dbo].[tb_c] add constraint [FK__tb_c__idd__0A9D95DB] foreign key(idd) references [dbo].[tb_b](idd)
-
alter table [dbo].[tb_b] add constraint [FK__tb_b__id__05D8E0BE] foreign key(id) references [dbo].[tb](id)
-
*/
另外,还有一个问题:原来两个表之间是有外键的,删除了外键导入数据后,导入的数据记录条数和原表也一致,发现子表有记录不属于主表的,那么原来的外键是怎么建立的?
-
create table tb(id int primary key ,vv varchar(10))
-
-
insert into tb
-
values(1,'aa')
-
go
-
-
create table tb_b(
-
idd int primary key,
-
id int --foreign key references tb(id)
-
)
-
-
insert into tb_b
-
values(1,2) --id不在主表中
-
go
-
-
--新增外键约束,不会报错,with nocheck对于之前已经存在的数据,不会进行检测
-
ALTER TABLE [dbo].[tb_b] WITH noCHECK ADD FOREIGN KEY([id])
-
REFERENCES [dbo].[tb] ([id])
-
GO
-
-
-
--会报错 ,在建立上面的约束后,再次插入,就会报错了
-
insert into tb_b
-
values(2,2) --id不在主表中
2、如何根据表名查询出创建该表的代码
-
--当用以下代码创建一个表后,如何根据表名查询出创建该表的代码(也就是以下代码)?
-
CREATE TABLE [dbo].[a1](
-
[c2] [decimal](10, 2) NULL,
-
[c3] [decimal](10, 3) NULL CONSTRAINT [DF_a1_c3] DEFAULT ((0)),
-
[re] [bigint] IDENTITY(1,1) NOT NULL,
-
CONSTRAINT [PK_a1] PRIMARY KEY CLUSTERED
-
(
-
[re] ASC
-
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
-
) ON [PRIMARY]
-
go
-
declare @sql varchar(8000),@tablename varchar(100)
-
set @tablename ='a1'--这里输入表名
-
set @sql = 'create table ['+@tablename+']
-
(
-
'
-
select @sql = @sql + b.name + ' '+
-
c.name+
-
case when c.collation_name is not null then '('+
-
case when b.max_length <>-1 then convert(varchar(100),b.max_length)
-
else 'MAX'
-
end +') '
-
else ''
-
end +
-
case when b.is_identity = 1 then ' identity('+convert(varchar(100),IDENT_SEED(@tablename))+','+convert(varchar(100),IDENT_INCR(@tablename))+')' else '' end +
-
case when d.definition is not null then ' default('+d.definition +')' else '' end +
-
case when b.is_nullable = 0 then ' not null' else ' null' end +
-
-
',
-
'
-
from sys.objects a join sys.columns b
-
on a.object_id = b.object_id
-
join sys.types c
-
on b.system_type_id = c.system_type_id and b.user_type_id = c.user_type_id
-
left join sys.default_constraints d
-
on b.default_object_id = d.object_id
-
where a.name=@tablename
-
order by b.column_id
-
if exists(select * from sys.indexes where object_id =object_id(@tablename) and is_primary_key =1 )
-
begin
-
select @sql = @sql + 'CONSTRAINT ['+name+'] PRIMARY KEY '+type_desc+'
-
(
-
' from sys.indexes where object_id =object_id(@tablename) and is_primary_key =1
-
select @sql = @sql + b.name + case when a.is_descending_key =1 then ' DESC' else ' ASC' end +',
-
' from sys.index_columns a join sys.columns b
-
on a.object_id= b.object_id and a.column_id = b.column_id
-
where a.object_id =object_id(@tablename)
-
select @sql = left(@sql,len(@sql)-3)+'
-
)'
-
select @sql = @sql+'
-
) ON [PRIMARY] '
-
end
-
else
-
begin
-
select @sql = left(@sql,len(@sql)-1)+'
-
) ON [PRIMARY] '
-
end
-
print @sql
-
-
/*
-
create table [a1]
-
(
-
c2 decimal null,
-
c3 decimal default(((0))) null,
-
re bigint identity(1,1) not null,
-
CONSTRAINT [PK_a1] PRIMARY KEY CLUSTERED
-
(
-
re ASC
-
)
-
) ON [PRIMARY]
-
-
*/
【SQL Server DBA】维护语句:删除并创建外键约束、获取建表语句的更多相关文章
- sql server drop talbe 自动删除关联的外键 ,权限体系(二)
alter table dbo.Sys_PowerTeamForUser add constraint FK_Sys_User_Sys_PowerTeamForUser foreign key (Sy ...
- sql server drop talbe 自动删除关联的外键 ,权限体系(一)
if object_id('Proc_DropTableWithFK') is not null begin drop proc dbo.Proc_DropTableWithFK end GO ) a ...
- sql操作数据库(3)-->外键约束、数据库表之间的关系、三大范式、多表查询、事务
外键约束 在新表中添加外键约束语法: constraint 外键约束名称 foreign key(外键的字段名称) references 主表表名(主键字段名) 在已有表中添加外键约束:alter t ...
- SQL-46 在audit表上创建外键约束,其emp_no对应employees_test表的主键id。
题目描述 在audit表上创建外键约束,其emp_no对应employees_test表的主键id.CREATE TABLE employees_test(ID INT PRIMARY KEY NOT ...
- C# 如何物理删除有主外键约束的记录?存储过程实现
十年河东,十年河西,莫欺少年穷 本篇主旨是如何物理删除有主外键约束的记录!那么,我们从主外键走起! 下面新建三张有主外键约束的表,分别为:系/学院表,专业班表,学生表,如下: CREATE TABLE ...
- SQL语句删除和添加外键、主键的方法
--删除外键 语法:alter table 表名 drop constraint 外键约束名 如: alter table Stu_PkFk_Sc drop constraint FK_s alter ...
- 【转】SQL语句删除和添加外键、主键
--删除外键 语法:alter table 表名 drop constraint 外键约束名 如: alter table Stu_PkFk_Sc drop constraint FK_s alter ...
- MySQL数据库 : 查询语句,连接查询及外键约束
查询指定字段 select 字段1,字段2 from 表名; 消除重复行(重复指的是结果集中的所有完全重复行) select distinct 字段1,字段2.. ...
- MySQL创建外键约束的报错Error : Can't create table '#sql-534_185' (errno: 150)
总得来说是因为两个表的字段类型不一致,例如: 两个字段的类型或大小不严格匹配,一个为tinyint,另一个为char:或一个为int(10)另一个为int(9)也是不行的,即使都为int(10),但一 ...
随机推荐
- 回声消除(AEC)原理
一.前言 因为工作的关系,笔者从2004年开始接触回声消除(Echo Cancellation)技术,而后一直在某大型通讯企业从事与回声消除技术相关的工作,对回声消除这个看似神秘.高端和难以理解的技术 ...
- zabbix使用fping监控任意两个节点之间的网络质量、丢包率和响应时间
zabbix使用fping监控任意两个节点之间的网络质量.丢包率和响应时间 之前的博文 使用zabbix3..4的ICMP Ping模版实现对客户端网络状态的监控 https://www.cnblog ...
- Shell中 2>/dev/null
1.文件描述符 Linux系统预留可三个文件描述符:0.1和2,他们的意义如下所示: 0——标准输入(stdin) 1——标准输出(stdout) 2——标准错误(stderr) 标准输出——stdo ...
- Apache使用内置插件mod_php解析php的配置
apache安装完毕之后,修改httpd.conf配置文件,添加代码如下: LoadModule php5_module modules/libphp5.so <FilesMatch \.php ...
- ubuntu18.04手动安装二进制MySQL8.0
wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.13-linux-glibc2.12-x86_64.tar.xz tar xvJf ...
- css代码陷阱
1.选择器优先级 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- JS正则验证6位数字组成,验证纯中文组成
常见的简单规则还有6位数字组成的密码,如果想要6位数字以上,第二个参数可以不设置.验证是否是纯中文,可以用Unicode字符区间,在网上找到了验证中文的表达式,然后查了查看Unicode编码的表格,这 ...
- mssql的update :from语法
一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新.而表的更新操作中,在很多情况下需要在表达式中引用要更新的表以外的数据.我们先来讨论根据其他表数据更新你要更新的表 一.MS S ...
- mysql大小写敏感配置
mysql大小写敏感配置show global variables like '%lower_case%'; show global variables like '%lower_case%'; &l ...
- Java创建线程的两种方法
大多数情况,通过实例化一个Thread对象来创建一个线程.Java定义了两种方式: 实现Runnable 接口: 可以继承Thread类. 下面的两小节依次介绍了每一种方式. 实现Runnable接口 ...
