所以我有两个表的数据库。并且它们之间有外键关系。我想做一些测试,但桌子太大了。我想删除这些表中的大部分数据,只在第一个表中保留大约 500 行,在第二个表中保留相关行,这样测试会更快。我怎样才能做到这一点?
我正在对我们的开发数据库进行干净的备份,以便轻松地重新启动数据库。该数据库有大约 200 个测试用户,应该将其删除以使其真正干净,但问题是我无法删除其中任何一个。
当我运行如下命令时:
DROP USER [MyGarbageUser]
Run Code Online (Sandbox Code Playgroud)
它提示我以下错误:
消息 15284,级别 16,状态 1,第 5 行 数据库主体已授予或拒绝对数据库中的对象的权限,无法删除。
这些用户既不拥有该数据库中的任何对象(据我所知),也不应该拥有。在网上搜索了一大堆后,我仍然无法找到解决方案。
如何强制从该数据库中删除 MyGarbageUser?
我需要删除所有三个表中 UserIndex = 1 和 ItemNumber = 5202 的记录,所有这些记录都在单个查询中。我正在使用 SQL 2008 R2。
表用户信息1
| 用户索引 | 项目编号 | 项目计数 |
|---|---|---|
| 1 | 5202 | 99 |
| 1 | 1600 | 50 |
| 2 | 155 | 2 |
| 3 | 125 | 60 |
表用户信息2
| 用户索引 | 项目编号 | 项目计数 |
|---|---|---|
| 8 | 1265 | 50 |
| 4 | 1899 | 41 |
| 1 | 5202 | 99 |
| 3 | 125 | 60 |
表用户信息3
| 用户索引 | 项目编号 | 项目计数 |
|---|---|---|
| 6 | 5205 | 85 |
| 1 | 6666 | 41 |
| 3 | 4455 | 44 |
| 1 | 5202 | 50 |
我尝试将此查询与两个表一起使用,但它不起作用:
DELETE ItemInfo1, ItemInfo2
FROM ItemInfo1
LEFT JOIN ItemInfo2
ON ItemInfo1.UserIndex = ItemInfo2.UserIndex
WHERE ItemInfo1.UserIndex = 1;
Run Code Online (Sandbox Code Playgroud) 假设我的表名 Company 有两列 cname, location。
在表中,我有两条记录
cname |位置
Asmetric |达拉斯
Sophore |华盛顿
当我执行删除操作时在这张表上
delete company where cname='Sophore';
Run Code Online (Sandbox Code Playgroud)
我收到一个错误
Error 1064:You have an error in sql syntax check the manual that corresponds to your sql server version
而我原以为完整的记录会被删除,是语法错误还是不完整。欢迎提出任何建议
DELETE我的生产 SQL 服务器中的查询导致死锁。我知道 DELETE 导致了这种情况,因为我检查了扩展事件并检查了死锁 XML 并发现此 DELETE 正在阻塞,这最终导致死锁。
所以DELETE是发生在两个表格,TB1和TB2。tb1 的主键在 tb2 中可用作外键,并CASCADE DELETE在 tb2 外键中使用。
我什Allow Page Locks至FALSE在 tb1 和 tb2 中创建了聚集索引,但仍然没有运气。
我想READ COMMITTED SNAPSHOT在我的数据库中尝试之前尝试所有其他选项。
任何帮助将不胜感激。
附加信息:
使用READ COMMITTED SNAPSHOT也是一个挑战,因为它涉及风险。
这是 XDL
<deadlock>
<victim-list>
<victimProcess id="process257a65d6ca8" />
</victim-list>
<process-list>
<process id="process257a65d6ca8" taskpriority="0" logused="6024" waitresource="KEY: 6:72057794784329728 (bb7a6e52eae1)" waittime="4485" ownerId="45816472292" transactionname="user_transaction" lasttranstarted="2019-01-08T11:30:06.837" XDES="0x24883ec2a70" lockMode="RangeS-U" schedulerid="26" kpid="39320" status="suspended" spid="217" sbid="2" …Run Code Online (Sandbox Code Playgroud) 在我正在处理的数据库中,有一个名为 的表,persons大约有一百万行,并且来自其他表(有些有数百万行)的 60 个 FK (FK) 约束指向它。
如果我从 中删除一行persons,则需要很多分钟,这不会是问题,但它也会使表保持锁定,从而阻止数据库的所有进程。过去,这曾导致用户报告系统宕机。
当然,如果我为所有的FK添加支持索引的话,情况会大大改善(目前60张表中只有20张有)。但是这些FK很多都是针对诸如 之类的列modified_by,因此所有索引都没有其他目的,并且会在日常操作中降低系统的性能,只有在特殊情况下才能获得改进。
在运行 DELETE 之前,我已经确保所有引用行都已被删除或更新。我手动执行此操作,因为我强烈反对使用 CASCADE。
我没有考虑软删除,因为否则我将不得不更改读取表persons以跳过已删除行的所有软件。
有没有办法(可能是暂时的)更改表的锁定机制persons,以便即使 DELETE 需要一个小时,也不会影响并发进程?
禁用 FK 可能是一种可能。风险在于,当我删除该行时,其他人会造成不一致,然后我无法重新启用 FK。
要删除的行:通常一次删除一行。手动操作或计划操作。
有趣的一点:我没有立即检查执行计划,但显然,除了引用表的 PK 上的 7 例“聚集索引扫描(Clustered)”之外,几乎所有操作的成本都是 0%;其中一种费用为 57%,另一种费用为 1% 至 16%。我仍然不明白为什么它应该扫描聚集索引。
假设我有两张表,一张名为ParentTable,另一张名为ChildTable,具有一对多关系,其中一个父项可能有多个子项。
我正在创建一个AFTER DELETE触发器ChildTable。在该触发器中,我正在检查一个值ParentTable(如果存在),如下所示:
-- ...
FROM deleted d
JOIN ParentTable pt ON d.FK_Parent = pt.ID
WHERE pt.Foo = 'bar'
Run Code Online (Sandbox Code Playgroud)
如果我先从 删除ChildTable,然后从 删除ParentTable,AFTER DELETE触发器是在删除行之前还是之后ParentTable触发?
A。这两个DELETE语句通常位于显式事务中,因为我使用的是实体框架。
如果我将外键设置为ChildTable,CASCADE DELETE然后从ParentTableonly 中删除,当触发器触发时,中的行ParentTable仍然可以访问吗AFTER DELETE?
之后我需要日志文件做什么?
我特别在谈论“高度控制”的环境。所以,真正的问题是:我怎样才能明确地强制一切正常以避免可能的数据丢失?这里有人有做这种手术的经验吗?
更新
这样做的原因是我不喜欢庞大的日志文件。高度受控的环境是我的 PC 在单用户模式下运行单个应用程序。我是此应用程序的开发人员,我可以完全控制代码更改。我宁愿删除而不是SHRINK这样,请不要建议我简单地删除SHRINK文件。
UDATE 2 -- 练习
我已经在生产中使用了这个过程半年多,没有任何问题。
DELETE FROM sales;
Run Code Online (Sandbox Code Playgroud)
并且如果sales表上没有其他未提交的事务。关于该DELETE陈述,哪项陈述是正确的?
它删除表中的所有行并且删除的行不能回滚
它删除所有行以及表的结构
如果表有主键,它不会删除行
它删除表中的所有行并且可以回滚删除的行
当然,正确答案在1到4之间。我不知道删除的数据是否可以回滚。
如果有人知道,请帮助我。谢谢。