skip to Main Content

I would like to parse this Json response file coming from a rest api to a MS SQL table in C# as I don’t want to loop multiple times as the files could be big.
I only need the nested block PolicyPayrolls Policy Details to be stored into a table. Is there any way I can store parse this nested block inserted into a table. How do I approach it?


      {
   "ValidationErrors":[
      
   ],
   "ApplicationExceptions":[
      
   ],
   "PageSize":2,
   "CurrentPageIndex":1,
   "NextPageIndex":2,
   "PolicyStatus":"CANCELLED",
   "PayrollStatus":"OUTSTANDING",
   "PolicyPayrolls":[
      {
         "PolicyDetails":{
            "PolicyName":"Test 1",
            "PolicyHeaderId":1133,
            "GroupIdn":"",
            "PolicyNumber":234,
            "PolicyUnitNumber":16612,
            "PolicyYearDate":"2022",
            "PolicySuffixCode":"",
            "InceptionDate":"2022-01-08T00:00:00",
            "ExpirationnDate":"2023-01-08T00:00:00",
            "BillPlanType":"STIPULATED"
         },
         "PayrollDetails":[
            {
               "PayrollId":1284,
               "PayrollStatus":"Outstanding",
               "StartDate":"2022-01-08T00:00:00",
               "EndDate":"2022-06-06T00:00:00",
               "DueDate":"2022-07-07T18:59:08.0316001"
            }
         ]
      },
      {
         "PolicyDetails":{
            "PolicyName":"TEST POLICY 2313",
            "PolicyHeaderId":625,
            "GroupIdn":"",
            "PolicyNumber":4381,
            "PolicyUnitNumber":193,
            "PolicyYearDate":"2021",
            "PolicySuffixCode":"",
            "InceptionDate":"2021-07-01T00:00:00",
            "ExpirationnDate":"2022-07-01T00:00:00",
            "BillPlanType":"STIPULATED"
         },
         "PayrollDetails":[
            {
               "PayrollId":1200,
               "PayrollStatus":"Outstanding",
               "StartDate":"2022-01-01T00:00:00",
               "EndDate":"2022-06-06T00:00:00",
               "DueDate":"2022-07-07T18:58:06.0948818"
            }
         ]
      }
   ],
   "PolicyUnitNumber":0,
   "PolicyYearDate":null,
   "SucessResult":true,
   "ResultCount":69
}

DDL

 CREATE TABLE [DBO].[POLICY_OUTSTANDING](
  [Id] [bigint] IDENTITY(1,1) NOT NULL,
  [PolicyYear] [varchar](50) NULL,
  [PolicySuffix] [varchar](20) NULL,
  [PolicyUnitNumber] [varchar](50) NULL,
  [PolicyGroupId] [varchar](50) NULL,
  [CreatedBy] [varchar](20) NOT NULL DEFAULT ('DEVDB'),
  [CreatedDate] [datetime2](7) NOT NULL CONSTRAINT [DC_PolicyDue_CreatedDate]  DEFAULT (getdate()),
  [UpdatedBy] [varchar](20) NOT NULL CONSTRAINT [DC_PolicyDue_ModifiedBy]  DEFAULT ('DEVDB'),
  [UpdatedDate] [datetime2](7) NOT NULL CONSTRAINT [DC_PolicyDue_ModifiedDate]  DEFAULT (getdate()),
  [InceptionDate] [datetime2](7) NULL,
  [ExpirationDate] [datetime2](7) NULL,
  [PolicyNumber] INT NULL,
    CONSTRAINT [PK_PolicyDue] PRIMARY KEY CLUSTERED 
     (
   [Id] ASC
     )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
     IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS 
     = ON) ON [PRIMARY]
     ) ON [PRIMARY]

     GO

Edit: Needed to parse the Json and insert into a db table in C#.

EDit:
I am able to do OPENJSON in MS SQL. But I need to do it in C# code without looping and do a Bulk Insert as I may have to process 2000 records in one go.

2

