我有一个SSIS包,它将查询中的数据导出到一个平面文件中,该文件将用于导入数据仓库。 我的一个要求是添加一个包含当前日期的标题行,以及一个包含总行数的页脚行。

我想在一个脚本组件或任务中理想地执行此操作,使用C#来实现包中的整洁。 在编写代码时,我是一个菜鸟。 如何才能做到这一点? 我在网上环顾四周,但似乎找不到足够接近我想要的东西。

===============>>#1 票数:1

以下是可用于脚本任务的代码,该脚本任务允许您输出带有页眉和页脚的CSV:

using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.IO;

namespace ST_80294de8b8dd4779a54f707270089f8c.csproj
{
    [System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {

        #region VSTA generated code
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion

        public void Main()
        {
            int ErrorFlag = 0;

            // Try-Catch block 
            try
            {
                int RowCount = 0;
                bool fireAgain = true;
                string SQLCommandText = "SELECT ColumnA = 1, ColumnB = 'A' UNION SELECT ColumnA = 2, ColumnB = 'B' UNION SELECT ColumnA = 3, ColumnB = 'C';";

                SqlConnection SQLConnection = new SqlConnection("Data Source=LocalHost;Initial Catalog=master;Integrated Security=SSPI;Application Name=SSIS-My Package Name;Connect Timeout=600");
                SqlCommand SQLCommand = new SqlCommand(SQLCommandText, SQLConnection);
                SQLCommand.CommandTimeout = 60 * 60;
                SqlDataAdapter SQLDataAdapter = new SqlDataAdapter(SQLCommand);
                DataTable dt = new DataTable();
                SQLDataAdapter.Fill(dt);
                SQLConnection.Close();
                RowCount = dt.Rows.Count;

                Dts.Events.FireInformation(0, "DataTable Rows", RowCount.ToString(), "", 0, ref fireAgain);

                StreamWriter sw = new StreamWriter("C:\\Test.csv", false);

                // Write the header.
                sw.Write("Today's date is " + DateTime.Now.ToLongDateString());

                // Write the column headers.
                sw.Write(sw.NewLine);
                int iColCount = dt.Columns.Count;
                for (int i = 0; i < iColCount; i++)
                {
                    sw.Write(dt.Columns[i]);
                    if (i < iColCount - 1)
                    {
                        sw.Write(",");
                    }
                }

                // Write the details.
                sw.Write(sw.NewLine);
                foreach (DataRow dr in dt.Rows)
                {
                    for (int i = 0; i < iColCount; i++)
                    {
                        if (!Convert.IsDBNull(dr[i]))
                        {
                            sw.Write(dr[i].ToString());
                        }
                        if (i < iColCount - 1)
                        {
                            sw.Write(",");
                        }
                    }
                    sw.Write(sw.NewLine);
                }

                // Write the footer.
                sw.Write("Row count: " + RowCount.ToString());

                sw.Close();
            }

            catch (SqlException e)
            {
                Dts.Events.FireError(0, "SqlException", e.Message, "", 0);
                ErrorFlag = 1;
            }

            catch (IOException e)
            {
                Dts.Events.FireError(0, "IOException", e.Message, "", 0);
                ErrorFlag = 1;
            }

            catch (Exception e)
            {
                Dts.Events.FireError(0, "Exception", e.Message, "", 0);
                ErrorFlag = 1;
            }

            // Return results. 
            if (ErrorFlag == 0)
            {
                Dts.TaskResult = (int)ScriptResults.Success;
            }
            else
            {
                Dts.TaskResult = (int)ScriptResults.Failure;
            } 

        }
    }
}

您也可以在不使用C#的情况下执行此操作,但这会有点难看:

  1. 变量1:用于分配数据流2中的行数的Int变量。

  2. 变量2:带有生成SQL命令的表达式的字符串变量。 如果变量1名为RowCount,那么这里是一组示例代码:

    “SELECT ColumnA ='”+(DT_WSTR,1252)(@ [User :: RowCount])+“',ColumnB = NULL”

  3. 数据流1:执行SQL命令以生成文件的标头并输出到平面文件目的地。 将“覆盖文件中的数据”设置为true。

  4. 数据流2:执行SQL命令以生成平面文件的详细信息。 将“覆盖文件中的数据”设置为false。 包括行计数转换并将值分配给变量1。

