SSIS C#脚本任务源反序列化JSon每行一个条目
我必须假设我是一个SQL的家伙,而不是C#的家伙 我必须接受这样一个JSon:SSIS C#脚本任务源反序列化JSon每行一个条目,c#,json,ssis,C#,Json,Ssis,我必须假设我是一个SQL的家伙,而不是C#的家伙 我必须接受这样一个JSon: [ { "gameId": "a_string_id", "name": "A string with the name", "width": 1280, "height": 720, "description": "A lot
[
{
"gameId": "a_string_id",
"name": "A string with the name",
"width": 1280,
"height": 720,
"description": "A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble",
"themeUrl": "/address1/address2/address3/filename.jpg",
"thumbnailUrl": "/address1/address2/address3/filename.jpg",
"verticalThumbnailUrl": "",
"helpUrl": "",
"trivia": [],
"traits": [
"aString"
],
"seoName": "a-long-name",
"friendlyName": "a-friendly-name"
},
{
"gameId": "a_string_id",
"name": "A string with the name",
"width": 1600,
"height": 878,
"description": "",
"themeUrl": "/address1/address2/address3/filename.jpg",
"thumbnailUrl": "/address1/address2/address3/filename.jpg",
"verticalThumbnailUrl": "",
"helpUrl": "",
"trivia": [],
"traits": [],
"seoName": "a-long-name",
"friendlyName": "a-friendly-name"
}
]
我需要使用脚本任务源来执行此操作。
我需要将json的一个实体放在每一行中,最好已经分隔成列,因为整个json非常长,并且没有这样的变量可以包含它
我的代码如下:
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Collections.Generic;
using System.Net;
using System.Web.Script.Serialization;
using System.Collections;
/// <summary>
/// This is the class to which to add your code. Do not change the name, attributes, or parent
/// of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
/// <summary>
/// This method is called once, before rows begin to be processed in the data flow.
///
/// You can remove this method if you don't need to do anything here.
/// </summary>
public override void PreExecute()
{
base.PreExecute();
}
/// <summary>
/// This method is called after all the rows have passed through this component.
///
/// You can delete this method if you don't need to do anything here.
/// </summary>
public override void PostExecute()
{
base.PostExecute();
}
public override void CreateNewOutputRows()
{
/*
Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
*/
String json = DownloadJson("http://someapi.com");
// Convert json string to .net object using the old school JavaScriptSerializer class
//JavaScriptSerializer serialize = new JavaScriptSerializer();
//Root righe = (Root)serialize.Deserialize(json, typeof(Root));
// Loop through array of earthquakes, outputing desired values to SSIS buffer
//foreach (var feature in righe.MyArray)
//{
// Output0Buffer.AddRow();
// Output0Buffer.gameid = feature.gameid;
//}
Output0Buffer.AddRow();
Output0Buffer.gameid = json;
}
public static string DownloadJson(string downloadURL)
{
using (WebClient client = new WebClient())
{
return client.DownloadString(downloadURL);
}
}
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class MyArray
{
public string gameId { get; set; }
public string name { get; set; }
public int width { get; set; }
public int height { get; set; }
public string description { get; set; }
public string themeUrl { get; set; }
public string thumbnailUrl { get; set; }
public string verticalThumbnailUrl { get; set; }
public string helpUrl { get; set; }
public List<string> trivia { get; set; }
public List<object> traits { get; set; }
public string seoName { get; set; }
public string friendlyName { get; set; }
internal static IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
public string gameid { get; set; }
}
public class Root
{
public List<MyArray> MyArray { get; set; }
}
public class MyArrayList : IEnumerable<MyArray>
{
private List<MyArray> carbootsales;
public IEnumerator<MyArray> GetEnumerator()
{
return carbootsales.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return MyArray.GetEnumerator();
}
}
}
使用系统;
使用系统数据;
使用Microsoft.SqlServer.Dts.Pipeline.Wrapper;
使用Microsoft.SqlServer.Dts.Runtime.Wrapper;
使用System.Collections.Generic;
Net系统;
使用System.Web.Script.Serialization;
使用系统集合;
///
///这是要向其中添加代码的类。不要更改名称、属性或父级
///这个班的学生。
///
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
公共类ScriptMain:UserComponent
{
///
///在数据流中开始处理行之前,调用此方法一次。
///
///如果不需要在此处执行任何操作,可以删除此方法。
///
公共覆盖无效预执行()
{
base.PreExecute();
}
///
///此方法在所有行都通过此组件后调用。
///
///如果不需要在此处执行任何操作,可以删除此方法。
///
公共重写void PostExecute()
{
base.PostExecute();
}
公共覆盖无效CreateNewOutputRows()
{
/*
通过对名为“Buffer”的成员变量调用AddRow方法来添加行。
例如,如果输出名为“MyOutput”,则调用MyOutputBuffer.AddRow()。
*/
字符串json=下载json(“http://someapi.com");
//使用老式JavaScriptSerializer类将json字符串转换为.net对象
//JavaScriptSerializer serialize=新的JavaScriptSerializer();
//Root righe=(Root)序列化。反序列化(json,typeof(Root));
//循环遍历地震数组,将所需值输出到SSIS缓冲区
//foreach(righe.MyArray中的var特性)
//{
//Output0Buffer.AddRow();
//Output0Buffer.gameid=feature.gameid;
//}
Output0Buffer.AddRow();
Output0Buffer.gameid=json;
}
公共静态字符串下载JSON(字符串下载URL)
{
使用(WebClient=newWebClient())
{
返回client.DownloadString(downloadURL);
}
}
//根myDeserializedClass=JsonConvert.DeserializeObject(myJsonResponse);
公共类MyArray
{
公共字符串gameId{get;set;}
公共字符串名称{get;set;}
公共整数宽度{get;set;}
公共整数高度{get;set;}
公共字符串说明{get;set;}
公共字符串themeUrl{get;set;}
公共字符串thumbnailUrl{get;set;}
公共字符串verticalThumbnailUrl{get;set;}
公共字符串帮助URL{get;set;}
公共列表琐事{get;set;}
公共列表特征{get;set;}
公共字符串seoName{get;set;}
公共字符串friendlyName{get;set;}
内部静态IEnumerator GetEnumerator()
{
抛出新的NotImplementedException();
}
公共字符串gameid{get;set;}
}
公共类根
{
公共列表MyArray{get;set;}
}
公共类MyArrayList:IEnumerable
{
私人清单销售;
公共IEnumerator GetEnumerator()
{
返回carbootsales.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
返回MyArray.GetEnumerator();
}
}
}
现在,我只是尝试使用一列GameId
我收到的错误如下:
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Collections.Generic;
using System.Net;
using System.Web.Script.Serialization;
using System.Collections;
/// <summary>
/// This is the class to which to add your code. Do not change the name, attributes, or parent
/// of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
/// <summary>
/// This method is called once, before rows begin to be processed in the data flow.
///
/// You can remove this method if you don't need to do anything here.
/// </summary>
public override void PreExecute()
{
base.PreExecute();
}
/// <summary>
/// This method is called after all the rows have passed through this component.
///
/// You can delete this method if you don't need to do anything here.
/// </summary>
public override void PostExecute()
{
base.PostExecute();
}
public override void CreateNewOutputRows()
{
/*
Add rows by calling the AddRow method on the member variable named "<Output Name>Buffer".
For example, call MyOutputBuffer.AddRow() if your output was named "MyOutput".
*/
String json = DownloadJson("http://someapi.com");
// Convert json string to .net object using the old school JavaScriptSerializer class
//JavaScriptSerializer serialize = new JavaScriptSerializer();
//Root righe = (Root)serialize.Deserialize(json, typeof(Root));
// Loop through array of earthquakes, outputing desired values to SSIS buffer
//foreach (var feature in righe.MyArray)
//{
// Output0Buffer.AddRow();
// Output0Buffer.gameid = feature.gameid;
//}
Output0Buffer.AddRow();
Output0Buffer.gameid = json;
}
public static string DownloadJson(string downloadURL)
{
using (WebClient client = new WebClient())
{
return client.DownloadString(downloadURL);
}
}
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class MyArray
{
public string gameId { get; set; }
public string name { get; set; }
public int width { get; set; }
public int height { get; set; }
public string description { get; set; }
public string themeUrl { get; set; }
public string thumbnailUrl { get; set; }
public string verticalThumbnailUrl { get; set; }
public string helpUrl { get; set; }
public List<string> trivia { get; set; }
public List<object> traits { get; set; }
public string seoName { get; set; }
public string friendlyName { get; set; }
internal static IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
public string gameid { get; set; }
}
public class Root
{
public List<MyArray> MyArray { get; set; }
}
public class MyArrayList : IEnumerable<MyArray>
{
private List<MyArray> carbootsales;
public IEnumerator<MyArray> GetEnumerator()
{
return carbootsales.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return MyArray.GetEnumerator();
}
}
}
位于Microsoft.SqlServer.Dts.Pipeline.PipelineBuffer.SetString(Int32 columnIndex,字符串值)
位于Microsoft.SqlServer.Dts.Pipeline.PipelineBuffer.set_项(Int32 columnIndex,对象值)
在ScriptMain.CreateNewOutputRows()处
在UserComponent.PrimeOutput(Int32输出、Int32[]输出、PipelineBuffer[]缓冲区、OutputNameMap输出映射)
位于Microsoft.SqlServer.Dts.Pipeline.ScriptComponentHost.PrimeOutput(Int32输出、Int32[]输出、PipelineBuffer[]缓冲区)
这个错误对我来说是阿拉伯语
如果有人能提供帮助,甚至提出解决问题的新方法,那就太好了
谢谢此代码块引发异常
String json = DownloadJson("http://someapi.com");
Output0Buffer.AddRow();
Output0Buffer.gameid = json;
它可能会溢出您为字符串列定义的任何长度。但是,我有一个午餐时间,所以你有一个解决办法;)
我做了什么不同
我定义了一个成员变量myArray
,它是myArray类型的老式数组。当我们将json转换为对象时,这将是每项级别的列表(game1、game2等)
在我的PreExecute方法中,我将下载json并将其转换为以数组形式键入的类的In实例
当我试图解包json时,遇到了不明确的定义错误,我点击了根MyArrayList定义
我从MyArray类中删除了枚举数和小写的gameid
,因为json表明它应该是gameid
在我的CreateNewOutputRows中,我将枚举整个成员数组,对于我找到的每个项,我将向输出缓冲区添加一个新行,然后用数据填充它
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Collections.Generic;
using System.Net;
// Add reference to System.Web.Extensions
using System.Web.Script.Serialization;
using System.Collections;
// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class MyArray
{
public string gameId { get; set; }
public string name { get; set; }
public int width { get; set; }
public int height { get; set; }
public string description { get; set; }
public string themeUrl { get; set; }
public string thumbnailUrl { get; set; }
public string verticalThumbnailUrl { get; set; }
public string helpUrl { get; set; }
public List<string> trivia { get; set; }
public List<object> traits { get; set; }
public string seoName { get; set; }
public string friendlyName { get; set; }
}
/// <summary>
/// This is the class to which to add your code. Do not change the name, attributes, or parent
/// of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
//Root rootDocument;
MyArray[] myArray;
public string DownloadJson(string downloadURL)
{
return @"[
{
'gameId': 'a_string_id',
'name': 'A string with the name',
'width': 1280,
'height': 720,
'description': 'A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble A lot of mumble jumble',
'themeUrl': '/address1/address2/address3/filename.jpg',
'thumbnailUrl': '/address1/address2/address3/filename.jpg',
'verticalThumbnailUrl': '',
'helpUrl': '',
'trivia': [],
'traits': [
'aString'
],
'seoName': 'a-long-name',
'friendlyName': 'a-friendly-name'
},
{
'gameId': 'a_string_id',
'name': 'A string with the name',
'width': 1600,
'height': 878,
'description': '',
'themeUrl': '/address1/address2/address3/filename.jpg',
'thumbnailUrl': '/address1/address2/address3/filename.jpg',
'verticalThumbnailUrl': '',
'helpUrl': '',
'trivia': [],
'traits': [],
'seoName': 'a-long-name',
'friendlyName': 'a-friendly-name'
}
]";
//using (WebClient client = new WebClient())
//{
// return client.DownloadString(downloadURL);
//}
}
public override void PreExecute()
{
base.PreExecute();
// You likely want to have this as a Variable and passed in to the method
string json = DownloadJson("http://someapi.com");
JavaScriptSerializer serialize = new JavaScriptSerializer();
myArray = serialize.Deserialize<MyArray[]>(json);
}
/// <summary>
/// This method is called after all the rows have passed through this component.
///
/// You can delete this method if you don't need to do anything here.
/// </summary>
public override void PostExecute()
{
base.PostExecute();
}
public override void CreateNewOutputRows()
{
foreach (var item in this.myArray)
{
Output0Buffer.AddRow();
Output0Buffer.gameid = item.gameId;
Output0Buffer.height = item.height;
Output0Buffer.width = item.width;
Output0Buffer.name = item.name;
}
}
}
该代码大致正确,但不会检查这些集合是否为null,也不会检查其中是否已存在分隔符。无论如何,这是由数据知识工作者决定的
另一种方法可能是创建一个OutputRivaBuffer,并通过单独的路径发送gameId和单个琐事值
根本没有错误处理,因此您需要加强此代码
您可能希望使用