从变量使用OLE DB Source命令的EzAPI等价物是什么?

TL;博士

什么是使用OLE DB Source的EzAPI代码,数据访问模式为“来自变量的SQL命令”并分配变量?

前言

每月一次,我们需要使用生产数据子集刷新公共测试站点。 我们已经确定,根据我们的需求,SSIS解决方案最适合完成此任务。

我的目标是系统地构建大量(100+)“复制”包。 EzAPI是SSIS对象模型的友好包装器,它似乎是一种保存鼠标点击的好方法。

我希望我的包装看起来像

  • 变量 – “tableName”; [架构]。[表名]
  • 变量 – “sourceQuery”; SELECT * FROM [Schema]。[TableName]
  • DataFlow – “Replicate Schema_TableName”
    • OLE DB源 – “Src Schema_TableName”; 数据访问模式:来自变量的SQL命令; 变量名: User::sourceQuery
    • OLE DB目标 – “Dest Schema_TableName”; 表或视图名称变量 – 快速加载; 变量名称 – User :: tableName

这是我的表到表复制包的代码。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.SqlServer.SSIS.EzAPI; using Microsoft.SqlServer.Dts.Runtime; namespace EzApiDemo { public class TableToTable : EzSrcDestPackage { public TableToTable(Package p) : base(p) { } public static implicit operator TableToTable(Package p) { return new TableToTable(p); } public TableToTable(string sourceServer, string database, string table, string destinationServer) : base() { string saniName = TableToTable.SanitizeName(table); string sourceQuery = string.Format("SELECT D.* FROM {0} D", table); // Define package variables this.Variables.Add("sourceQuery", false, "User", sourceQuery); this.Variables.Add("tableName", false, "User", table); // Configure DataFlow properties this.DataFlow.Name = "Replicate " + saniName; this.DataFlow.Description = "Scripted replication"; // Connection manager configuration this.SrcConn.SetConnectionString(sourceServer, database); this.SrcConn.Name = "PROD"; this.SrcConn.Description = string.Empty; this.DestConn.SetConnectionString(destinationServer, database); this.DestConn.Name = "PREPROD"; this.DestConn.Description = string.Empty; // Configure Dataflow's Source properties this.Source.Name = "Src " + saniName; this.Source.Description = string.Empty; this.Source.SqlCommand = sourceQuery; // Configure Dataflow's Destination properties this.Dest.Name = "Dest " + saniName; this.Dest.Description = string.Empty; this.Dest.Table = table; this.Dest.FastLoadKeepIdentity = true; this.Dest.FastLoadKeepNulls = true; this.Dest.DataSourceVariable = this.Variables["tableName"].QualifiedName; this.Dest.AccessMode = AccessMode.AM_OPENROWSET_FASTLOAD_VARIABLE; this.Dest.LinkAllInputsToOutputs(); } ///  /// Sanitize a name so that it is valid for SSIS objects. /// Strips []/\:= /// Replaces . with _ ///  ///  ///  public static string SanitizeName(string name) { string saniName = name.Replace("[", String.Empty).Replace("]", string.Empty).Replace(".", "_").Replace("/", string.Empty).Replace("\\", string.Empty).Replace(":", string.Empty); return saniName; } } } 

调用看起来像TableToTable s2 = new TableToTable(@"localhost\localsqla", "AdventureWorks", "[HumanResources].[Department]", @"localhost\localsqlb"); 并构建一个包, 除了在源中使用变量 ,它可以执行我想要的操作。

问题

上面的代码提供了访问模式作为SQL查询,查询嵌入在OLE源中。 希望它使用“来自变量的SQL命令”和变量为@[User::sourceQuery]我坚持使用的是源中的变量。

分配类似的东西应该是一件简单的事情

  this.Source.DataSourceVariable = this.Variables["sourceQuery"].QualifiedName; this.Source.AccessMode = AccessMode.AM_SQLCOMMAND_VARIABLE; 

这会导致选择正确的数据访问模式,但不会填充变量。 ole db source

您可以观察到我在目标中执行了类似的步骤,该步骤接受变量并且“正确”工作。

  this.Dest.DataSourceVariable = this.Variables["tableName"].QualifiedName; this.Dest.AccessMode = AccessMode.AM_OPENROWSET_FASTLOAD_VARIABLE; 

目的地与变量

什么行不通

列出我尝试过的排列

  this.Source.AccessMode = AccessMode.AM_OPENROWSET; 

数据访问模式中的结果设置为表或视图和表的名称或视图为空。

  this.Source.AccessMode = AccessMode.AM_OPENROWSET_VARIABLE; 

数据访问模式中的结果设置为“表或视图名称变量”,变量名称为sourceQuery。 非常接近我想要的,除了访问模式不正确。 如果这个包运行,它会爆炸,因为OpenRowSet会期望一个直接的表名。

  this.Source.AccessMode = AccessMode.AM_SQLCOMMAND; 

数据访问模式中的结果设置为“SQL命令”,SQL命令文本为“User :: sourceQuery”这是变量名称的字面值,因此它是正确的,但由于访问模式错误,它不起作用。

  this.Source.AccessMode = AccessMode.AM_OPENROWSET_FASTLOAD; this.Source.AccessMode = AccessMode.AM_OPENROWSET_FASTLOAD_VARIABLE; 

其中这些是正确的访问模式,因为它们是目的地(我仍然尝试过它们,但它们没有按预期工作)。

此时,我想我会尝试通过创建一个包含已根据需要定义OLE DB源的包然后检查源对象的属性来向后工作。

  Application app = new Application(); Package p = app.LoadPackage(@"C:\sandbox\SSISHackAndSlash\SSISHackAndSlash\EzApiPackage.dtsx", null); TableToTable to = new TableToTable(p); 

来源属性

我的代码使用变量的限定名称设置了SqlCommand和DataSourceVarible。 我已经下载了变更集65381并编译了(在修复了对SQL Server 2012 dll的一些引用之后)希望自2008年12月30日Stable构建以来可能已经有一个修复但无济于事。

我在他们的代码中发现了一个错误,或者我错过了什么?

EzAPI的当前稳定版本不支持将变量赋值为OleDB Source属性。 我在CodePlex上开了一个类似的讨论 ,最后了解了所有这些的工作原理。

根问题是当访问模式设置为“来自变量的SQL命令”时,应设置相关属性“SqlCommandVariable”。 目前,代码仅涵盖目标变量。

我的决心是下载源代码并修改EzComponents.cs中属性DataSourceVariable的setter(更改集65381的第1027行)

  set { m_comp.SetComponentProperty("OpenRowsetVariable", value); if (AccessMode == AccessMode.AM_SQLCOMMAND_VARIABLE) { m_comp.SetComponentProperty("SqlCommandVariable", value); } ReinitializeMetaData(); } 

如果您希望正确解决此问题,则可以提出问题

尝试交换

 this.Source.DataSourceVariable = this.Variables["sourceQuery"].QualifiedName; this.Source.AccessMode = AccessMode.AM_SQLCOMMAND_VARIABLE; 

 this.Source.AccessMode = AccessMode.AM_SQLCOMMAND_VARIABLE; this.Source.DataSourceVariable = this.Variables["sourceQuery"].QualifiedName; 

我发现订单比使用典型API更重要。