SSIS 错误 - 找不到脚本的二进制代码
SSIS error- Binary code for the script is not found
我 运行 遇到了这个奇怪的 SSIS 错误,服务器上的脚本组件一直失败并显示错误 -"The binary code for the script is not found. Please open the script and make sure it build correctly"。
该脚本在我的本地机器上构建得非常好。除了打开脚本组件时获得的标准引用之外,脚本组件基本上引用 3 个额外的 DLL。这些 dll 是 Microsoft.Hadoop.avro.dll、Newtonsoft.json.dll 和 Microsoft.Csharp。
Microsoft.Hadoop.avro 和 Newtonsoft.json 是我必须下载的,我什至已经在本地和服务器上注册到 GAC。
我试过打开组件、重建它们、保存它们并部署它们。我已将数据流上的 DelayValidation 设置为 False。我已将参考部分中的 dll 的 "Copy local" 设置为 False。我通过显式放入 GAC 位置重新添加了引用,即 C:\Windows\Microsoft.Net\Assembly\GAC_MSIL.
这是脚本组件的示例代码
#region Help: Introduction to the Script Component
/* The Script Component allows you to perform virtually any operation that can be accomplished in
* a .Net application within the context of an Integration Services data flow.
*
* Expand the other regions which have "Help" prefixes for examples of specific ways to use
* Integration Services features within this script component. */
#endregion
#region Namespaces
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using Microsoft.Hadoop.Avro;
using Microsoft.Hadoop.Avro.Container;
using Microsoft.Hadoop.Avro.Schema;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using Microsoft.CSharp.RuntimeBinder;
using System.Linq;
using System.Reflection;
#endregion
/// <summary>
/// This is the class to which to add your code. Do not change the name, attributes, or parent
/// of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
#region Help: Using Integration Services variables and parameters
/* To use a variable in this script, first ensure that the variable has been added to
* either the list contained in the ReadOnlyVariables property or the list contained in
* the ReadWriteVariables property of this script component, according to whether or not your
* code needs to write into the variable. To do so, save this script, close this instance of
* Visual Studio, and update the ReadOnlyVariables and ReadWriteVariables properties in the
* Script Transformation Editor window.
* To use a parameter in this script, follow the same steps. Parameters are always read-only.
*
* Example of reading from a variable or parameter:
* DateTime startTime = Variables.MyStartTime;
*
* Example of writing to a variable:
* Variables.myStringVariable = "new value";
*/
#endregion
#region Help: Using Integration Services Connnection Managers
/* Some types of connection managers can be used in this script component. See the help topic
* "Working with Connection Managers Programatically" for details.
*
* To use a connection manager in this script, first ensure that the connection manager has
* been added to either the list of connection managers on the Connection Managers page of the
* script component editor. To add the connection manager, save this script, close this instance of
* Visual Studio, and add the Connection Manager to the list.
*
* If the component needs to hold a connection open while processing rows, override the
* AcquireConnections and ReleaseConnections methods.
*
* Example of using an ADO.Net connection manager to acquire a SqlConnection:
* object rawConnection = Connections.SalesDB.AcquireConnection(transaction);
* SqlConnection salesDBConn = (SqlConnection)rawConnection;
*
* Example of using a File connection manager to acquire a file path:
* object rawConnection = Connections.Prices_zip.AcquireConnection(transaction);
* string filePath = (string)rawConnection;
*
* Example of releasing a connection manager:
* Connections.SalesDB.ReleaseConnection(rawConnection);
*/
#endregion
#region Help: Firing Integration Services Events
/* This script component can fire events.
*
* Example of firing an error event:
* ComponentMetaData.FireError(10, "Process Values", "Bad value", "", 0, out cancel);
*
* Example of firing an information event:
* ComponentMetaData.FireInformation(10, "Process Values", "Processing has started", "", 0, fireAgain);
*
* Example of firing a warning event:
* ComponentMetaData.FireWarning(10, "Process Values", "No rows were received", "", 0);
*/
#endregion
string copiedAddressFile;
private StreamWriter textWriter;
private string columnDelimiter = ",";
List<AvroRecord> DatesRowList;
public override void AcquireConnections(object Transaction)
{
IDTSConnectionManager100 connMgr = this.Connections.Dates;
copiedAddressFile = (string)connMgr.AcquireConnection(null);
}
public static string Schema = "";
/// <summary>
/// This method is called once, before rows begin to be processed in the data flow.
///
/// You can remove this method if you don't need to do anything here.
/// </summary>
public override void PreExecute()
{
base.PreExecute();
Schema = @"{
""type"":""record"",
""name"":""Microsoft.Hadoop.Avro.Specifications.Dates"",
""fields"":
[
{ ""name"":""MK_DatesID"", ""type"":""int"" },
{ ""name"":""Date"", ""type"":""string"" },
{ ""name"":""IsTradingDay"", ""type"":""boolean"" }
]
}";
DatesRowList = new List<AvroRecord>();
}
/// <summary>
/// This method is called after all the rows have passed through this component.
///
/// You can delete this method if you don't need to do anything here.
/// </summary>
public override void PostExecute()
{
base.PostExecute();
if (Variables.PushToDataLake == true)
{
using (Stream st = new FileStream(copiedAddressFile, FileMode.Create, FileAccess.Write, FileShare.Write))
{
using (var w = AvroContainer.CreateGenericWriter(Schema, st, Codec.Deflate))
{
using (var writer = new SequentialWriter<object>(w, 24))
{
// Serialize the data to stream using the sequential writer
DatesRowList.ForEach(writer.Write);
}
}
}
}
}
/// <summary>
/// This method is called once for every row that passes through the component from Input0.
///
/// Example of reading a value from a column in the the row:
/// string zipCode = Row.ZipCode
///
/// Example of writing a value to a column in the row:
/// Row.ZipCode = zipCode
/// </summary>
/// <param name="Row">The row that is currently passing through the component</param>
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
var serializer = AvroSerializer.CreateGeneric(Schema);
var rootSchema = serializer.WriterSchema as RecordSchema;
//Create a generic record to represent the data
dynamic DatesRow = new AvroRecord(rootSchema);
DatesRow.MK_DatesID = Row.MKDatesID;
DatesRow.Date = Row.Date.ToString();
DatesRow.IsTradingDay = Row.IsTradingDay;
DatesRowList.Add(DatesRow);
}
}
基本上这个脚本组件充当目的地并写入 avro 文件。
如前所述,一切都适用于我的本地。我什至尝试从服务器上的 SSIS 目录下载我本地的包,然后执行它,即使这样也能正常工作(只是为了看看在部署过程中是否发生了某些变化或出现问题)。我无法解释这里缺少什么。顺便说一下,这是 SSIS 2016,部署到目录(项目部署模型),然后我通过 SQL 代理作业执行它。
脚本组件的Target框架为.Net 4.5
有人有解决这个问题的想法吗?
如果需要更多信息,我很乐意提供。
所以,我发现了这个案例的问题。 运行 SQL 作业步骤的代理帐户没有正确的访问权限。这就是它抛出神秘错误的原因 - "Binary code for the script not found"。创建代理帐户、本地管理员并成功。
我 运行 遇到了这个奇怪的 SSIS 错误,服务器上的脚本组件一直失败并显示错误 -"The binary code for the script is not found. Please open the script and make sure it build correctly"。 该脚本在我的本地机器上构建得非常好。除了打开脚本组件时获得的标准引用之外,脚本组件基本上引用 3 个额外的 DLL。这些 dll 是 Microsoft.Hadoop.avro.dll、Newtonsoft.json.dll 和 Microsoft.Csharp。
Microsoft.Hadoop.avro 和 Newtonsoft.json 是我必须下载的,我什至已经在本地和服务器上注册到 GAC。
我试过打开组件、重建它们、保存它们并部署它们。我已将数据流上的 DelayValidation 设置为 False。我已将参考部分中的 dll 的 "Copy local" 设置为 False。我通过显式放入 GAC 位置重新添加了引用,即 C:\Windows\Microsoft.Net\Assembly\GAC_MSIL.
这是脚本组件的示例代码
#region Help: Introduction to the Script Component
/* The Script Component allows you to perform virtually any operation that can be accomplished in
* a .Net application within the context of an Integration Services data flow.
*
* Expand the other regions which have "Help" prefixes for examples of specific ways to use
* Integration Services features within this script component. */
#endregion
#region Namespaces
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using Microsoft.Hadoop.Avro;
using Microsoft.Hadoop.Avro.Container;
using Microsoft.Hadoop.Avro.Schema;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using Microsoft.CSharp.RuntimeBinder;
using System.Linq;
using System.Reflection;
#endregion
/// <summary>
/// This is the class to which to add your code. Do not change the name, attributes, or parent
/// of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
#region Help: Using Integration Services variables and parameters
/* To use a variable in this script, first ensure that the variable has been added to
* either the list contained in the ReadOnlyVariables property or the list contained in
* the ReadWriteVariables property of this script component, according to whether or not your
* code needs to write into the variable. To do so, save this script, close this instance of
* Visual Studio, and update the ReadOnlyVariables and ReadWriteVariables properties in the
* Script Transformation Editor window.
* To use a parameter in this script, follow the same steps. Parameters are always read-only.
*
* Example of reading from a variable or parameter:
* DateTime startTime = Variables.MyStartTime;
*
* Example of writing to a variable:
* Variables.myStringVariable = "new value";
*/
#endregion
#region Help: Using Integration Services Connnection Managers
/* Some types of connection managers can be used in this script component. See the help topic
* "Working with Connection Managers Programatically" for details.
*
* To use a connection manager in this script, first ensure that the connection manager has
* been added to either the list of connection managers on the Connection Managers page of the
* script component editor. To add the connection manager, save this script, close this instance of
* Visual Studio, and add the Connection Manager to the list.
*
* If the component needs to hold a connection open while processing rows, override the
* AcquireConnections and ReleaseConnections methods.
*
* Example of using an ADO.Net connection manager to acquire a SqlConnection:
* object rawConnection = Connections.SalesDB.AcquireConnection(transaction);
* SqlConnection salesDBConn = (SqlConnection)rawConnection;
*
* Example of using a File connection manager to acquire a file path:
* object rawConnection = Connections.Prices_zip.AcquireConnection(transaction);
* string filePath = (string)rawConnection;
*
* Example of releasing a connection manager:
* Connections.SalesDB.ReleaseConnection(rawConnection);
*/
#endregion
#region Help: Firing Integration Services Events
/* This script component can fire events.
*
* Example of firing an error event:
* ComponentMetaData.FireError(10, "Process Values", "Bad value", "", 0, out cancel);
*
* Example of firing an information event:
* ComponentMetaData.FireInformation(10, "Process Values", "Processing has started", "", 0, fireAgain);
*
* Example of firing a warning event:
* ComponentMetaData.FireWarning(10, "Process Values", "No rows were received", "", 0);
*/
#endregion
string copiedAddressFile;
private StreamWriter textWriter;
private string columnDelimiter = ",";
List<AvroRecord> DatesRowList;
public override void AcquireConnections(object Transaction)
{
IDTSConnectionManager100 connMgr = this.Connections.Dates;
copiedAddressFile = (string)connMgr.AcquireConnection(null);
}
public static string Schema = "";
/// <summary>
/// This method is called once, before rows begin to be processed in the data flow.
///
/// You can remove this method if you don't need to do anything here.
/// </summary>
public override void PreExecute()
{
base.PreExecute();
Schema = @"{
""type"":""record"",
""name"":""Microsoft.Hadoop.Avro.Specifications.Dates"",
""fields"":
[
{ ""name"":""MK_DatesID"", ""type"":""int"" },
{ ""name"":""Date"", ""type"":""string"" },
{ ""name"":""IsTradingDay"", ""type"":""boolean"" }
]
}";
DatesRowList = new List<AvroRecord>();
}
/// <summary>
/// This method is called after all the rows have passed through this component.
///
/// You can delete this method if you don't need to do anything here.
/// </summary>
public override void PostExecute()
{
base.PostExecute();
if (Variables.PushToDataLake == true)
{
using (Stream st = new FileStream(copiedAddressFile, FileMode.Create, FileAccess.Write, FileShare.Write))
{
using (var w = AvroContainer.CreateGenericWriter(Schema, st, Codec.Deflate))
{
using (var writer = new SequentialWriter<object>(w, 24))
{
// Serialize the data to stream using the sequential writer
DatesRowList.ForEach(writer.Write);
}
}
}
}
}
/// <summary>
/// This method is called once for every row that passes through the component from Input0.
///
/// Example of reading a value from a column in the the row:
/// string zipCode = Row.ZipCode
///
/// Example of writing a value to a column in the row:
/// Row.ZipCode = zipCode
/// </summary>
/// <param name="Row">The row that is currently passing through the component</param>
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
var serializer = AvroSerializer.CreateGeneric(Schema);
var rootSchema = serializer.WriterSchema as RecordSchema;
//Create a generic record to represent the data
dynamic DatesRow = new AvroRecord(rootSchema);
DatesRow.MK_DatesID = Row.MKDatesID;
DatesRow.Date = Row.Date.ToString();
DatesRow.IsTradingDay = Row.IsTradingDay;
DatesRowList.Add(DatesRow);
}
}
基本上这个脚本组件充当目的地并写入 avro 文件。
如前所述,一切都适用于我的本地。我什至尝试从服务器上的 SSIS 目录下载我本地的包,然后执行它,即使这样也能正常工作(只是为了看看在部署过程中是否发生了某些变化或出现问题)。我无法解释这里缺少什么。顺便说一下,这是 SSIS 2016,部署到目录(项目部署模型),然后我通过 SQL 代理作业执行它。
脚本组件的Target框架为.Net 4.5
有人有解决这个问题的想法吗?
如果需要更多信息,我很乐意提供。
所以,我发现了这个案例的问题。 运行 SQL 作业步骤的代理帐户没有正确的访问权限。这就是它抛出神秘错误的原因 - "Binary code for the script not found"。创建代理帐户、本地管理员并成功。