【问题标题】:Truncate existing table within a stored procedure then insert fresh data截断存储过程中的现有表,然后插入新数据
【发布时间】:2016-11-07 12:58:40
【问题描述】:

我有一个返回结果集的存储过程。之后,我将此结果集插入到创建的真实表中。然后我正在使用该真实表创建 SSRS 报告。

所以,是这样的:

CREATE PROCEDURE Test
AS
   DECLARE @TempTable TABLE(..)

   INSERT INTO @TempTable
       SELECT...
       FROM ...
       WHERE ...

SELECT * FROM @TempTable

--============================

INSERT INTO RealTable EXEC [dbo].[Test] 

如何修改此存储过程,以便每次执行时都会使用现有数据截断表,然后插入新数据?

所以我需要这样的东西:

create procedure Test
as
TRUNCATE RealTable
DECLARE @TempTable TABLE(..)

INSERT INTO @TempTable
    SELECT...
    FROM...
    WHERE...

SELECT * FROM @TempTable INTO RealTable

或者我应该只创建可以运行类似命令的代理作业:

Truncate Table RealTable
INSERT INTO RealTable EXEC [dbo].[Test] 

就逻辑而言,我是否走在正确的道路上?

【问题讨论】:

  • 似乎非常很危险 - 如果两个用户同时点击它,一个用户将抹去另一个用户的结果。似乎带有会话 ID 列的表或其他方法会更安全。
  • 您不需要填充临时表,您可以直接进入真实表。此外,您还需要注意,只有在表没有外键主页时才能截断表
  • 用户没有运行此报告。我是每周部署它并通过电子邮件发送它的人。
  • 那么我应该在我的存储过程中在哪里说截断表?
  • 在插入之前的任何时候。所以流程是这样的:CREATE SP AS ... TRUNCATE TABLE ... INSERT INTO RealTable SELECT ... FROM ... WHERE ...'.

标签: sql-server tsql ssms


【解决方案1】:

不要截断。使用 MERGE 语句。

CREATE PROCEDURE Test
AS

MERGE RealTable TRGT
USING SourceTable SRCE
    ON SRCE.[Column] = TRGT.Column --use columns that can be joined together
WHEN MATCHED THEN UPDATE
        SET TRGT.Column1 = SRCE.Column1,
            TRGT.Column2 = SRCE.Column2
        ....................
WHEN NOT MATCHED BY TARGET THEN INSERT
        VALUES
        (
            SRCE.Column1,
            SRCE.Column2,
            .....................
        )
WHEN NOT MATCHED BY SOURCE THEN 
        DELETE;

【讨论】:

  • 想解释一下为什么?
【解决方案2】:
  1. 如果插入相同的数据,截断的目的是什么?
  2. 如果您的并发用户超过 1 个,会发生什么情况?

你可以做的另一件事: 1. 插入目标表 从 SourceTable 中选择 * 2. 在 TargetTable 上重建索引 3. exec sp_rename SourceTable, SourceTable_Old exec sp_rename 目标表,源表 删除表 SourceTable_Old

  • 当表变量不是一个选项时,这是刷新整个表数据的旧方法,没有太大影响。

【讨论】:

  • 截断的目的是为了刷新数据。然后每周根据该数据运行报告。我是唯一一个部署报告并将其发送到特定电子邮件的人。未经我的许可,任何人都不会发布报告
  • 几个问题: 1. 将其放入事务中,因此不会对表进行更新 2. 使用表变量时,将其填充到 tempdb - 可能会导致其他问题(空间、锁定) 3 . 插入数据后,重建所有索引会全盘扫描,需要更新统计数据。
【解决方案3】:

这是您直接从@TempTable 插入到 RealTable 时可能需要的。

create procedure Test
as
BEGIN

TRUNCATE TABLE RealTable

INSERT INTO RealTable 
    SELECT...
    FROM someothertable
    WHERE...

END

【讨论】:

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