Answers


  1. It is SQL server, right? Although JSON capabilities of SQL server is not much (compared to say postgreSQL), still you can use OpenJson(), Json_value(). ie:

    SELECT pd.pn,
           pd.phid,
           pd.gid,
           pd.pnum,
           pd.punit,
           pd.pyear,
           pd.psuffix,
           pd.incedption,
           pd.expires,
           pd.plantype,
           PayrollId,
           PayrollStatus,
           StartDate,
           EndDate,
           DueDate
    FROM
        OPENJSON(@json)
        WITH
        (
            PolicyPayrolls NVARCHAR(MAX) AS JSON
        ) t
        CROSS APPLY
        OPENJSON(t.PolicyPayrolls)
        WITH
        (
            PolicyDetails NVARCHAR(MAX) AS JSON,
            PayrollDetails NVARCHAR(MAX) AS JSON
        ) pp
        CROSS APPLY
    (
        SELECT JSON_VALUE(pp.PolicyDetails, '$.PolicyName'),
               JSON_VALUE(pp.PolicyDetails, '$.PolicyHeaderId'),
               JSON_VALUE(pp.PolicyDetails, '$.GroupIdn'),
               JSON_VALUE(pp.PolicyDetails, '$.PolicyNumber'),
               JSON_VALUE(pp.PolicyDetails, '$.PolicyUnitNumber'),
               JSON_VALUE(pp.PolicyDetails, '$.PolicyYearDate'),
               JSON_VALUE(pp.PolicyDetails, '$.PolicySuffixCode'),
               JSON_VALUE(pp.PolicyDetails, '$.InceptionDate'),
               JSON_VALUE(pp.PolicyDetails, '$.ExpirationnDate'),
               JSON_VALUE(pp.PolicyDetails, '$.BillPlanType')
    ) pd(pn, phid, gid, pnum, punit, pyear, psuffix, incedption, expires, plantype)
        CROSS APPLY
        OPENJSON(pp.PayrollDetails)
        WITH
        (
            PayrollId INT,
            PayrollStatus VARCHAR(20),
            StartDate DATE,
            EndDate DATE,
            DueDate DATE
        );
    

    DBFiddle demo is here

    EDIT: I didn’t notice C# there before. If you would do this in C# then it would be much easier really. You could create your matching classes and deserialize with it or use anonymous deseriliaztion with newtonsoft. ie:

    var policies = JsonConvert.DeserializeAnonymousType(json, new
    {
        PolicyPayrolls = new[] {
        new {
                PolicyDetails = new {
                PolicyName="",
                PolicyHeaderId=0,
                GroupIdn="",
                PolicyNumber=0,
                PolicyUnitNumber=0,
                PolicyYearDate=0,
                PolicySuffixCode="",
                InceptionDate=DateTime.Now,
                ExpirationnDate=DateTime.Now,
                BillPlanType=""
            },
        PayrollDetails = new[] {
                new {PayrollId=0,
               PayrollStatus="",
               StartDate=DateTime.Now,
               EndDate=DateTime.Now,
               DueDate=DateTime.Now}
            }
        }
        }
    });
    

    Result looks like:
    Result sample

    EDIT2: I think it is like this:

    You have a json file (or REST API result) that looks like the one in question but with many more items (2000+) ?
    And also a table matching the create table definition on the question
    You want the content of json be inserted into that table?
    And you want to insert from within C#.

    Then:

    Assuming databasename is SampleDb on server localhost, tablename is
    tmpPOLICY_OUTSTANDING and json comes from a file on
    "d:tempinsurance.json"

    void Main()
    {
        var sql = @"INSERT INTO dbo.tmpPOLICY_OUTSTANDING(PolicyYear, PolicySuffix, PolicyUnitNumber, PolicyGroupId, 
        InceptionDate, ExpirationDate, PolicyNumber)
    SELECT pd.PolicyYearDate, pd.PolicySuffixCode, pd.PolicyUnitNumber, pd.GroupIdn,
           pd.InceptionDate, pd.ExpirationnDate,pd.PolicyNumber
    FROM
        OPENJSON(@json) 
            WITH(PolicyPayrolls NVARCHAR(MAX) AS JSON) t
        CROSS APPLY OPENJSON(t.PolicyPayrolls)
            WITH(PolicyDetails NVARCHAR(MAX) AS JSON, PayrollDetails NVARCHAR(MAX) AS JSON) pp
        CROSS APPLY OPENJSON(pp.PolicyDetails)
            WITH(PolicyName VARCHAR(50), PolicyHeaderId VARCHAR(50), GroupIdn VARCHAR(50), 
            PolicyUnitNumber VARCHAR(50), PolicyNumber INT, PolicyYearDate VARCHAR(10), 
            PolicySuffixCode VARCHAR(50), InceptionDate DATE, ExpirationnDate DATE, BillPlanType VARCHAR(10)) pd
        CROSS APPLY OPENJSON(pp.PayrollDetails)
        WITH(PayrollId INT, PayrollStatus VARCHAR(20), StartDate DATE, EndDate DATE, DueDate DATE);
    ";
        using (SqlConnection cn = new SqlConnection("server=.;Database=SampleDb;Trusted_Connection=yes"))
        using (SqlCommand cmd = new SqlCommand(sql,cn))
        {
            cmd.Parameters.Add("@json", SqlDbType.VarChar).Value = File.ReadAllText(@"d:tempinsurance.json");
            
            cn.Open();
            cmd.ExecuteNonQuery();
            cn.Close();
        }
        Console.WriteLine("Done");
    }
    
    Login or Signup to reply.
  2. Take a look at Newtonsoft.Json Nuget package.
    I used it and it’s really simple; you could retrieve the entire field from MSSQL and then process it in your C# application.

    To parse text as a JToken:

    JToken token = JObect.Parse(text);
    

    To read a specific value:

    int age = token["age"].Value<int>();
    

    To browse children nodes:

    List<JToken> children = token.Children();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search