sql - 在插入期间避免重复
问题描述
我正在研究一个存储过程,该过程当前每小时构建我们的事实表。目前,在每小时刷新期间,它会截断表并每次插入新数据。我正在尝试将其更改为仅删除不需要的行并附加新行。我已经得到了删除部分,但是目前,由于 ID 列(主键)是在插入时创建的,我不确定如何避免插入重复记录,这是我目前看到的。
目前,存储过程在插入时插入主键 (ID)。我取出了截断表查询并用删除查询替换了它。现在我需要在插入过程中避免重复。
--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
,null
--,[ID]
FROM #TEMP_FACT
--code for avoiding duplicates
--CLEAR ALL DATA FROM FACTBP
DELETE FROM dbo.FactBP
WHERE SHIP_DATE < DATEADD(s,-1,DATEADD(mm,
DATEDIFF(m,0,GETDATE())-2,0)) and SHIP_DATE IS NOT NULL
解决方案
您需要检查natural key。由于您在谈论事实表,因此自然键可能是许多字段的组合。如果我们假设 SOURCE 和 DC_ORDER_NUMBER 构成自然键,这应该有效:
INSERT INTO dbo.FactBP
SELECT
t.[SOURCE]
, t.[DC_ORDER_NUMBER]
, t.[CUSTOMER_PURCHASE_ORDER_ID]
, t.[BILL_TO]
, t.[CUSTOMER_MASTER_RECORD_TYPE]
, t.[SHIP_TO]
, t.[CUSTOMER_NAME]
, t.[SALES_ORDER]
, t.[ORDER_CARRIER]
, t.[CARRIER_SERVICE_ID]
, t.[CREATE_DATE]
, t.[CREATE_TIME]
, t.[ALLOCATION_DATE]
, t.[REQUESTED_SHIP_DATE]
, t.[ADJ_REQ_SHIP]
, t.[CANCEL_DATE]
, t.[DISPATCH_DATE]
, t.[RELEASED_DATE]
, t.[RELEASED_TIME]
, t.[PRIORITY_ORDER]
, t.[SHIPPING_LOAD_NUMBER]
, t.[ORDER_HDR_STATUS]
, t.[ORDER_STATUS]
, t.[DELIVERY_NUMBER]
, t.[DCMS_ORDER_TYPE]
, t.[ORDER_TYPE]
, t.[MATERIAL]
, t.[QUALITY]
, t.[MERCHANDISE_SIZE_1]
, t.[SPECIAL_PROCESS_CODE_1]
, t.[SPECIAL_PROCESS_CODE_2]
, t.[SPECIAL_PROCESS_CODE_3]
, t.[DIVISION]
, t.[DIVISION_DESC]
, t.[ORDER_QTY]
, t.[ORDER_SELECTED_QTY]
, t.[CARTON_PARCEL_ID]
, t.[CARTON_ID]
, t.[SHIP_DATE]
, t.[SHIP_TIME]
, t.[PACKED_DATE]
, t.[PACKED_TIME]
, t.[ADJ_PACKED_DATE]
, t.[FULL_CASE_PULL_STATUS]
, t.[CARRIER_ID]
, t.[TRAILER_ID]
, t.[WAVE_NUMBER]
, t.[DISPATCH_RELEASE_PRIORITY]
, t.[CARTON_TOTE_COUNT]
, t.[PICK_PACK_METHOD]
, t.[RELEASED_QTY]
, t.[SHIP_QTY]
, t.[MERCHANDISE_STYLE]
, t.[PICK_WAREHOUSE]
, t.[PICK_AREA]
, t.[PICK_ZONE]
, t.[PICK_AISLE]
, t.EST_DEL_DATE
, null
--,[ID]
FROM #TEMP_FACT t
left outer join dbo.FactBP f on f.[SOURCE] = t.[SOURCE]
and f.[DC_ORDER_NUMBER] = t.[DC_ORDER_NUMBER]
where f.[SOURCE] is null
调整连接和WHERE
子句以匹配表的自然键。
您还应该再看看您的DELETE
脚本。您真的要删除所有带有 a 的记录SHIP_DATE < 2019-07-31 23:59:59.000
吗?还是应该这样<=
?也许这会更好(更简单):
DELETE FROM dbo.FactBP
WHERE SHIP_DATE < cast(dateadd(day, 1, EOMONTH(getdate(), -3)) as datetime2)
and SHIP_DATE IS NOT NULL
推荐阅读
- javascript - Is it okay to use an infinite loop to constantly check the Connection to a Server?
- javascript - 如何在反应虚拟化中检测滚动事件的结束?
- amazon-web-services - 加载命名空间时出错。未经授权:验证您有权访问 Kubernetes 集群
- javascript - splitslider.js - 打开一个特定的 div,而不是用箭头
- javascript - 如何在中间件中将 Koa bodyParser 上传限制设置为特定路由而不是全局?
- javascript - 在cropper js中上传图片会出错拒绝加载图片违反内容安全策略指令:“img-src * data:”
- kubernetes - 无法访问用完 istio 服务网格的 api
- angular - 如何将授权标头设置为为其他 API 请求生成的不记名令牌
- javascript - 更改 Google 饼图上的饼图文本
- html - 为什么这个引导模板有一个从左到右的滚动条?