【发布时间】: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