使用場景:sql
咱們和第三方水錶廠家合做,他們會傳遞9萬條json 經過咱們的接口 insert(update)咱們的數據庫表中。數據庫
表值參數:存儲過程當中定義表的字段,類型(我理解爲 臨時表),C# 定義同樣類型的DataTable,將json數據填充到DataTable,同時將DataTable 做爲參數 傳入到表值參數存儲過程當中。json
Parallel.ForEach:自動對數據進行分區。假如9萬條數據,4核 分爲17462條數據分別做爲table傳入到存儲過程執行insert(update)測試
這個我測試的時候,9萬多條數據用時9分10秒,速度還有有點慢,我最後採用了另外一種辦法,在下一篇博客中寫道。blog
並行+表值參數主要代碼 如下爲C#主要代碼接口
表值參數 建表:ip
USE [MeterReadTest]
GOci
/****** Object: UserDefinedTableType [dbo].[MRTableType] Script Date: 2018/6/20 15:58:48 ******/
CREATE TYPE [dbo].[MRTableType] AS TABLE(
[id] [int] NULL,
[freezedate] [varchar](20) NULL,
[dreaddate] [varchar](20) NULL,
[freezeMonth] [varchar](20) NULL,
[meter_sn] [varchar](20) NULL,
[meter_no] [varchar](20) NULL,
[flow] [decimal](18, 0) NULL,
[dayflow] [decimal](18, 0) NULL
)
GOget
存儲過程:博客
USE [MeterReadTest]
GO
/****** Object: StoredProcedure [dbo].[sp_test] Script Date: 2018/6/20 15:57:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/* 建立一個存儲過程以表值參數做爲輸入 */
ALTER Procedure [dbo].[sp_test](@dataTable MRTableType readonly)
as
declare @temp Table(
id int,
freezedate varchar(20),
dreaddate varchar(20),
meter_sn varchar(20),
meter_no varchar(20),
flow decimal,
dayflow decimal,
freezeMonth varchar(20)
);
--將表值參數賦值給@temp
insert into @temp(id,freezedate,dreaddate,freezeMonth,meter_sn,meter_no,flow,dayflow) select id,freezedate,dreaddate,freezeMonth,meter_sn,meter_no,flow,dayflow from @dataTable;
declare
@oldflow AS varchar(20),
@id AS int,
@imeterid As int,
@freezedate As varchar(20),
@dreaddate As varchar(20),
@meter_sn varchar(20),
@meter_no varchar(20),
@flow decimal,
@sql nvarchar(1000),
@dayflow decimal,
@time date,
@readtime datetime,
@tempMeterID int,
@freezeMonth varchar(20);
--第一種方案 C# 並行+存儲過程(循環遍歷)
--while exists(select @id from @temp)
--begin
--SET ROWCOUNT 1
----賦值
--select @freezedate=freezedate,@dreaddate=dreaddate,@meter_sn=meter_sn,@id=id, @meter_no=meter_no,@flow=flow from @temp;
--select @time=(CONVERT(varchar(100),@freezedate, 20));
--select @readtime=(CONVERT(varchar(100),@dreaddate, 20));
-- select @oldflow=0;
----計算日用量
--select @tempMeterID= iMeterID from WR_Meters where tMeterAddr= @meter_no and iMeterManufactureID='1'
--select top 1 @oldflow=fFreezeNumber from WR_FreezeDay where iMeterID=@tempMeterID
--and dFreezeDate <@time order by dFreezeDate desc;
--if exists(select iMeterID from [dbo].[WR_FreezeDay] where iMeterID=@tempMeterID and dFreezeDate=@freezedate)
-- update WR_FreezeDay set fFreezeNumber=@flow,fUseNumber=(@flow-@oldflow),dFactDate=GETDATE(),
-- dReadDate=@readtime where iMeterID=(select iMeterID from WR_Meters where
-- tMeterAddr=@meter_no and iMeterManufactureID='1' and dFreezeDate=@time);
--else
-- insert into WR_FreezeDay (iMeterID,dFreezeDate,fFreezeNumber,fUseNumber,dFactDate,dReadDate) values
-- (@tempMeterID,@time,@flow,(@flow-@oldflow),getdate(),@readtime);
--SET ROWCOUNT 0 --DELETE FROM @temp WHERE id=@id; --end