为什么在使用LIKE关键字时无法执行SQL DELETE查询?

时间:2019-07-09 05:52:22

标签: sql sql-server

我想从表中删除一些数据,因此编写查询以将其删除。所以首先我选择了要使用此查询删除的数据,它向我显示了正确的数据

select * from PATS.Discipline where Code like '%DHA-DIS%'

然后我使用相同的where条件编写删除,但它不起作用

DELETE FROM PATS.Discipline WHERE Code LIKE '%DHA-DIS%'

此处我在执行查询时共享一些屏幕截图 enter image description here

这是一些示例数据 enter image description here

这是最后一个执行结果,我已经等待了1分钟,最后停止了执行 enter image description here

添加表结构 enter image description here

11 个答案:

答案 0 :(得分:4)

它应该工作正常,我没有发现查询有任何问题,请尝试在新的查询窗口中编写新查询,以确保查询是干净的

对我来说,它可以正常工作并从表中删除测试数据

select * from Discipline
select * from Discipline where Code like '%DHA-DIS%'

enter image description here

DELETE FROM Discipline WHERE Code LIKE '%DHA-DIS%'

(2 row(s) affected)


select * from Discipline where Code like '%DHA-DIS%'

enter image description here

您可以看到上面的查询工作正常,它删除了与查询匹配的2行。

答案 1 :(得分:2)

我认为您在这里更担心执行时间,因为这花费了很长时间,所以您取消了执行。过去我遇到的问题是我的解决方案是重新启动SQL Management Studio并尝试相同的查询,它将正常工作。

答案 2 :(得分:1)

1)您要删除5000行,但这不一定是整个表。表中有多少行?

2)您的SELECT SUM(CASE WHEN [IsInStock]='True' THEN 1 ELSE 0 END) AS [InStock], SUM(CASE WHEN [IsInStock]='False' THEN 1 ELSE 0 END) AS [OutOfStock] FROM [Prodcuts] 语句将需要进行表扫描才能满足。如果有很多行或很大的列,那将花费很长时间。

3)在其使用的表上发布查询计划和统计信息。

4)如果取消LIKE,则数据库将回滚。这就是为什么您看到它什么都不做的原因。

答案 3 :(得分:1)

其他进程可能对表Discipline进行了锁定
您可以通过运行此脚本找到表上的锁

declare @lock table (spid int, dbid int, objId int, indId int, Type char(4), resource nchar(32), Mode char(8), status char(6))
declare @who table (spid int, ecid int, status char(30), loginname char(128), hostname char(128), blk char(5), dbname char(128), cmd char(16), request_id INT)
declare @LockSummary table (loginname varchar(28), DB varchar(128), object varchar(30), ToLevel varchar(20), How_Many int, Xclusive_lock_for_command char(16), spid int, hostname char(128))

insert into @lock exec sp_lock
insert into @who exec sp_who

insert into @LockSummary
select loginname, 
       db_name(dbid) as DB,
       object_name(objID) as object,
       max(mode) as [ToLevel],
       Count(*) as [How Many],
       Max(Case When mode= 'X' Then cmd Else null End) as [Xclusive lock for command],
       l.spid, 
       hostname
from   @lock l 
  join @who w on l.spid = w.spid
where  dbID != db_id('tempdb') 
and    l.status = 'GRANT'
group by dbID, objID, l.spid, hostname, loginname

select * 
from   @LockSummary 
where  object like '%Discipline%'
order by [ToLevel] Desc, [How_Many] Desc, loginname, DB, object

答案 4 :(得分:0)

您是否在编辑模式下尝试了相同的查询。 您可以这样做

  1. 右键单击Pats.Discipline表。
  2. 选择编辑前200行...
  3. Ctrl + 3编辑查询。
  4. select * from Discipline where Code like '%DHA-DIS%'代替查询
  5. 单击下图中的第一个顶部单元格以选择所有行
  6. 点击删除按钮

如果执行时间过长,请尝试将查询更改为类似的内容

  

从“'%DHA-DIS%'之类的代码中选择前1000个*

如果成功,请重复该步骤

enter image description here

答案 5 :(得分:0)

两件事可能会拖慢您的删除速度

  1. 您在引用Pats.Discipline表的PK的外键上具有级联删除功能。您可以通过运行以下查询来检查是否有任何启用了级联删除的键。
    select * from sys.foreign_keys where delete_referential_action > 0
  1. Pats.Discipline表的主键在具有大量行的其他表中用作外键。删除“纪律”表中具有这些字段的记录将触发对引用了该键的所有表的参照完整性检查,并且根据某些因素,这可能是一个漫长的过程。 如果您知道此删除没有违反参照完整性,则可以删除外键,然后运行delete命令,然后重新创建外键。

