如何运行删除查询以跳过由另一个表的外键引用的记录?

Law*_*son 3 sql-server

我有一个通过查询远程 API 进行大量搜索的应用程序。结果被拉入我的数据层 (SQL Server),它们会在那里查看用户是否愿意与它们进一步交互。一旦用户开始使用该项目,它就必须留在系统中,但其余的结果完全没有用,只是占用空间。

我正在考虑制作一个任务,该任务将运行一个 sproc 来删除任何未被另一个表引用的行。有没有办法做到这一点?

另一种措辞是:有没有办法执行删除语句,该语句会跳过由于违反参照完整性而导致错误的行?

编辑:感谢来自@Kos 的新信息......我正在考虑的替代路径是向表中添加一个位列,如果该行最终被使用并且只是让我的任务删除行标记为假,则将其标记为真。

为了清楚起见,这里是情况的概述。这些语法可能并不完美,但希望您能明白:

-- Where all the results get pulled down and held (The table I want to clean up every 2 hours or so)
CREATE TABLE [reservations].[DumpTable](
    [utypeID] [bigint] IDENTITY(1,1) NOT NULL
    -- Other columns
    CONSTRAINT [PK_UnitTypesFound] PRIMARY KEY CLUSTERED 
    (
        [utypeID] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]


-- This is one of many other tables that might reference the dump table
CREATE TABLE [reservations].[OtherTables](
    [memberID]  INT NOT NULL,
    [utypeID]   BIGINT NOT NULL -- Need to Know if the dumptable is referenced here
    CONSTRAINT [PK_MemberUnitTypes] PRIMARY KEY CLUSTERED
    (
        [memberID],
        [utypeID]
    ) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,     ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

ALTER TABLE [reservations].[OtherTables]  WITH CHECK ADD  CONSTRAINT [FK_OtherTable_DumpTable] FOREIGN KEY([utypeID])
    REFERENCES [reservations].[DumpTable] ([utypeID])

ALTER TABLE [reservations].[OtherTables] CHECK CONSTRAINT [FK_OtherTable_DumpTable]
Run Code Online (Sandbox Code Playgroud)

Mar*_*shi 6

也可以使用这个查询,使用join代替where子句可以加快查询速度。

DELETE FROM DATA_TABLE 
FROM         DATA_TABLE LEFT OUTER JOIN
                      OTHERON DATA_TABLE.OTHER_TABLE_ID= OTHER.ID 
WHERE     (OTHER.ID IS NULL) and DATA_TABLE.SOME_TIMESTAMP < threshold_time
Run Code Online (Sandbox Code Playgroud)


Vin*_* V. 5

我今天遇到了同样的问题,最后到了这里。最终我想出了一种不同的方法,更接近于劳伦斯正在寻找的 IMO,但也很可能慢得多,这在我自己的情况下不是问题。

所以基本上我使用一个游标来逐行删除我的行,如果发生约束错误,我将删除语句放在 try/catch 块中以恢复循环:

DECLARE @idc as int
DECLARE Contact_Cursor CURSOR FOR
SELECT ID 
FROM ContactInfo;
OPEN Contact_Cursor;
FETCH NEXT FROM Contact_Cursor INTO @idc 
WHILE @@FETCH_STATUS = 0
  BEGIN
    begin try
      delete from ContactInfo where id = @idc;
      FETCH NEXT FROM Contact_Cursor INTO @idc 
    end try
    begin catch
      FETCH NEXT FROM Contact_Cursor INTO @idc 
    end catch
   END;
CLOSE Contact_Cursor;
DEALLOCATE Contact_Cursor;
GO
Run Code Online (Sandbox Code Playgroud)