我花了最后24小时梳理互联网寻求解决方案,但尚未找到解决方案。我正在尝试将单个模型的批量upsert(更新或插入)执行到mssql db中。使用updateOnDuplicate的bulkCreate:true不适用于mssql。还有其他解决方案吗?这是数据集,在1-50k行之间。任何帮助将不胜感激!
答案 0 :(得分:0)
对于SQL 2016+,您只需使用NVarchar(max)参数将批量数据作为JSON传递,然后在服务器上解析并加载它。您的查询看起来像这样:
Insert into TargetTable(Number,Date,Customer,Quantity,[Order])
SELECT Number,Date,Customer,Quantity,[Order]
FROM OPENJSON ( @json )
WITH (
Number varchar(200) '$.Order.Number',
Date datetime '$.Order.Date',
Customer varchar(200) '$.AccountNumber',
Quantity int '$.Item.Quantity',
[Order] nvarchar(MAX) AS JSON
);
您可以将@json参数与NVarchar(max)(字符串)值绑定,如:
[
{
"Order": {
"Number":"SO43659",
"Date":"2011-05-31T00:00:00"
},
"AccountNumber":"AW29825",
"Item": {
"Price":2024.9940,
"Quantity":1
}
},
{
"Order": {
"Number":"SO43661",
"Date":"2011-06-01T00:00:00"
},
"AccountNumber":"AW73565",
"Item": {
"Price":2024.9940,
"Quantity":3
}
}
]
更新看起来像:
with q as
(
select t.Number, t.Quantity oldQuantity, j.Quantity newQuantity
from OPENJSON ( @json )
WITH (
Number varchar(200) '$.Order.Number',
Date datetime '$.Order.Date',
Customer varchar(200) '$.AccountNumber',
Quantity int '$.Item.Quantity',
[Order] nvarchar(MAX) AS JSON
) j
join TargetTable t
on j.Number = t.Number
)
update q set oldQuantity = newQuantity
请参阅:https://docs.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql
如果您无法绑定参数,那么请在您的TSQL批处理中将JSON文档包含为文字字符串。
答案 1 :(得分:0)
使用OpenJson将数据转换为表,并与源表合并,如下所示:
const upsertedData = [
{
id: "123",
value: "Value 2"
},
{
id: "124",
value: "Value 1"
}
]
const upsert = async (data) => {
await sequelize.query(
`BEGIN
DECLARE @json NVARCHAR(MAX);
SET @json = :dataToBeUpserted
MERGE INTO dbo.tableToBeUpserted AS Target
USING (SELECT * from OpenJson(@json) WITH (
id nvarchar(32),
value nvarchar(32),
)) AS Source
ON (Target.id = Source.id)
WHEN MATCHED THEN
UPDATE SET
Target.value = Source.value
WHEN NOT MATCHED THEN
INSERT (id, value)
VALUES (Source.id, Source.value);
END`,
{
replacements: {
dataToBeUpserted: JSON.stringify(data)
},
}
)
}
await upsert(upsertedData)