使用OLE DB Source的EzAPI代码是什么,数据访问模式为“来自变量的SQL命令”并分配变量?
每月一次,我们需要使用生产数据子集刷新公共测试站点。我们已经确定,根据我们的需求,SSIS解决方案最适合完成此任务。
我的目标是系统地构建大量(100+)“复制”包。 EzAPI是SSIS object model的友好包装,它似乎是保存鼠标点击的好方法。
我希望我的包看起来像
User::sourceQuery
这是我的表到表复制包的代码。
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<EzOleDbSource, EzSqlOleDbCM, EzOleDbDestination, EzSqlOleDbCM>
{
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();
}
/// <summary>
/// Sanitize a name so that it is valid for SSIS objects.
/// Strips []/\:=
/// Replaces . with _
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
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 Query提供,查询嵌入在OLE Source中。希望它使用“来自变量的SQL命令”并且该变量为@[User::sourceQuery]
我所坚持的是在源中使用变量。
应该分配像
这样的东西 this.Source.DataSourceVariable = this.Variables["sourceQuery"].QualifiedName;
this.Source.AccessMode = AccessMode.AM_SQLCOMMAND_VARIABLE;
这会导致选择正确的数据访问模式,但不会填充变量。
您可以观察到我在目的地执行了类似的步骤 接受变量并且“正确”工作。
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构建以来可能已经有一个修复但是无济于事。
我是否在代码中发现了错误,或者我错过了什么?
答案 0 :(得分:12)
EzAPI的当前稳定版本不支持将变量赋值为OleDB Source属性。我在CodePlex上打开了一个类似的discussion,最后了解了所有这些是如何工作的。
根问题是相关属性"SqlCommandVariable" should be set when the access mode is set to "SQL Command from Variable."目前,代码仅涵盖目标变量。
我的决心是下载源代码并修改EzComponents.cs中属性DataSourceVariable
的setter(更改集65381的第1027行)
set
{
m_comp.SetComponentProperty("OpenRowsetVariable", value);
if (AccessMode == AccessMode.AM_SQLCOMMAND_VARIABLE)
{
m_comp.SetComponentProperty("SqlCommandVariable", value);
}
ReinitializeMetaData();
}
如果您希望正确解决此问题,可以提升Issue
答案 1 :(得分:2)
尝试交换
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更重要。