gpt4 book ai didi

c# - 从变量使用 OLE DB 源命令的 EzAPI 等价物是什么?

转载 作者:可可西里 更新时间:2023-11-01 09:04:33 25 4
gpt4 key购买 nike

tl;dr

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

序言

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

我的目标是系统地构建大量(100 多个)“复制”包。 EzAPISSIS object model 的友好包装器这似乎是一种节省鼠标点击次数的好方法。

我希望我的包裹看起来像

  • 变量——“表名”; [架构].[表名]
  • 变量——“sourceQuery”;从 [架构].[表名] 中选择 *
  • DataFlow - “复制 Schema_TableName”
    • OLE DB 源 - “Src Schema_TableName”;数据访问模式:来自变量的SQL命令;变量名称:User::sourceQuery
    • OLE DB 目标 - “Dest Schema_TableName”;表或 View 名称可变 - 快速加载;变量名 - 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<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 查询的访问模式,查询嵌入到 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;

destination with variable

什么不起作用

列出我尝试过的排列

        this.Source.AccessMode = AccessMode.AM_OPENROWSET;

数据访问模式设置为表或 View 的结果,表或 View 的名称为空。

        this.Source.AccessMode = AccessMode.AM_OPENROWSET_VARIABLE;

数据访问模式设置为“表或 View 名称变量”且变量名称为 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);

Source properties

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

我是在他们的代码中发现了错误还是只是遗漏了什么?

最佳答案

EzAPI 的当前稳定版本不支持将变量分配为 OleDB 源属性。我开了一个类似的discussion在 CodePlex 上学习并最终了解了所有这些工作原理的更多信息。

根本问题是相关属性"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

关于c# - 从变量使用 OLE DB 源命令的 EzAPI 等价物是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8916674/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com