现代方式在 SSIS 2012 及更高版本中连接到脚本任务中的 SQL 服务器

Modern way connect to SQL Server inside Script Task in SSIS 2012 and later

当您在互联网上搜索或搜索如何 ​​connect to SQL database inside Script Task in SSIS 时,您会发现 .NET v1.1ish 代码如下:

ConnectionManager cm;
System.Data.SqlClient.SqlConnection sqlConn;
System.Data.SqlClient.SqlCommand sqlComm;

cm = Dts.Connections["ADO.NET.SqlDB"];    
sqlConn = (System.Data.SqlClient.SqlConnection)cm.AcquireConnection(Dts.Transaction);

sqlComm = new System.Data.SqlClient.SqlCommand("your SQL Command", sqlConn);
sqlComm.ExecuteNonQuery();

cm.ReleaseConnection(sqlConn);

我正在寻找可充分利用后来引入的 .NET 功能的更新代码。

首先,下面的代码怎么样。这是当前推荐的在 SSIS 2012 及更高版本中连接到 SQL 服务器内部脚本任务的方法,还是我在这里遗漏了什么?

ConnectionManager cm = Dts.Connections["ADO.NET.SqlDB"];
using (var sqlConn = (SqlConnection)cm.AcquireConnection(Dts.Transaction))
{
    if (sqlConn.State != ConnectionState.Open)
        sqlConn.Open();

    using (var sqlComm = new SqlCommand(
        String.Format("UPDATE myTab SET Processed = 4 where ID = '{0}'",
        idNumber), sqlConn))
    {
        return sqlComm.ExecuteNonQuery();
    }
}

ReleaseConnection()还需要吗? 在 SSIS 上下文中真的需要 sqlConn.Open() 吗?


一年后,希望我更聪明一点,我用这样的代码解决了问题:

ConnectionManager cm = Dts.Connections["ADO.NET.SqlServerDB"];
var sqlConn = (SqlConnection)cm.AcquireConnection(Dts.Transaction);
using (var sqlCmd = new SqlCommand(
  "INSERT INTO apou_moodle_import(id_num, username, email) VALUES(@IdNum, @Username, @Email)",
  sqlConn))
{
    sqlCmd.CommandType = CommandType.Text;
    sqlCmd.Parameters.AddWithValue("@IdNum", newUser.id_num);
    sqlCmd.Parameters.AddWithValue("@Username", newUser.username);
    sqlCmd.Parameters.AddWithValue("@Email", newUser.email);

    int rowsAffected = sqlCmd.ExecuteNonQuery();
}
cm.ReleaseConnection(sqlConn);

因此,我继续使用 ConnectionManager.ReleaseConnection,但是,SSIS 上下文中不需要 SqlConnection.OpenClose。另外,使用参数来确保安全。

好吧,using 结构允许您自动处理变量并更好地处理它。但是,sqlConn 不是一个简单的 class,它是一个 ConnectionManager 实例。开始使用时调用 AcquireConnection,结束时调用 ReleaseConnectionReleaseConnection 可能会执行一些特定于此数据源的内务处理。根据 ConnectionManager 实现,它可能会随时检查 ReleaseConnection 是否被调用并调用它。

据我了解,在大多数情况下,使用 using 的代码应该没问题。当您反复打开连接而不释放它时可能会出现问题 - 您可能 运行 连接池等。我会将内部组件包装到 try - finally 块中以确保 ReleaseConnection 执行。