Sql-Server

如何僅在載入的最新數據上執行儲存過程?

  • September 3, 2018

我的數據庫有一個表格,其中數據是從 Excel 上傳載入的。然後,對數據執行儲存過程以對其進行驗證並將其插入到另一個表中。

目前,我的儲存過程將在執行時再次對所有數據執行驗證。

如何使它僅對新載入的數據執行查詢?

我目前的儲存過程有以下查詢:

INSERT INTO dbo.Data_Pass(
  [ACC_NO]
 ,[ORGN]
 ,[DEST]
 ,[CTRY]
 ,[CRNCY]
 ,[PRDCT_NAME]
 ,[PRDCT_CODE]
 ,[DETAILS]
)
SELECT 
  [ACC_NO]
 ,[ORGN]
 ,[DEST]
 ,[CTRY]
 ,[CRNCY]
 ,[PRDCT_NAME]
 ,[PRDCT_CODE]
 ,[DETAILS]
FROM dbo.SOURCE_TBL AS ST
JOIN UPLOAD_DATA AS UD ON ST.ACC_NO = CAST(UD.ACC_NO AS nvarchar)
   AND ST.CTRY = CAST(UD.CTRY AS nvarchar)
WHERE ST.[PRDCT_CODE] = '102'
   AND CAST(UD.[PRDCT_CODE] AS nvarchar) LIKE '%%2' 
   AND ST.Val LIKE ('%' + CAST(UD.CorrectionVal AS nvarchar)+ '%');

UPDATE Data_Pass
SET REPORT_TY = 'Correction',
   CHECK_DT = GETDATE(),
   CHECK_SRC = 'Correction Report', 
   Data_Pass.STATUS = 'Validated'
WHERE REPORT_TY IS NULL AND CHECK_DT IS NULL AND CHECK_SRC IS NULL 

我還有一個id欄位,Data_Pass其中是主鍵並自動遞增。

一次載入的數據可能約為 200,000 甚至更多,因此我正在尋找最有效的方法來執行此操作。

編輯:在我的創建表語句中添加:

CREATE TABLE [dbo].[Data_Pass](
   [id] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
   [ACC_NO] [nvarchar](50) NULL,
   [ORGN] [nvarchar](50) NULL,
   [DEST] [nvarchar](max) NULL,
   [CTRY] [nvarchar](max) NULL,
   [CRNCY] [nvarchar](50) NULL,
   [PRDCT_NAME] [nvarchar](50) NULL,
   [PRDCT_CODE] [nvarchar](50) NULL,
   [DETAILS] [nvarchar](max) NULL,
   [REPORT_TY] [nvarchar](max) NULL,
   [CHECK_DT] [datetime2](7) NULL,
   [CHECK_SRC] [nvarchar](max) NULL,
   [STATUS] [nvarchar](50) NULL
)

| id  | ACC_NO    |  ORGN | DEST | CTRY |  CRNCY |  PRDCT_NAME  | PRDCT_CODE |  DETAILS |  REPORT_TY   |  CHECK_DT  |      CHECK_SRC      |   STATUS   |
--------------------------------------------------------------------------------------------------------------------------------------------------------
| 979 | 900000000 |  TYO  |  SIN |  SG  |   SGD  |    NULL      |   A12      |    NULL  |  Correction  |   15:47.8  |   Correction Report |  Validated |
| 980 | 900000001 |  TYO  |  SIN |  SG  |   SGD  |    NULL      |   A12      |    NULL  |  Correction  |   15:47.8  |   Correction Report |  Validated |
| 981 | 900000002 |  TYO  |  SIN |  SG  |   SGD  |    NULL      |   A12      |    NULL  |  Correction  |   15:47.8  |   Correction Report |  Validated |
| 982 | 900000003 |  TYO  |  SIN |  SG  |   SGD  |    NULL      |   A12      |    NULL  |  Correction  |   15:47.8  |   Correction Report |  Validated |
| 983 | 900000004 |  TYO  |  SIN |  SG  |   SGD  |    NULL      |   A12      |    NULL  |  Correction  |   09:09.0  |   Correction Report |  Validated |

社區 wiki 答案- 請編輯以改進:

不要直接載入到dbo.Data_Pass.

相反,載入到臨時表,並針對該表執行 SP。然後將經過驗證的最終數據插入dbo.Data_Pass.

通過“再次對所有數據執行驗證”,我假設您的意思是UPDATE您在問題中包含的陳述。解決問題的最簡單方法是根本不執行UPDATE。您沒有為[REPORT_TY][CHECK_DT][CHECK_SRC][STATUS]列指定插入值,因此您插入的行對於表中的這些列將始終具有 NULL 值Data_Pass。將您的插入查詢更改為:

INSERT INTO dbo.Data_Pass(
  [ACC_NO]
 ,[ORGN]
 ,[DEST]
 ,[CTRY]
 ,[CRNCY]
 ,[PRDCT_NAME]
 ,[PRDCT_CODE]
 ,[DETAILS]
 ,[REPORT_TY]
 ,[CHECK_DT]
 ,[CHECK_SRC]
 ,[STATUS]
)
SELECT 
  [ACC_NO]
 ,[ORGN]
 ,[DEST]
 ,[CTRY]
 ,[CRNCY]
 ,[PRDCT_NAME]
 ,[PRDCT_CODE]
 ,[DETAILS]
 ,'Correction'
 ,GETDATE()
 ,'Correction Report'
 ,'Validated'

如果由於某種原因這不是一個選項,那麼您可以利用標識列上的聚集索引,只要您不手動弄亂該值。如果您插入的所有行的值都大於[id]表中已存在的所有行的值,那麼您可以保存[id]插入之前的值並將其用作更新查詢的過濾器。就像是:

DECLARE @max_id INT;

SELECT @max_id = MAX(Id)
FROM [dbo].[Data_Pass];

INSERT INTO dbo.Data_Pass(
...
AND ST.Val LIKE ('%' + CAST (UD.CorrectionVal AS nvarchar) + '%'));

UPDATE Data_Pass
SET REPORT_TY = 'Correction',
   CHECK_DT = GETDATE(),
   CHECK_SRC = 'Correction Report', 
   Data_Pass.STATUS = 'Validated'
WHERE REPORT_TY IS NULL AND CHECK_DT IS NULL AND CHECK_SRC IS NULL
AND Id > @max_id;

引用自:https://dba.stackexchange.com/questions/216467