【问题标题】:Need help to optimize my stored procedure需要帮助来优化我的存储过程
【发布时间】:2020-01-27 01:02:35
【问题描述】:

我需要帮助优化我的存储过程。这是针对我们的事实表的,当前存储过程会截断表,然后将数据重新加载。我想摆脱截断,而是通过当前不存在的 last_update 列追加新行或删除行。还有一个包含一列的 last_update 表,在每次存储过程运行时都会更改,但我宁愿 last_update 是表本身的一列,而不是单独的列。

我创建了一个触发器,它应该在存储过程运行时使用当前日期更新 last_updated 列,但我也想摆脱截断,而是追加/删除行。存储过程当前的结构方式让我很难弄清楚如何最好地做到这一点。

存储过程首先将数据添加到 2 个临时表中,然后将两个临时表中的数据添加到第三个临时表中,然后截断当前的 FACT TABLE,然后第三个临时表最终插入到 FACT 表中。

--CLEAR LAST UPDATE TABLE
TRUNCATE TABLE ADM.LastUpdate;

--SET NEW LAST UPDATE TIME
INSERT INTO ADM.LastUpdate(TABLE_NAME, UPDATE_TIME)
VALUES('FactBP', CONVERT(VARCHAR, GETDATE(), 100)+' (CST)');

--CHECK TO SEE IF TEMP TABLES EXISTS THEN DROP
IF OBJECT_ID('tempdb.dbo.#TEMP_CARTON', 'U') IS NOT NULL
    DROP TABLE #TEMP_CARTON;

IF OBJECT_ID('tempdb.dbo.#TEMP_ORDER', 'U') IS NOT NULL
    DROP TABLE #TEMP_ORDER;

--CREATE TEMP TABLES
SELECT *
INTO #TEMP_CARTON
FROM [dbo].[FACT_CARTON_V];

SELECT *
INTO #TEMP_ORDER
FROM [dbo].[FACT_ORDER_V];

--CHECK TO SEE IF DATA EXISTS IN #TEMP_CARTON AND #TEMP_ORDER
IF EXISTS(SELECT * FROM #TEMP_CARTON)
    AND EXISTS(SELECT * FROM #TEMP_ORDER)

--CODE HERE joins the data from #TEMP_CARTON and #TEMP ORDER and puts it into a 3rd temp table #TEMP_FACT.


--CLEAR ALL DATA FROM FACTBP
TRUNCATE TABLE dbo.FactBP;

--INSERT DATA FROM TEMP TABLE TO FACTBP
INSERT INTO dbo.FactBP
SELECT 
[SOURCE]
      ,[DC_ORDER_NUMBER]
      ,[CUSTOMER_PURCHASE_ORDER_ID]
      ,[BILL_TO]
      ,[CUSTOMER_MASTER_RECORD_TYPE]
      ,[SHIP_TO]
      ,[CUSTOMER_NAME]
      ,[SALES_ORDER]
      ,[ORDER_CARRIER]
      ,[CARRIER_SERVICE_ID]
      ,[CREATE_DATE]
      ,[CREATE_TIME]
      ,[ALLOCATION_DATE]
      ,[REQUESTED_SHIP_DATE]
      ,[ADJ_REQ_SHIP]
      ,[CANCEL_DATE]
      ,[DISPATCH_DATE]
      ,[RELEASED_DATE]
      ,[RELEASED_TIME]
      ,[PRIORITY_ORDER]
      ,[SHIPPING_LOAD_NUMBER]
      ,[ORDER_HDR_STATUS]
      ,[ORDER_STATUS]
      ,[DELIVERY_NUMBER]
      ,[DCMS_ORDER_TYPE]
      ,[ORDER_TYPE]
      ,[MATERIAL]
      ,[QUALITY]
      ,[MERCHANDISE_SIZE_1]
      ,[SPECIAL_PROCESS_CODE_1]
      ,[SPECIAL_PROCESS_CODE_2]
      ,[SPECIAL_PROCESS_CODE_3]
      ,[DIVISION]
      ,[DIVISION_DESC]
      ,[ORDER_QTY]
      ,[ORDER_SELECTED_QTY]
      ,[CARTON_PARCEL_ID]
      ,[CARTON_ID]
      ,[SHIP_DATE]
      ,[SHIP_TIME]
      ,[PACKED_DATE]
      ,[PACKED_TIME]
      ,[ADJ_PACKED_DATE]
      ,[FULL_CASE_PULL_STATUS]
      ,[CARRIER_ID]
      ,[TRAILER_ID]
      ,[WAVE_NUMBER]
      ,[DISPATCH_RELEASE_PRIORITY]
      ,[CARTON_TOTE_COUNT]
      ,[PICK_PACK_METHOD]
      ,[RELEASED_QTY]
      ,[SHIP_QTY]
      ,[MERCHANDISE_STYLE]
      ,[PICK_WAREHOUSE]
      ,[PICK_AREA]
      ,[PICK_ZONE]
      ,[PICK_AISLE]
      ,EST_DEL_DATE
FROM #TEMP_FACT;

目前,由于我已将 last_updated 列添加到我的 FACT TABLE 中并创建了一个触发器,我实际上并没有通过存储过程为它传递任何值,所以我得到一个错误

对象或列名丢失或为空。

我不确定应该在哪里传递 LAST_UPDATED 列的任何值。

这是我为更新last_updated 列创建的触发器:

CREATE TRIGGER last_updated
ON dbo.factbp
AFTER UPDATE 
AS
    UPDATE dbo.factbp
    SET last_updated = GETDATE()
    FROM Inserted i
    WHERE dbo.factbp.id = i.id

【问题讨论】:

  • 出于测试目的,您可以使用 getdate()。但可能需要根据业务需求重新审视该逻辑。
  • 请输入您的trigger 代码。让我知道您将如何在 FACT TABLE 中识别 record wise last updated 或不识别 insert/update/delete
  • 或者你也可以硬编码一个未来的日期;再次基于一些业务逻辑,例如“9999-09-09”;但也可用于 ISNULL,以防 Last_Update_Date 列未找到匹配条件。再次是商业规则。
  • @JIKEN 我已经添加了上面的触发代码。 SP 每天运行一次,因此我希望删除任何超过 2 个月的行,并附加表中当前不存在的任何新行。
  • @UmairAhmed - 您需要将触发代码从 AFTER UPDATE 更改为 AFTER INSERT

标签: sql sql-server stored-procedures triggers


【解决方案1】:

我会尝试的第一件事是在两个临时表 #TEMP_CARTON 和 #TEMP_ORDER 上创建主键,并使用 intersect 命令获取两个表共有的行:

select * from  #TEMP_CARTON
intersect
SELECT * FROM #TEMP_ORDER

【讨论】:

    【解决方案2】:

    想出了答案。我只需要在插入期间为 last_updated 值输入“null”,然后触发器会自行添加时间戳。

    【讨论】:

      猜你喜欢
      • 2012-03-02
      • 2011-08-05
      • 1970-01-01
      • 2014-12-23
      • 2014-07-23
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多