SSIS脚本组件源 - 通过Odata从SharePoint 365列表中读取
如果我的问题未得到充分描述,则表示歉意。我是一个.Net/C#/ SSIS新手。也道歉,如果已经回答,我已经尝试在这里搜索和谷歌几个小时没有运气。SSIS脚本组件源 - 通过Odata从SharePoint 365列表中读取
背景:我需要从SharePoint 365列表中提取数据行,并将某些列未转换为准备导入SQL Server表格的格式。我意识到SSIS有Odata Source和内置的Unpivot组件,并且我已经成功地将这些用于概念验证。
但是,我相信我需要一个自定义脚本组件,因为从源SharePoint列表中取消转换的列数是可变的。每个月左右,都会添加一个新列(它与SharePoint中的财务预测“工具”相关,以及最新的预测月份更改)。我的理解是,在设计时必须在SSIS中定义源列,因此如果我的源列发生更改,我可以考虑解决这个问题的唯一方法就是不用每个月手动更改SSIS数据流,都会以编程方式将Odata源和未转换函数到一个自定义脚本组件。
我明白,或可以弄清楚unpivot逻辑。我正在努力的部分是如何实际连接并公开给定列表,并将数据行/列作为列表进行循环显示,然后执行映射到输出列。
我的请求指导的“出发点”是这样的: 1)使用标准的SSIS Odata连接管理器创建并成功连接到有问题的SharePoint站点。 2)在视觉设计器上创建标准“脚本组件”,类型=源。 3)从脚本组件属性中,将Odata连接管理器与名称“myConnection”关联。 4)需要帮助 - >在脚本组件中,打开到特定列表的连接,读取它的内容,并执行unpivot逻辑。
出于说明的目的,假定源是一个SharePoint列表标题为研究和站点两个“固定”的字符串列,和列具有匹配月末日期名称(可变数目例如2016年9月30日, 10/31/2016等)包含整数值。我想将研究和网站源列映射到相同名称的目标列,并且未映射列名称映射到ProjectionMonth的月份列,并将整数值映射到ProjectionValue。
这里是基本的算法,我想到的(我知道这是不是编译 - 这就是我需要你的帮助!):
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.Data.SqlClient;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
IDTSConnectionManager100 connMgr;
SqlConnection sqlConn; // from MSDN tutorial, but I don't know how to adapt to Odata/SharePoint 365 list
SqlDataReader sqlReader; // not sure how to adapt
public override void AcquireConnections(object Transaction)
{
connMgr = this.Connections.myConnection;
sqlConn = (SqlConnection)connMgr.AcquireConnection(null); // This is from MSDN tutorial, but I don't know how to adapt to Odata
}
public override void PreExecute()
{
//Not sure how to adapt to odata to read specific SharePoint list
SqlCommand cmd = new SqlCommand("SELECT * FROM <some sharepoint list>", sqlConn);
sqlReader = cmd.ExecuteReader();
}
public override void PostExecute()
{
sqlReader.Close(); // Not sure how to adapt.
}
public override void CreateNewOutputRows()
{
string myStudy;
string mySite;
string myProjectionMonth;
string myProjectionValue;
// This is a rough representation of the logic needed.
// I realize that the actual code to access column values/names depends on the class(es) I need to use, but not sure what those classes are/how to access
foreach (myListRow in sqlConn.rows)
{
myStudy = myListRow.Columns["Study"].value;
mySite = myListRow.Columns["Site"].value;
foreach (myColumn in myListRow.Columns)
if (DateTime.TryParse(myColumn.Name, out dateValue))
{
myProjectionMonth = myColumn.Name;
myProjectionValue = myColumn.Value;
Output0Buffer.AddRow();
Output0Buffer.Study = myStudy;
Output0Buffer.Site = mySite;
Output0Buffer.ProjectionMonth = myProjectionMonth;
Output0Buffer.ProjectionValue = myProjectionValue;
}
}
}
}
编辑:为例,假设源SharePoint列表有以下几点:
Study Site 9/30/2016 10/31/2016
123 ABC 5 10
我想脚本组件连接到列表,查看它的内容,并返回以下逆转置数据最终加载到SQL设置服务器:
Study Site ProjectionMonth ProjectionValue
123 ABC 9/30/2016 5
123 ABC 10/31/2016 10
所以这可能不是这样做的一种理想的方式,并且它没有利用我想要的标准SSIS OData的连接管理器......但它在技术上完成任务和它的好现在足够我的了。
如果您有任何建议的反馈/改进/ /等,将有兴趣。
#region Namespaces
using System;
using Microsoft.SharePoint.Client;
using System.Security;
using System.Collections.Generic;
#endregion
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void CreateNewOutputRows()
{
// Connect to SharePoint
ClientContext context = new ClientContext("https://<redacted>.sharepoint.com/Development");
SecureString passWord = new SecureString();
foreach (char c in Variables.sharepointPassword.ToCharArray()) passWord.AppendChar(c);
context.Credentials = new SharePointOnlineCredentials("<redacted>@<redacted>.onmicrosoft.com", passWord);
// Define the target list
List EnrollmentList = context.Web.Lists.GetByTitle("Enrollment Projections");
// Find all fields in the target list
FieldCollection myFields = EnrollmentList.Fields;
context.Load(myFields);
context.ExecuteQuery();
// Load all rows from the target list
CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
ListItemCollection items = EnrollmentList.GetItems(query);
context.Load(items);
context.ExecuteQuery();
//Store valid date fields
List<Field> myDateFields = new List<Field>();
foreach (Field tempField in myFields)
{
DateTime tempDate;
if (DateTime.TryParse(tempField.Title, out tempDate))
{
myDateFields.Add(tempField);
}
}
string myStudy;
string mySite;
string myMonth;
string myValue;
foreach (ListItem listItem in items)
{
myStudy = listItem["Study"].ToString();
mySite = listItem["Site"].ToString();
foreach (Field tempField in myDateFields)
{
myMonth = tempField.Title;
myValue = listItem[tempField.InternalName.ToString()].ToString();
Output0Buffer.AddRow();
Output0Buffer.Study = myStudy;
Output0Buffer.Site = mySite;
Output0Buffer.ProjectedMonth = myMonth;
Output0Buffer.ProjectedValue = Convert.ToInt32(myValue);
}
}
}
}
您好,我昨天用,这不是可能重新使用连接管理器来填充网站/凭据脚本内clientContext结论结束了发现了类似的旅程。我通过传入参数并从中构建SharePointOnlineCredentials对象,最终做了或多或少的工作。 – sasfrog