答案 6 :(得分:0)

注意:恢复原状

如果可能Alter PATSDiscipline

ID int PK
Code varchar(20)
Name varchar(50)
CreatedBY varchar(50) or even better INT
CreatedDate Datetime2(0)
UpdatedBY varchar(50) or even better INT
UpdatedDate Datetime2(0)

或者更改任何可能的列。

通过首先手动与关注表联接,可以将

CreatedBY转换为INT。 然后更正代码。

我没有在讨论这一点,Code LIKE '%DHA-DIS%' is NON SARGable。 或为什么不应该使用。 以及代码列是否应为NON Clustered Index

更改表设计将在各个方面为您提供帮助,无论是Select查询还是DML operation,而且永远如此。

或者,您可以执行此操作

Select Resultset放入Temp表中,然后加入并删除

create table #temp (id uniqueidentifier not null primary key)

insert into #temp 
select id from PATS.Discipline where Code like '%DHA-DIS%'

delete from PATS.Discipline
where exists(select 1 from #temp where #temp.id=PATS.Discipline.id )

您可以同时执行两个步骤

如果“删除数据”以百万为单位,则可以使用分页,<​​/ p>

DECLARE @TopSize INT = 10000
DECLARE @BatchSize INT = 10000
DECLARE @MaxLimit INT = 1
DECLARE @RowCount INT = 0

BEGIN TRY
    WHILE (@TopSize <= @MaxLimit)
    BEGIN


    delete TOP (@TopSize) from PATS.Discipline
    where exists(select 1 from #temp where #temp.id=PATS.Discipline.id )


        SET @RowCount = @@RowCount

        --PRINT @TopSize
        IF (
                @RowCount = 0
                OR @RowCount IS NULL
                )
            BREAK;
        ELSE
            SET @TopSize = @TopSize + @BatchSize
    END
END TRY

BEGIN CATCH
    --catch error
END CATCH

答案 7 :(得分:0)

此答案基于我的个人经验。

您正在将uniqueidentifier作为表的ID存储,并使其成为主集群键。由于重新索引表,删除这样的行数会花费一些时间。所以,我建议-

  1. 删除主键索引
  2. 执行您的删除语句
  3. 重新添加主键索引

在类似情况下,它对我有帮助。 为什么?因为在此策略中,该表的索引仅被操纵两次。在删除表时不会发生重新索引。因此,您将在执行删除操作方面看到显着的进步。

因此,您的查询应该像这样-

ALTER TABLE PATS.Discipline DROP CONSTRAINT [PK_Discipline]
GO
DELETE FROM PATS.Discipline WHERE Code LIKE '%DHA-DIS%'
GO
ALTER TABLE PATS.Discipline DROP CONSTRAINT [PK_Discipline] PRIMARY KEY CLUSTERED
GO

注意:此删除策略仅适用于表具有大量索引或主键为uniqueidentifier并且您试图从该表中删除更多行的情况。但是在正常情况下,应该使用相同的旧删除查询。

答案 8 :(得分:0)

LIKE关键字可能不是问题。 SELECT似乎返回了大量匹配的行-我认为相对较快(?)-因此问题是“删除(或阻止)删除的速度慢?”试试

DELETE TOP 1 FROM PATS.Discipline WHERE Code LIKE '%DHA-DIS%'

,如果可行,请尝试TOP 10/100...

一个有根据的猜测说,由于重新索引和/或跨表关系(外键约束)和/或只是建立了一个非常大的事务,所以速度很慢。

如何加快速度?在已经发布的答案中,有很多很好的建议,我也建议您看一下:How to efficiently delete rows while NOT using Truncate Table in a 500,000+ rows table

答案 9 :(得分:0)

其他所有,尽管删除查询中使用了like语句,但最初使用的代码没有任何问题,会对性能产生影响。如果我知道我只删除了几千行,则采用CTE方法并将其重新加入源表:

pipenv shell

答案 10 :(得分:0)

您使用的查询没有问题。

可能有几个原因。在执行过程中,网络电缆可能已断开连接,数据库可能已脱机,电源可能已出现故障或由于其他事务等原因导致对表的访问已锁定

查询失败时,甚至花费了超过1分钟的时间,对吗?但是,一旦成功,执行速度很快。查询失败时,那时必须已经通过网络对该表进行了另一次访问。

处理大量数据(例如5000)时,您可以添加存储过程并添加事务块。