【发布时间】:2009-06-23 11:01:56
【问题描述】:
看起来应该很简单,但到目前为止,我还没有找到将存储在 SSIS 字符串变量中的值保存到文本文件的方法。我已经研究过在数据流中使用平面文件目标,但这需要数据流源。
关于如何做到这一点的任何想法?
【问题讨论】:
看起来应该很简单,但到目前为止,我还没有找到将存储在 SSIS 字符串变量中的值保存到文本文件的方法。我已经研究过在数据流中使用平面文件目标,但这需要数据流源。
关于如何做到这一点的任何想法?
【问题讨论】:
下面是一些在 C# 中的 SQL CLR 中工作的代码的小示例。如果您在 2005 年,我相信您将需要使用 VB。脚本任务还需要将读取变量属性设置为 MyVariable 以使变量的值对其可用。
// create a writer and open the file
TextWriter tw = new StreamWriter("\\\\server\\share$\\myfile.txt");
// write a line of text to the file
tw.WriteLine(Dts.Variables["MyVariable"].Value);
// close the stream
tw.Close();
【讨论】:
使用脚本任务。
我刚试过这个。我创建了一个文件连接管理器,连接字符串指向我要写入的文件。然后我创建了一个包含要写入的文本的字符串变量。
我添加了一个脚本任务,在只读变量列表中指定了我的字符串变量,然后单击了编辑脚本。脚本如下:
public void Main()
{
ConnectionManager cm = Dts.Connections["File.tmp"];
var path = cm.ConnectionString;
var textToWrite = (string)Dts.Variables["User::StringVariable"].Value;
System.IO.File.WriteAllText(path, textToWrite);
Dts.TaskResult = (int)ScriptResults.Success;
}
这没有问题。
【讨论】:
在一个简单的脚本任务中只需要一行代码。不需要其他依赖项,例如连接管理器。
这是它在 C# 中的样子:
public void Main()
{
string variableValue = Dts.Variables["TheVariable"].Value.ToString();
string outputFile = Dts.Variables["Path"].Value.ToString();
System.IO.File.WriteAllText(outputFile, variableValue);
Dts.TaskResult = (int)ScriptResults.Success;
}
显然这里最重要的一行是包含 WriteAllText 函数调用的那一行。
Path 变量应包含输出文件的完整路径 + 文件名。
【讨论】:
好的,我有一个不涉及使用脚本任务的答案。选择一些你拥有的 oledb sql 源代码,这很简单,并且你有很多控制权。进行只返回一行的查询。然后将此查询放入字符串变量中: "select vara, 'nnnn" + @[User:varIWantToSee] + "' as myvar from tablea where vara = 1" 然后在 OLEDB 源中选择“来自变量的 SQL 命令” 对于 varIWantToSee ,请确保使用大量字符对其进行初始化,否则 ssis 会为该列创建一个非常小的长度,它不会让您覆盖。在运行时 varIWantToSee 将被设置,您可以看到它。将这一切都泵入一个平面文件目的地,您就可以开展业务了。为什么有些人必须这样做?因为有些人需要知道运行环境中的变量值,所以他们的笔记本开发并没有显示出他们需要的变量值。就我而言,我在 Azure 环境中运行它,该环境具有我需要测试的数据库访问权限。如果我是 microsoft,我将创建一个任务,通过将其写入包运行时创建的 ssis 日志文件来显示作业该阶段的运行时变量值。如果有人知道如何做到这一点,请赐教。
【讨论】:
可以使用派生列转换将变量的值写入列。问题是它需要一个源来驱动它,并且没有可以使用的股票数据源,它只会在管道上吐出一个空行。
因此,您要么重新利用单行源来驱动派生列转换,要么按照另一个答案的建议进行操作,并使用脚本源来完成。
【讨论】:
我按照你描述的方式做了。我已经定义了一个 oledb 连接管理器,所以我使用了 OLE DB 源 并使用了 SQL 命令数据访问模式。我使用了一个简单的查询:
select getdate() as dt
...只是为了摆脱它。现在我知道了我的变量拉动的日期。然后我使用派生列转换使我的包变量可用并将其写到一个平面文件中。
优雅?不,但它可以完成工作。
【讨论】:
假设您不想弄乱脚本任务,并且您没有可以连接到的数据库,只是为了发出数据源命令,例如:
SELECT 'Some arbitrary text'
仍然有几种方法可以将 Process 任务用于像将一行文本写入文件这样简单的事情。例如,您可以将 PowerShell 与使用以下表达式构建的输入变量一起使用:
"'"+REPLACE(@[User::Text],"'","''")+"' > '"+REPLACE(@[User::Filename],"'","''")+"'"
请注意,我转义了文件名,因为那里的单引号是合法的。另请注意,我使用“>”进行重定向,如果文件存在,则会覆盖该文件。如果我想追加,我会使用“>>”。
最初,当 User::Text 包含多行时,我在使用此方法时遇到了问题。事实证明,当命令跨行时,您的文件名后需要一些额外的 EOL 字符。像这样:
"'"+REPLACE(@[User::Text],"'","''")+"' > '"+REPLACE(@[User::Filename],"'","''")+"'\r\n\r\n"
将 cmd.exe 与 echo 一起使用有点不稳定,但在某些情况下也可以工作并且开销要少得多。
附:我注意到在某些版本的 PowerShell 中,StandardInputVariable 内容在没有这个的情况下会被忽略:
-Command -
在“参数”框中。作为命令参数的唯一减号是“神奇的”,并记录在https://docs.microsoft.com/en-us/powershell/scripting/powershell.exe-command-line-help。我相信所有版本的 PowerShell 都接受这个参数,所以即使你的版本不需要它,你也可能想要包含它,因为它不应该破坏任何东西,并且如果 PowerShell 更新到需要它的版本,它可能会阻止你的代码破坏。
【讨论】: