【发布时间】:2016-12-09 09:41:02
【问题描述】:
我已经在 MSDN [https://social.msdn.microsoft.com/Forums/en-US/6cd447d8-21e5-44be-aee6-ad6bdcaac40f/programmatically-created-package-having-difficulties-running?forum=sqlintegrationservices] 上发布了同样的问题,我希望这里的人可以提供帮助。
---这是问题---
我正在尝试创建一个简单的 SSIS 任务,通过 .NET Interop 程序集将数据从 SQL Server 表(一个名为 [num] 的 int 列)加载到一个 Oracle 表(一个名为 [ID] 的 NUMBER 列)对于 SSIS。我可以创建包并将其保存到 DTSX 文件,但是当我运行(以编程方式或通过 dtexec)时,它会失败。我正在遵循以编程方式创建包的开发指南,当我查看各种对象的属性时,我并没有真正跳出来。
作为次要问题,我看到有可用的 Package.Validate 方法,但我不知道如何调用它(需要参数和返回值)。当我通过 dtexec 运行包时,它会进行验证并提供一些有用的验证错误,所以我希望能够以编程方式挂钩。
我得到的验证错误是:
错误:2016-12-08 09:39:15.96 代码:0xC004706B 来源: {A8E8D1A6-3826-4222-B6DC-46008A1722DF} SSIS.Pipeline 说明: “OLE DB Destination”验证失败并返回验证状态 “VS_NEEDSNEWMETADATA”。
据我在线了解,此错误的原因是列映射错误,但我或多或少直接从开发指南中提取了代码。
所以我的两个问题是:
- 如何解决此验证错误 VS_NEEDSNEWMETADATA,最好以编程方式解决?
- 如何调用 Package.Validate 以通过编程方式获取此类验证错误?**
感谢任何帮助!
完整的代码清单(我在 C# Interactive 中使用 Visual Studio 运行,没有抛出异常,但结果以失败值结束):
// these are just adding references to the context:
#r "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.SqlServer.DTSPipelineWrap\v4.0_11.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.DTSPipelineWrap.dll"
#r "C:\Windows\Microsoft.NET\assembly\GAC_64\Microsoft.SqlServer.DTSRuntimeWrap\v4.0_11.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.DTSRuntimeWrap.dll"
#r "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.SqlServer.ManagedDTS\v4.0_11.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.ManagedDTS.dll"
#r "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.SqlServer.PipelineHost\v4.0_11.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.PipelineHost.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Core.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Xml.Linq.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.DataSetExtensions.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\Microsoft.CSharp.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Net.Http.dll"
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Xml.dll"
// the actual code:
using dtsrt = Microsoft.SqlServer.Dts.Runtime;
using dtsp = Microsoft.SqlServer.Dts.Pipeline;
using dtspw = Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using refl = System.Reflection;
private string GetHresultSymbolicName(int errorCode)
{
dtsrt.HResults hresults = new Microsoft.SqlServer.Dts.Runtime.HResults();
return (from refl.FieldInfo fi in hresults.GetType().GetFields() where (((int)fi.GetValue(hresults)) == errorCode) select fi.Name).Single();
}
// base setup
dtsrt.Package package = new dtsrt.Package();
dtsrt.Executable e = package.Executables.Add("STOCK:PipelineTask");
dtsrt.TaskHost thMainPipe = e as dtsrt.TaskHost;
dtspw.MainPipe dataFlowTask = thMainPipe.InnerObject as dtspw.MainPipe;
dtsrt.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
dtsrt.PipelineComponentInfos componentInfos = app.PipelineComponentInfos;
// source connection
dtsrt.ConnectionManager srcConnectionManager = package.Connections.Add("OLEDB");
srcConnectionManager.Name = "Source OLEDB Connection";
srcConnectionManager.ConnectionString = "Provider=SQLOLEDB; Address=XXX; Database=Sandbox; Trusted_Connection=yes;";
// dest connection
dtsrt.ConnectionManager destConnectionManager = package.Connections.Add("OLEDB");
destConnectionManager.Name = "Destination OLEDB Connection";
destConnectionManager.ConnectionString = "Provider=OraOLEDB.Oracle; Data Source=XXX;User Id=SANDBOX;Password=123456;";
// thanks: ole.OleDbDataReader rdr = ole.OleDbEnumerator.GetRootEnumerator();
// dest component
dtspw.IDTSComponentMetaData100 destComponent = dataFlowTask.ComponentMetaDataCollection.New();
destComponent.ComponentClassID = "DTSAdapter.OLEDBDestination.3";
destComponent.Instantiate();
dtspw.CManagedComponentWrapper destWrapper = destComponent.Instantiate();
destWrapper.ProvideComponentProperties();
destComponent.RuntimeConnectionCollection[0].ConnectionManager = dtsrt.DtsConvert.GetExtendedInterface(destConnectionManager);
destComponent.RuntimeConnectionCollection[0].ConnectionManagerID = destConnectionManager.ID;
destComponent.CustomPropertyCollection["CommandTimeout"].Value = 0; // no timeout
destComponent.CustomPropertyCollection["AccessMode"].Value = 2; // sqlcommand
destComponent.CustomPropertyCollection["SqlCommand"].Value = "select * from my_asdf";
destWrapper.AcquireConnections(null);
destWrapper.ReinitializeMetaData();
destWrapper.ReleaseConnections();
// source component
dtspw.IDTSComponentMetaData100 srcComponent = dataFlowTask.ComponentMetaDataCollection.New();
srcComponent.ComponentClassID = "DTSAdapter.OLEDBSource.3";
srcComponent.Instantiate();
dtspw.CManagedComponentWrapper srcWrapper = srcComponent.Instantiate();
srcWrapper.ProvideComponentProperties();
srcComponent.RuntimeConnectionCollection[0].ConnectionManager = dtsrt.DtsConvert.GetExtendedInterface(srcConnectionManager);
srcComponent.RuntimeConnectionCollection[0].ConnectionManagerID = srcConnectionManager.ID;
srcComponent.CustomPropertyCollection["CommandTimeout"].Value = 0; // no timeout
srcComponent.CustomPropertyCollection["AccessMode"].Value = 2; // sqlcommand
srcComponent.CustomPropertyCollection["SqlCommand"].Value = "select num from big_numbers2";
srcWrapper.AcquireConnections(null);
srcWrapper.ReinitializeMetaData();
srcWrapper.ReleaseConnections();
dtspw.IDTSPath100 path = dataFlowTask.PathCollection.New();
path.AttachPathAndPropagateNotifications(srcComponent.OutputCollection[0], destComponent.InputCollection[0]);
// Just one column mapping, as each table has just one column
dtspw.IDTSInput100 destInput = destComponent.InputCollection[0];
dtspw.IDTSVirtualInput100 vDestInput = destInput.GetVirtualInput();
destWrapper.SetUsageType(destInput.ID, vDestInput, vDestInput.VirtualInputColumnCollection[0].LineageID, dtspw.DTSUsageType.UT_READONLY);
// save it, run it
app.SaveToXml("D:\\myDtsx.dtsx", package, null);
dtsrt.DTSExecResult result = package.Execute(); // result = failure
【问题讨论】:
标签: c# sql-server ssis