【发布时间】:2018-02-15 01:55:50
【问题描述】:
我一直在尝试拼凑其他用户如何完成他们的项目,但我的理解仍然有限。
我想获取任何给定的 XML 源,创建一个数据流任务,并将其数据传递到与 XML 文件的表名匹配的 OLE DB 目标。使用可视化工具运行它意味着我无法执行动态数据流任务,因为元数据不会刷新。
我创建了一个创建包的脚本,但是当我在 Visual Studio 中打开包时,它有一个红色 x 表示输入列不能为零。当我向下钻取并查看 OLE DB 目标的映射时,然后单击确定 - 它会为我更正它。我无法弄清楚如何以编程方式做到这一点。
我看到其他人通过使用 foreach 循环并遍历输入列来解决它,但我似乎无法弄清楚。
我还有一个单独的脚本,我试图用它来模仿几个人的脚本,但它有不同的问题。不知道怎么发附件
提前感谢您的帮助:)
编辑
我在尝试 BIML 时得到了积极的反馈,我会的……但我想知道短期内是否有人可以帮助我弄清楚为什么这没有为我的输入填写 ExternalMetaDataColumnId。我在下面发布了我的更新代码,其中的 foreach 循环没有按照我的预期进行。
谢谢 #地区 使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Text; 使用 System.Threading.Tasks; 使用 Microsoft.SqlServer.Dts.Runtime; 使用 Microsoft.SqlServer.Dts.Pipeline.Wrapper; 使用 System.Xml; #endregion
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
#region Initial Setup
Application a = new Application();
Package p = new Package();
TaskHost t = p.Executables.Add("DTS.Pipeline") as TaskHost;
t.Name = "DataFlow Task";
t.Description = "Flat File to Database";
MainPipe mp = t.InnerObject as MainPipe;
#endregion
#region Flat File Source in Dataflow Task
IDTSComponentMetaData100 md = mp.ComponentMetaDataCollection.New();
md.ComponentClassID = "Microsoft.XmlSourceAdapter";
md.Name = "XML Source";
CManagedComponentWrapper wrp = md.Instantiate();
wrp.ProvideComponentProperties();
#endregion
#region Add connection manager to OLE DB
ConnectionManager conn = p.Connections.Add("OLEDB");
conn.Name = "westcoastuserDBO";
conn.ConnectionString = "Data Source=SERVER;Initial Catalog=DBO;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;";
#endregion
#region XML Source Properties
wrp.SetComponentProperty("XMLData", @"C:\Users\file.xml");
wrp.SetComponentProperty("XMLSchemaDefinition", @"C:\Users\file.xsd");
wrp.SetComponentProperty("AccessMode", 0);
wrp.SetComponentProperty("UseInlineSchema", false);
//below does not work
//wrp.SetComponentProperty("XMLIntegerMapping", 0).TypeConverter = "Microsoft.SqlServer.Dts.Pipeline.XmlSourceAdapter + XMLIntegerMappingConverter";
wrp.ReinitializeMetaData();
wrp.ReleaseConnections();
IDTSComponentMetaData100 md2 = mp.ComponentMetaDataCollection.New();
md2.ComponentClassID = "Microsoft.OLEDBDestination";
CManagedComponentWrapper wrp2 = md2.Instantiate();
wrp2.ProvideComponentProperties();
md2.Name = "OLE DB Connection";
md2.UsesDispositions = true;
md2.Version = 4;
wrp2.SetComponentProperty("OpenRowset", "dbo.authorizations");
#endregion
IDTSPath100 path = mp.PathCollection.New();
path.AttachPathAndPropagateNotifications(md.OutputCollection[0], md2.InputCollection[0]);
IDTSInput100 input = md2.InputCollection[0];
IDTSVirtualInput100 vInput = input.GetVirtualInput();
//below taken from https://stackoverflow.com/questions/12587709/c-sharp-ssis-data-flow-component-creating-custom-input-columns
IDTSExternalMetadataColumnCollection100 externalColumnCollection = input.ExternalMetadataColumnCollection;
// Iterate through the virtual input column collection.
foreach (IDTSVirtualInputColumn100 vColumn in vInput.VirtualInputColumnCollection)
{
// Call the SetUsageType method of the destination
// to add each available virtual input column as an input column.
wrp2.SetUsageType(
input.ID, vInput, vColumn.LineageID, DTSUsageType.UT_READONLY);
}
// Get the destination's default output collection
IDTSOutputCollection100 outColl = md2.OutputCollection;
// Iterate through the outputs in default output collection
foreach (IDTSOutput100 output in outColl)
{
// Iterate through the default output columns in the output
int count = output.OutputColumnCollection.Count;
foreach (IDTSOutputColumn100 outputColumn in output.OutputColumnCollection)
{
// Get the output's external metadata column collection
IDTSExternalMetadataColumnCollection100 extMetadataColumnColl = output.ExternalMetadataColumnCollection;
// Iterate through the external metadata column collection's external metadata columns
foreach (IDTSExternalMetadataColumn100 extMetadataColumn in extMetadataColumnColl)
{
// Call the MapOutPutColumn method of the destination to map
// each available output column to an external metadata column
wrp2.MapOutputColumn(
output.ID, outputColumn.ID, extMetadataColumn.ID, true);
}
}
}
md2.RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.GetExtendedInterface(conn);
md2.RuntimeConnectionCollection[0].ConnectionManagerID = conn.ID;
conn.AcquireConnection(null);
#region Save Package to FileSystem
string packageXml = @"C:\Users\test.dtsx";
XmlDocument myPkgDocument = new XmlDocument();
p.SaveToXML(ref myPkgDocument, null, null);
a.SaveToXml(packageXml, p, null);
#endregion
}
}
}
【问题讨论】:
-
看在上帝的份上使用 BIML :) bimlscript.com 和 mssqltips.com/sqlservertip/3094/… 和 sqlservercentral.com/stairway/100550 - 通过使用他们自己的应用程序,您可以绕过 BIDShelper。
-
也看看这个链接。非常实用的指南,几乎是你想要做的。 sqlservercentral.com/articles/Integration+Services+(SSIS)/…
-
太棒了。我肯定会把这个放在我的队列中去尝试。我快受够了我的 C# 脚本,而 BIML 目前看起来非常吸引人。理想情况下,我只需要一个脚本来加载一个包以刷新元数据......就是这样。不幸的是,通过 BIML 编写整个包的创建脚本似乎比使用 C# 来实现该功能更容易/。感谢你的这篇文章! :)
标签: c# sql-server xml ssis etl