无法将数据从 JSON 插入 SQL 服务器 table

Unable to insert data from the JSON in to the SQL server table

我正在尝试创建一个调用 REST API 并将响应插入到 Azure SQL 服务器 table 的 SSIS 包。为此,我正在使用脚本任务和 ADO.NET 连接管理器。 API 响应采用 JSON 格式,如下所示

{[
  {"id": 1,    "name": "AX",    "description": "B",    "shippingFreeze": false,    "receivingFreeze": false,    "mouseNorovirus": false,    "irradiatedFeed": true,    "createdAt": "2022-02-24T10:03:50.09",    "lastUpdated": "2022-02-24T10:03:50.09"  }, 

 {"id": 2,    "name": "PD ",    "description": "F",    "shippingFreeze": false,    "receivingFreeze": false,    "mouseNorovirus": false,    "irradiatedFeed": false,    "createdAt": "2022-02-24T10:03:50.09",    "lastUpdated": "2022-02-24T10:03:50.09"  }
]}

Table 在 SQL 服务器中

我正在尝试遍历 JSON 并将它们中的每一个插入到 SQL 服务器 tables,如下所示

var result = response.Content.ReadAsStringAsync().Result;
dynamic res_JSON = JsonConvert.DeserializeObject(result);

ConnectionManager cm = Dts.Connections["SurplusMouse_ADONET"];
var sqlConn = (System.Data.SqlClient.SqlConnection)cm.AcquireConnection(Dts.Transaction);

 using (var sqlCmd = new System.Data.SqlClient.SqlCommand("INSERT INTO [dbo].[RM_Room]([ROOMID],[NAME],[DESCRIPTION],[SHIPPING_FREEZE],[RECEIVING_FREEZE],[MOUSE_NOROVIRUS],[IRRADIATED_FEED]) VALUES(@ROOMID,@NAME,@DESCRIPTION,@SHIPPING_FREEZE,@RECEIVING_FREEZE,@MOUSE_NOROVIRUS,@IRRADIATED_FEED,)", sqlConn))
  {
     foreach (var jsonObj in res_JSON)
      {
         sqlCmd.CommandType = CommandType.Text;
         sqlCmd.Parameters.AddWithValue("@ROOMID", jsonObj.id.ToString());              
         sqlCmd.Parameters.AddWithValue("@NAME", jsonObj.name.ToString());
         sqlCmd.Parameters.AddWithValue("@DESCRIPTION", jsonObj.description.ToString());
         sqlCmd.Parameters.AddWithValue("@SHIPPING_FREEZE", (jsonObj.shippingFreeze.ToString() == "true") ? "T" : "F");
         sqlCmd.Parameters.AddWithValue("@RECEIVING_FREEZE", (jsonObj.receivingFreeze.ToString() == "true") ? "T" : "F");
         sqlCmd.Parameters.AddWithValue("@MOUSE_NOROVIRUS", (jsonObj.mouseNorovirus.ToString() == "true") ? "T" : "F");
         sqlCmd.Parameters.AddWithValue("@IRRADIATED_FEED", (jsonObj.irradiatedFeed.ToString() == "true") ? "T" : "F");
         int no_exec = sqlCmd.ExecuteNonQuery();
     }
   }
   cm.ReleaseConnection(sqlConn);
  }}
  catch (Exception ex)
  {
    Dts.TaskResult = (int)ScriptResults.Failure;
  }

当我调试时抛出类似

的错误

和堆栈跟踪

at System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,Boolean breakConnection,Action1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action1 wrapCloseInAction) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj,布尔调用者有连接锁,布尔异步关闭) 在 System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior、SqlCommand cmdHandler、SqlDataReader dataStream、BulkCopySimpleResultSet bulkCopyHandler、TdsParserStateObject stateObj、Boolean& dataReady) 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds、RunBehavior runBehavior、字符串 resetOptionsString、布尔值 isInternal、布尔值 forDescribeParameterEncryption、布尔值 shouldCacheForAlwaysEncrypted) 在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior runBehavior、Boolean returnStream、Boolean async、Int32 timeout、Task& task、Boolean asyncWrite、Boolean inRetry、SqlDataReader ds、Boolean describeParameterEncryptionRequest) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior runBehavior、Boolean returnStream、String 方法、TaskCompletionSource1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource1 完成、String methodName、Boolean sendToPipe、Int32 超时、Boolean& usedCache、Boolean asyncWrite、Boolean inRetry) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在 ST_b0ab9fccfaa640008ecd1bdf57ec4324.ScriptMain.Main() 在 C:\Users\dv_admin\AppData\Local\Temp\vstaff553a1bba27\ScriptMain.cs:line 76

