将附件从 SP 迁移到 SQL BLOB
Migrating attachments from SP to SQL BLOB
我需要将大量附件从 SharePoint 中的多个列表移动到 SQL 中的 BLOB table。我找到了允许我将附件下载到本地驱动器的代码,但我无法修改它以将其作为二进制数据直接加载到 SharePoint 中。
using Microsoft.SharePoint.Client;
using System;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void CreateNewOutputRows()
{
try
{
int startListID = 1;
String siteUrl = "https://mysharepointsite.com/sites/mysite";
String listName = "AttachmentTesting";
NetworkCredential credentials =
new NetworkCredential("username", "password", "domain");
using (ClientContext clientContext = new ClientContext(siteUrl))
{
clientContext.Credentials = credentials;
//Get the Site Collection
Site oSite = clientContext.Site;
clientContext.Load(oSite);
clientContext.ExecuteQuery();
// Get the Web
Web oWeb = clientContext.Web;
clientContext.Load(oWeb);
clientContext.ExecuteQuery();
CamlQuery query = new CamlQuery();
query.ViewXml = @"";
List oList = clientContext.Web.Lists.GetByTitle(listName);
clientContext.Load(oList);
clientContext.ExecuteQuery();
ListItemCollection items = oList.GetItems(query);
clientContext.Load(items);
clientContext.ExecuteQuery();
foreach (ListItem listItem in items)
{
if (Int32.Parse(listItem["ID"].ToString()) >= startListID)
{
Folder folder =
oWeb.GetFolderByServerRelativeUrl(oSite.Url +
"/Lists/" + listName + "/Attachments/" +
listItem["ID"]);
clientContext.Load(folder);
try
{
clientContext.ExecuteQuery();
}
catch (ServerException ex)
{
}
FileCollection attachments = folder.Files;
clientContext.Load(attachments);
clientContext.ExecuteQuery();
foreach (Microsoft.SharePoint.Client.File oFile in folder.Files)
{
FileInfo myFileinfo = new FileInfo(oFile.Name);
WebClient client1 = new WebClient();
client1.Credentials = credentials;
byte[] fileContents =
client1.DownloadData("https://mysharepointsite.com" +
oFile.ServerRelativeUrl);
}
}
}
}
}
catch (Exception e)
{
}
}
}
最后的filestream只是为了测试前面的代码,它成功地检索了附件。现在我需要进行下一步并将其加载到某种缓冲区中以推入 SQL。我试过使用:
Output0Buffer.AddRow();
Output0Buffer.fileName = oFile.Name;
在循环内部和最后的 Output0Buffer.SetEndOfRowset();
但这给出了一个错误:
[Import Column [2]] Error: SSIS Error Code DTS_E_INDUCEDTRANSFORMFAILUREONERROR. The "Import Column" failed because error code 0xC02090BB occurred, and the error row disposition on "Import Column.Inputs[Import Column Input].Columns[fileName]" specifies failure on error. An error occurred on the specified object of the specified component. There may be error messages posted before this with more information about the failure.
如何执行将字节数组文件内容推送到 SQL table blob 列的最后一步?
非常感谢。
编辑:我应该省略 fstream。那只是为了测试目的。我想要做的是将附件直接从 SharePoint 推送到 SQL,而无需将其存储在本地的中间步骤。
您应该使用本地驱动器中的路径。
string path = "C:\Temp\" + oFile.Name;
FileStream fStream = new FileStream(path, FileMode.Create);
fStream.Write(fileContents, 0, fileContents.Length);
fStream.Close();
Output0Buffer.AddRow();
Output0Buffer.fileName = path;
// ... after foreach loop
Output0Buffer.SetEndOfRowset();
已解决!
感谢 tinamou 的回答,但我应该提到我试图避免将文件放在本地驱动器上的中间步骤。
我通过向名为 "fileBinary" 的脚本组件添加另一个输出并使用 AddBlobData 方法用我的字节数组填充它来解决它。
byte[] fileContents = client1.DownloadData("https://mysharepointsite.com/sites/mysite" +
oFile.ServerRelativeUrl);
Output0Buffer.AddRow();
Output0Buffer.fileName = oFile.Name;
Output0Buffer.fileBinary.AddBlobData(fileContents);
然后在我所有的 FOR 循环之外(也由 tinamou 建议):
Output0Buffer.SetEndOfRowset();
我需要将大量附件从 SharePoint 中的多个列表移动到 SQL 中的 BLOB table。我找到了允许我将附件下载到本地驱动器的代码,但我无法修改它以将其作为二进制数据直接加载到 SharePoint 中。
using Microsoft.SharePoint.Client;
using System;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
public override void CreateNewOutputRows()
{
try
{
int startListID = 1;
String siteUrl = "https://mysharepointsite.com/sites/mysite";
String listName = "AttachmentTesting";
NetworkCredential credentials =
new NetworkCredential("username", "password", "domain");
using (ClientContext clientContext = new ClientContext(siteUrl))
{
clientContext.Credentials = credentials;
//Get the Site Collection
Site oSite = clientContext.Site;
clientContext.Load(oSite);
clientContext.ExecuteQuery();
// Get the Web
Web oWeb = clientContext.Web;
clientContext.Load(oWeb);
clientContext.ExecuteQuery();
CamlQuery query = new CamlQuery();
query.ViewXml = @"";
List oList = clientContext.Web.Lists.GetByTitle(listName);
clientContext.Load(oList);
clientContext.ExecuteQuery();
ListItemCollection items = oList.GetItems(query);
clientContext.Load(items);
clientContext.ExecuteQuery();
foreach (ListItem listItem in items)
{
if (Int32.Parse(listItem["ID"].ToString()) >= startListID)
{
Folder folder =
oWeb.GetFolderByServerRelativeUrl(oSite.Url +
"/Lists/" + listName + "/Attachments/" +
listItem["ID"]);
clientContext.Load(folder);
try
{
clientContext.ExecuteQuery();
}
catch (ServerException ex)
{
}
FileCollection attachments = folder.Files;
clientContext.Load(attachments);
clientContext.ExecuteQuery();
foreach (Microsoft.SharePoint.Client.File oFile in folder.Files)
{
FileInfo myFileinfo = new FileInfo(oFile.Name);
WebClient client1 = new WebClient();
client1.Credentials = credentials;
byte[] fileContents =
client1.DownloadData("https://mysharepointsite.com" +
oFile.ServerRelativeUrl);
}
}
}
}
}
catch (Exception e)
{
}
}
}
最后的filestream只是为了测试前面的代码,它成功地检索了附件。现在我需要进行下一步并将其加载到某种缓冲区中以推入 SQL。我试过使用:
Output0Buffer.AddRow();
Output0Buffer.fileName = oFile.Name;
在循环内部和最后的 Output0Buffer.SetEndOfRowset();
但这给出了一个错误:
[Import Column [2]] Error: SSIS Error Code DTS_E_INDUCEDTRANSFORMFAILUREONERROR. The "Import Column" failed because error code 0xC02090BB occurred, and the error row disposition on "Import Column.Inputs[Import Column Input].Columns[fileName]" specifies failure on error. An error occurred on the specified object of the specified component. There may be error messages posted before this with more information about the failure.
如何执行将字节数组文件内容推送到 SQL table blob 列的最后一步? 非常感谢。
编辑:我应该省略 fstream。那只是为了测试目的。我想要做的是将附件直接从 SharePoint 推送到 SQL,而无需将其存储在本地的中间步骤。
您应该使用本地驱动器中的路径。
string path = "C:\Temp\" + oFile.Name;
FileStream fStream = new FileStream(path, FileMode.Create);
fStream.Write(fileContents, 0, fileContents.Length);
fStream.Close();
Output0Buffer.AddRow();
Output0Buffer.fileName = path;
// ... after foreach loop
Output0Buffer.SetEndOfRowset();
已解决!
感谢 tinamou 的回答,但我应该提到我试图避免将文件放在本地驱动器上的中间步骤。
我通过向名为 "fileBinary" 的脚本组件添加另一个输出并使用 AddBlobData 方法用我的字节数组填充它来解决它。
byte[] fileContents = client1.DownloadData("https://mysharepointsite.com/sites/mysite" +
oFile.ServerRelativeUrl);
Output0Buffer.AddRow();
Output0Buffer.fileName = oFile.Name;
Output0Buffer.fileBinary.AddBlobData(fileContents);
然后在我所有的 FOR 循环之外(也由 tinamou 建议):
Output0Buffer.SetEndOfRowset();