【问题标题】:Deleting records from all tables, what's wrong here?从所有表中删除记录,这里有什么问题?
【发布时间】:2015-09-13 02:25:37
【问题描述】:

所以我正在运行 AppHarbor 创建的 SqlRestore 实用程序,可以在这里找到:

https://github.com/appharbor/AppHarbor-SqlServerBulkCopy

该实用程序的第一步是使用以下命令清除目标数据库中的数据:

// http://stackoverflow.com/questions/155246/how-do-you-truncate-all-tables-in-a-database-using-tsql/156813#156813
StringBuilder commandBuilder = new StringBuilder();
commandBuilder.Append(
    @"
    -- disable all constraints
    EXEC sp_msforeachtable ""ALTER TABLE ? NOCHECK CONSTRAINT all""

    -- delete data in all tables
    EXEC sp_msforeachtable ""DELETE FROM ?""

    -- enable all constraints
    exec sp_msforeachtable ""ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all""
");

当我运行它时(通过程序,也通过 Management Studio 手动运行),delete 语句抛出错误说invalid column name schoolid

起初,我不知道是哪个表抛出错误,所以我将删除步骤重新编写到光标,如下所示:

declare tableCursor cursor local forward_only for

    select [name]
    from sys.objects
    where [type] = 'U'

    declare @tableName varchar(50)

    open tableCursor

    fetch next from tableCursor into @tableName

    while (@@FETCH_STATUS = 0) begin
        print 'trying to delete from ' + @tableName
        exec('delete from ' + @tableName)
        print 'deleted from ' + @tableName

        fetch next from tableCursor into @tableName
    end

close tableCursor
deallocate tableCursor

以这种方式执行脚本告诉我它正在“试图从表 X 中删除”,但是当我查看表 X 的表定义时,该列不存在(并且永远不会存在)!

接下来,我决定手动删除该表,然后使用 VS Sql Server 架构比较重新生成表到我的目标数据库,因为它可能以某种方式损坏。

重新生成后,我重新运行该删除脚本,但它仍然抛出错误!

这是表定义:

CREATE TABLE [dbo].[TourneyPoolMatchResult] (
    [TourneyPoolMatchResultId]      INT            IDENTITY (1, 1) NOT NULL,
    [TournamentTypeId]              INT            NOT NULL,
    [WinningWrestlerId]             INT            NOT NULL,
    [LosingWrestlerId]              INT            NOT NULL,
    [WinType]                       VARCHAR (5)    NOT NULL,
    [Score]                         VARCHAR (20)   NULL,
    [BonusPoints]                   DECIMAL (2, 1) NOT NULL,
    [AdvancementPoints]             DECIMAL (2, 1) NOT NULL,
    [PlacementPoints]               INT            NOT NULL,
    [LosingWrestlerPlacementPoints] INT            NOT NULL,
    PRIMARY KEY CLUSTERED ([TourneyPoolMatchResultId] ASC)
);


GO
CREATE trigger [dbo].[trg_TourneyPoolMatchResult_Change]
    on [dbo].[TourneyPoolMatchResult]
    after insert, update, delete
    as

    exec [UpdateTeamPoints];
    exec [UpdatePointsForSubmittal];

如您所见,该表定义中没有任何关于 SchoolId 的信息。

这到底是怎么回事?

【问题讨论】:

  • 您使用了删除语句,并且您在删除时有一些触发器。也许您的触发函数(例如UpdateTeamPointsUpdatePointsForSubmittal)引用了一个名为 schoolid 的列?搜索你的sql代码,哪里有schoolid
  • 啊,好点,让我检查一下...
  • 是的,就是这样,请添加作为答案,以便我给你信用。
  • 谢谢,很高兴能帮上忙 :)

标签: sql-server tsql sql-server-2012 database-restore


【解决方案1】:

您使用了 delete 语句,并且在删除时有一些触发器。也许您的触发函数(例如 UpdateTeamPoints 或 UpdatePointsForSubmittal)引用了一个名为 schoolid 的列?请搜索你的sql代码,请问哪里有schoolid?

【讨论】:

    【解决方案2】:

    如果您的表没有Foreign Key 约束而不是

    DELETE FROM table_name;

    使用:

    TRUNCATE TABLE table_name;

    来自TRUNCATE

    从表或表的指定分区中删除所有行, 不记录单个行删除。截断表是 类似于没有 WHERE 子句的 DELETE 语句;然而, TRUNCATE TABLE 速度更快,使用的系统和事务日志更少 资源

    TRUNCATE TABLE 无法激活触发器,因为该操作确实 不记录单个行删除。有关详细信息,请参阅创建 触发器(Transact-SQL)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      相关资源
      最近更新 更多