我不确定我在这里缺少什么。非常感谢任何帮助

更新代码

   public async void Main()
    {
        try
        {
            var sqlConn = new System.Data.SqlClient.SqlConnection();
            ConnectionManager cm = Dts.Connections["SurplusMouse_ADONET"];

            string serviceUrl = Dts.Variables["$Project::ServiceUrl"].Value.ToString();
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri(serviceUrl);
           client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
            string APIUrl = string.Format(serviceUrl + "/rooms");
            var response = client.GetAsync(APIUrl).Result;
            if (response.IsSuccessStatusCode)
            {
                var result = await response.Content.ReadAsStringAsync();

                try
                {
                    sqlConn = (System.Data.SqlClient.SqlConnection)cm.AcquireConnection(Dts.Transaction);
                    const string query = @"INSERT INTO dbo.RM_Room
                                      (ROOMID, NAME, DESCRIPTION, SHIPPING_FREEZE, RECEIVING_FREEZE, MOUSE_NOROVIRUS, IRRADIATED_FEED)
                                       SELECT id, name, description,
                                              CASE shippingFreeze WHEN 1 THEN 'T' ELSE 'F' END,
                                              CASE receivingFreeze WHEN 1 THEN 'T' ELSE 'F' END,
                                              CASE mouseNorovirus WHEN 1 THEN 'T' ELSE 'F' END,
                                              CASE irradiatedFeed WHEN 1 THEN 'T' ELSE 'F' END
                                       FROM OPENJSON(@json)
                                       WITH (
                                             id int,
                                             name varchar(100),
                                             description varchar(1000),
                                             shippingFreeze bit,
                                             receivingFreeze bit,
                                             mouseNorovirus bit,
                                             irradiatedFeed bit
                                             ) j;";
                    using (var sqlCmd = new System.Data.SqlClient.SqlCommand(query, sqlConn))
                    {
                        sqlCmd.Parameters.Add("@json", SqlDbType.NVarChar, -1).Value = result;
                        await sqlConn.OpenAsync();
                        await sqlCmd.ExecuteNonQueryAsync();
                    }
                }
                catch (Exception ex)
                {
                    Dts.TaskResult = (int)ScriptResults.Failure;
                }
                finally
                {
                    if (sqlConn != null)
                        cm.ReleaseConnection(sqlConn);
                }

            }
        }
        catch (Exception ex)
        {
            Dts.TaskResult = (int)ScriptResults.Failure;
        }
    }

您的主要问题是 SQL 中多了一个逗号,这是一个语法错误。

将整个 JSON 传递给 SQL 服务器并使用 OPENJSON

粉碎它可能更容易
var result = await response.Content.ReadAsStringAsync();

ConnectionManager cm = Dts.Connections["SurplusMouse_ADONET"];

SqlConnection sqlConn = null;
try
{
    sqlConn = (SqlConnection)cm.AcquireConnection(Dts.Transaction));
    const string query = @"
INSERT INTO dbo.RM_Room
  (ROOMID, NAME, DESCRIPTION, SHIPPING_FREEZE, RECEIVING_FREEZE, MOUSE_NOROVIRUS, IRRADIATED_FEED)
SELECT
  id,
  name,
  description,
  CASE shippingFreeze WHEN 1 THEN 'T' ELSE 'F' END,
  CASE receivingFreeze WHEN 1 THEN 'T' ELSE 'F' END,
  CASE mouseNorovirus WHEN 1 THEN 'T' ELSE 'F' END,
  CASE irradiatedFeed WHEN 1 THEN 'T' ELSE 'F' END
FROM OPENJSON(@json)
  WITH (
    id int,
    name varchar(100),
    description varchar(1000),
    shippingFreeze bit,
    receivingFreeze bit,
    mouseNorovirus bit,
    irradiatedFeed bit
  ) j;
";
    using (var sqlCmd = new SqlCommand(query, sqlConn))
    {
        sqlCmd.Parameters.Add("@json", SqlDbType.NVarChar, -1).Value = result; 
        await sqlCmd.ExecuteNonQueryAsync();
    }
}
catch (Exception ex)
{
    Dts.TaskResult = (int)ScriptResults.Failure;
}
finally
{
    if(sqlConn != null)
        cm.ReleaseConnection(sqlConn);
}

备注:

  • sqlCmd.CommandType = CommandType.Text 是不必要的。
  • ReleaseConnection 需要在 finally
  • 尽管不清楚您一开始为什么要使用 ConnectionManager。您可能应该直接创建 SqlConnection,然后将其放入 using
  • 避免AddWithValue,而是明确指定类型和长度。
  • 使用 Async 版本的代码 await不要调用.Result,否则你可能会死锁。