  5. 数据流3:执行SQL命令以生成平面文件的页脚。 源应该“从变量设置命令”,它应该执行变量2.将“覆盖文件中的数据”设置为false。

===============>>#3 票数:0 已采纳

这就是我最终想出来的! 这是我能找到的最干净,最简单的方法。 它基本上只是构建标题和尾部行,然后附加到数据集。 一旦你完成它,看起来很简单! 它需要一些C#的知识,但是它比在SQL中尝试它更值得。

Microsoft SQL Server Integration Services Script Task
Write scripts using Microsoft Visual C# 2008.
The ScriptMain is the entry point class of the script.

using System;
using System.Text;
using System.IO;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;

namespace ST_db04adc927b941d19b3817996ff885c2.csproj
{
    [System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {

        #region VSTA generated code
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion

        /*
        The execution engine calls this method when the task executes.
        To access the object model, use the Dts property. Connections, variables, events,
        and logging features are available as members of the Dts property as shown in the following examples.

        To reference a variable, call Dts.Variables["MyCaseSensitiveVariableName"].Value;
        To post a log entry, call Dts.Log("This is my log text", 999, null);
        To fire an event, call Dts.Events.FireInformation(99, "test", "hit the help message", "", 0, true);

        To use the connections collection use something like the following:
        ConnectionManager cm = Dts.Connections.Add("OLEDB");
        cm.ConnectionString = "Data Source=localhost;Initial Catalog=AdventureWorks;Provider=SQLNCLI10;Integrated Security=SSPI;Auto Translate=False;";

        Before returning from this method, set the value of Dts.TaskResult to indicate success or failure.

        To open Help, press F1.
    */

        public void Main()
        {
            const string dirPath = @"C:\SSIS\Dev\";

            DateTime minusoneweek = DateTime.Today.AddDays(-7);

            DateTime minusoneday = DateTime.Today.AddDays(-1);

            var headerRecord = ("0|" + DateTime.Today.ToString("ddMMyyyy") + "|" + Dts.Variables["LastSequenceNumber"].Value + "|" 
                + Dts.Variables["FileName"].Value) + "|" + minusoneweek.ToString("ddMMyyyy") + "|" + minusoneday.ToString("ddMMyyyy");

            var fileBody = AddHeaderAndFooter.GetFileText(dirPath + "blank.txt");

            var trailerRecord = "9|" + AddHeaderAndFooter.CountRecords(dirPath + "blank.txt").ToString();

            var outPutData = headerRecord + "\r\n" + fileBody + trailerRecord + "\r\n";

            AddHeaderAndFooter.WriteToFile(dirPath + "blank.txt", outPutData);

        }
    }

    public static class AddHeaderAndFooter
    {
        public static int CountRecords(string filePath)
        {

            return (File.ReadAllLines(filePath).Length + 2);  

        }

        public static string GetFileText(string filePath)
        {
            var sr = new StreamReader(filePath, Encoding.Default);

            var recs = sr.ReadToEnd();

            sr.Close();

            return recs;
        }

        public static void WriteToFile(string filePath, string fileText)
        {

            var sw = new StreamWriter(filePath, false);

            sw.Write(fileText, Encoding.ASCII);

            sw.Close();

        }
    }
}

  ask by jhowe translate from so

未解决问题?本站智能推荐:

1回复

动态平面文件源路径

我正在尝试将动态文件路径传递给SSIS包变量。 我在连接表达式中将ConnectionString值设置为变量值。 因此,开始时,我将初始变量名称值设置为products.csv并得到错误: 保存程序包时发生非致命错误:名称不能包含以下任何字符:/ \\:[]。 =
1回复

SSIS包中的XML配置文件错误

我一直在使用SSIS软件包,但目前仍陷在此问题中。 我一直在使用我在Package Variable中编写的连接字符串进行开发,并且该值通过表达式传递给Connection Mannager。 像这样的东西: @ [User :: Connection] 它对于调试非常有用。 由于我
2回复

在SSIS脚本组件中添加第三方DLL参考

我在脚本组件中添加了第三方参考(Json newtonsoft)dll(使用“编辑脚本”选项),但是当我运行该软件包时,出现了错误 无法加载文件或程序集“ Newtonsoft.Json,版本= 4.5.0.0,区域性=中性,PublicKeyToken = 30ad4fe6b2a6aee
1回复

是否可以使用C#将ssis包执行的事件记录到文件中

是否可以记录从C#调用的ssis包执行事件 我需要记录在包执行期间生成的消息。 我正在使用SQL Server 2008。 提前致谢
2回复

SSIS计划程序无法访问远程位置上的文件

我有一个放在远程驱动器上的日志文件。 我只是从SSIS作业中读取此文件,然后扫描它是否有错误。 我已经在本地计算机上运行了这项工作,效果很好。 但是当我尝试将其安排在服务器上时。 SSIS作业失败,并抛出“拒绝访问文件”的错误,我尝试在其他用户下运行该作业,但仍然给出相同的错误。 我可
2回复

使用输入参数在SSIS包中调用storedprocedure

我正在从SSIS包调用Storedprocedure。 此存储过程有三个输入参数,如“开始日期”,“结束日期”和“字符串变量”。 我们从.Net应用程序调用SSIS包。 因此,我们必须将参数从C#代码传递给SSIS包,而SSIS包又传递给Storedprocedure。 我正在寻
1回复

将DTS ActiveX转换为SSIS中的脚本任务

我是这个论坛的新手,这是我的第一个话题,所以我希望将其发布在正确的位置。 我不知道任何C#,但是我知道一些VB,我已经将DTS包迁移到SSIS,但是我无法使ActiveX脚本正常工作,并决定在脚本任务中重新编写它。 我有4个全局变量,它们都具有已在“全局变量”菜单中设置的值。 链接到图
1回复

SSIS For Each循环中的脚本任务-写入文件

我的脚本任务在每个循环的SSIS中。 我希望脚本任务仅针对所有迭代将一些动态字符串写入一个文件。 每次迭代之后,都应该追加文件,而不用动态字符串的当前值覆盖文件。 它就像一个日志“工具”。 顺便说一句,SSIS是SQL Server集成服务的ETL工具。 我该怎么做呢 ? 我
1回复

如何在SSIS包中两次使用变量数据集

我使用记录集目标在变量中创建数据集。 以后在脚本组件(源)中使用只读变量,但是当我尝试在其他脚本组件(源)中使用此变量时,获取空数据集。 我认为第一个脚本组件阻止了我的变量,不知道如何解决。 两个脚本组件使用相等的代码,第一个组件第二个获得44行-无 如果将“脚本组件”更改为“
1回复

您可以在SSIS中重用代码吗? 您可以以编程方式更改源/目标吗?

我需要解析,转换并加载到sql server中的大约10个不同的csv文件。 我不想为此创建10个不同的ssis软件包,是否有可能创建一个我可以创建10个不同实例的SSIS软件包,并只需更改配置文件,以使其从正确的源csf文件中提取,并保存到正确的表? 是否还可以创建可重复使用的代码