使用以下
时出现问题ALTER PROCEDURE [SaveGlobalFines]
@JSON NVARCHAR(MAX)
AS
BEGIN
DECLARE @ChargeID INT
DECLARE @FineTypeID INT
DECLARE @AmountDB MONEY
DECLARE @AmountJSON MONEY
DECLARE @userID INT
DECLARE @Counter INT
SELECT @ChargeID=Fine.Charge_Id, @FineTypeID=Fine.FineType_Id, @AmountDB = Fine.Amount , @AmountJSON = JSON.Amount, @userID = JSON.user_id
FROM Fine
CROSS APPLY OPENJSON(@JSON,'$.amounts')
WITH(Charge_Id int, Amount money, FineType_Id int, user_id int)AS JSON
WHERE Fine.Charge_Id =JSON.Charge_Id and Fine.FineType_Id= JSON.FineType_Id and Fine.DateExpired IS NULL
IF @ChargeID IS NULL AND @FineTypeID IS NULL --if fine type and charge id are returned null insert new row
BEGIN
INSERT INTO Fine (Charge_Id,Amount,FineType_Id,user_id)
SELECT *
FROM OPENJSON(@JSON,'$.amounts')
WITH(Charge_Id int , Amount money, FineType_Id int, user_id int )AS JSON
END
ELSE-- Check if amount is the same if yes do not update current record and enter a new one
IF @AmountDB <> @AmountJSON
BEGIN
UPDATE Fine set DateExpired= GETDATE(), ExpiryDescription ='Updated by'+ CONVERT(NVARCHAR(10), JSON.user_id)
FROM OPENJSON(@JSON,'$.amounts')
WITH(Charge_Id int , Amount money, FineType_Id int, user_id int )AS JSON
WHERE Fine.Charge_Id =JSON.Charge_Id and Fine.FineType_Id=JSON.FineType_Id
INSERT INTO Fine (Charge_Id,Amount,FineType_Id,user_id)
SELECT *
FROM OPENJSON(@JSON,'$.amounts')
WITH(Charge_Id int, Amount money, FineType_Id int, user_id int)AS JSON
END
END
显然,vailarables示例@chargeID被json文件中的最后一个元素覆盖。这工作
SELECT *
FROM OPENJSON(@JSON,'$.amounts[0]')
WITH(Charge_Id int, Amount money, FineType_Id int, user_id int)AS JSON
我希望做类似下面的事情但是使用计数器,因为JSON文件并不总是相同。它可能只有一个元素,上面的内容将正常工作,但如果它有4个元素则不起作用
SELECT *
FROM OPENJSON(@JSON,'$.amounts[+'@Counter'+]')
WITH(Charge_Id int, Amount money, FineType_Id int, user_id int)AS JSON
但这引发了一次错误。传递的JSON类似于下面的
> "amounts": [
> {
> "Charge_Id": "368",
> "Amount": "800",
> "FineType_Id": 3,
> "user_id": 2
> },
> {
> "Charge_Id": "368",
> "Amount": "600",
> "FineType_Id": 4,
> "user_id": 2
> } ]
请帮忙
答案 0 :(得分:1)
如果我正确理解您的评论,您实际上并不想从json
中提取特定项目,而是希望对返回的每条记录执行某些操作。
如果这是正确的,您只需要在设计的基础上使用SQL。例如,此脚本返回一个附加列,用于检查Amount
列中的值是否小于700
:
declare @JSON nvarchar(max)
declare @counter int
set @JSON ='{
"amounts": [
{
"Charge_Id": "368",
"Amount": "800",
"FineType_Id": 3,
"user_id": 2
},
{
"Charge_Id": "368",
"Amount": "400",
"FineType_Id": 4,
"user_id": 2
}
]
}';
select j.*
,case when j.Amount < 700
then 'Less than £700'
else 'Not less than £700'
end as col
from openjson(@JSON,'$.amounts') with (Charge_Id int, Amount money, FineType_Id int, user_id int) as j;
哪个输出:
+-----------+--------+-------------+---------+-------------------+
| Charge_Id | Amount | FineType_Id | user_id | col |
+-----------+--------+-------------+---------+-------------------+
| 368 | 800.00 | 3 | 2 | Not less than 700 |
| 368 | 400.00 | 4 | 2 | Less than 700 |
+-----------+--------+-------------+---------+-------------------+
如果您希望基于update
数据执行某些insert
,delete
或json
操作,您还可以在基于正常SQL集的方式中执行这些操作
如果您需要对json
数据进行一些额外的过滤,您可以像其他任何查询一样放入where
子句。将脚本更改为以下内容只会为FineType_id
3
的记录返回一行:
select j.*
,case when j.Amount < 700
then 'Less than 700'
else 'Not less than 700'
end as col
from openjson(@JSON,'$.amounts') with (Charge_Id int, Amount money, FineType_Id int, user_id int) as j
where j.FineType_id = 3;