Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 使用SSIS脚本任务(VB)将Excel数据导入现有SQL Server表时出现问题_Sql Server_Excel_Vb.net_Ssis_Script Task - Fatal编程技术网

Sql server 使用SSIS脚本任务(VB)将Excel数据导入现有SQL Server表时出现问题

Sql server 使用SSIS脚本任务(VB)将Excel数据导入现有SQL Server表时出现问题,sql-server,excel,vb.net,ssis,script-task,Sql Server,Excel,Vb.net,Ssis,Script Task,我已成功加载datatable对象,其中包含Excel文件中表格中的数据。如何在更新查询中使用此数据表对象更新现有SQL Server表 我遇到这个错误: 调用的目标已引发异常 位于System.RuntimeMethodHandle.InvokeMethod(对象目标、对象[]参数、签名符号、布尔构造函数) 位于System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(对象obj,对象[]参数,对象[]参数) 在System.Reflec

我已成功加载datatable对象,其中包含Excel文件中表格中的数据。如何在更新查询中使用此数据表对象更新现有SQL Server表

我遇到这个错误:

调用的目标已引发异常

位于System.RuntimeMethodHandle.InvokeMethod(对象目标、对象[]参数、签名符号、布尔构造函数) 位于System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(对象obj,对象[]参数,对象[]参数) 在System.Reflection.RuntimeMethodInfo.Invoke(对象obj、BindingFlags invokeAttr、绑定器绑定器、对象[]参数、CultureInfo区域性) 位于System.RuntimeType.InvokeMember(字符串名称、BindingFlags BindingFlags、绑定器绑定器、对象目标、对象[]提供的参数、参数修改器[]修饰符、CultureInfo区域性、字符串[]namedParams) 位于Microsoft.SqlServer.Dts.Tasks.ScriptTask.vstatasksscriptingengine.ExecuteScript()处

Public Sub-Main()
Dim fileToTest作为字符串
将SheetName设置为字符串
Dim connectionString作为字符串
将连接设置为OLEDB连接
Dim excel命令作为OleDbCommand
将ODA设置为OLEDB数据适配器
Dim dtExcel作为新数据表()
Dim SQLConn作为SqlClient.SqlConnection
Dim SQLCmd作为SqlClient.SqlCommand
将SQLPara设置为SqlClient.SqlParameter
'打开到excel文件的连接
fileToTest=“C:\Users\testuser\Documents\test\mytestfile.xls”
connectionString=“Provider=Microsoft.Jet.OLEDB.4.0;”和“数据源=”&
fileToTest&“扩展属性=”“Excel 8.0;HDR=YES;IMEX=1”
excelConnection=新的OLEDB连接(connectionString)
excelConnection.Open()
'打开到LRPSF_源数据库SQL Server数据库的SQL连接
connectionString=“数据源=mysqlserver.net\sqlentdb1d;可信连接=True;数据库=LRPSF\u源\u DB;连接重置=FALSE”
SQLConn=newsqlclient.SqlConnection(connectionString)
SQLConn.Open()
'使用命令查询从Excel文件中的测试表中获取数据并存储在datatable对象中
SheetName=“测试$”
excelCommand=excelConnection.CreateCommand()
excelCommand.CommandText=“从[”&SheetName&“]中选择*
excelCommand.CommandType=CommandType.Text
ODA=新的OleDbDataAdapter(EXCEL命令)
ODA.Fill(dtExcel)“更新1”
我认为问题在于您没有在SQL Server中声明表结构。而不是使用
SqlDbType.Structured
,而不指定类型名称:

SQLCmd.Parameters.AddWithValue("@source", dtExcel).SqlDbType = SqlDbType.Structured
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.tStudent";
有关如何将datatable作为参数传递给SQL Server的详细信息,请检查以下问题:

此外,在中,他们使用了
dbo.tStudent
作为类型名称:

SQLCmd.Parameters.AddWithValue("@source", dtExcel).SqlDbType = SqlDbType.Structured
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.tStudent";
初步答复 如果您希望通过连接Excel文件来更新SQL表,那么这不是正确的方法。以这种方式传递表作为参数。将Excel表与SQL表联接的方法有很多:

SQL Server中的

  • 将Excel工作表添加为
SSI中的

  • 在SSIS中,在数据流任务中使用
    Excel源代码
    OLEDB命令
在VB/C中

  • 然后运行更新查询

在这个答案中,我没有提供太多细节,但我试图给出一些见解,说明哪些方法可以比脚本任务更好地实现目标。每个链接都包含您需要的信息以及更多信息

我通过执行以下步骤解决了此问题:

1) 在数据库中创建用户定义的表类型:

CREATE TYPE [dbo].[MyTableType] AS TABLE(
    [UPDATE_ID] NVARCHAR(255),
    [MY_COLUMN] NVARCHAR(255)
)
2) 创建包含以前创建的tabletype和update查询的存储过程:

CREATE procedure UpdateDB
    @myTableType MyTableType readonly
AS
BEGIN
    UPDATE TIS SET TIS.MY_COLUMN = TISX.MY_COLUMN 
    FROM dbo.TEST_INPUT_SIMPLE TIS INNER JOIN @myTableType AS TISX 
    ON TIS.UPDATE_ID = TISX.UPDATE_ID
END
3) 使用VB脚本任务,获取Excel数据并运行存储过程:

Public Sub Main()

    Dim fileToTest As String
    Dim SheetName As String
    Dim connectionString As String
    Dim excelConnection As OleDbConnection
    Dim excelCommand As OleDbCommand
    Dim ODA As OleDbDataAdapter
    Dim dtExcel As New DataTable()
    Dim SQLConn As SqlClient.SqlConnection
    Dim SQLCmd As SqlClient.SqlCommand

    'open a connection to the excel file'
    fileToTest = "C:\Users\testuser\Documents\test\mytestfile.xls"
    connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" &
    fileToTest & ";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1"""
    excelConnection = New OleDbConnection(connectionString)
    excelConnection.Open()

    'open a SQL connection to the LRPSF_Source_DB SQL Server DB'
    connectionString = "Data Source=mysqlserver.net\sqlentdb1d;Trusted_Connection=True;DATABASE=LRPSF_Source_DB;CONNECTION RESET=FALSE"
    SQLConn = New SqlClient.SqlConnection(connectionString)
    SQLConn.Open()

    'fetch the data from TEST table in Excel file using a command query and store in datatable object'
    SheetName = "TEST$"
    excelCommand = excelConnection.CreateCommand()
    excelCommand.CommandText = "SELECT * FROM [" & SheetName & "]"
    excelCommand.CommandType = CommandType.Text
    ODA = New OleDbDataAdapter(excelCommand)
    ODA.Fill(dtExcel) 'object is filled with Excel data'

    'load the dtExcel object into @myTableType object and run the stored procedure'
    SQLCmd = SQLConn.CreateCommand() 
    SQLCmd.CommandText = "[dbo].[UpdateDB]"
    SQLCmd.CommandType = CommandType.StoredProcedure
    SQLCmd.Parameters.AddWithValue("@myTableType", dtExcel) 
    SQLCmd.ExecuteNonQuery() 'run the stored procedure containing the update query'

    Dts.TaskResult = ScriptResults.Success

End Sub

谢谢你的帮助

vb第三个链接中的代码不适合批量复制。它试图做一个读卡器。在一个循环中阅读并传递给读卡器。我甚至不知道那会有什么用,但没什么好处。@Mary我一点也不喜欢这种方法。我支持SSIS方法。但我试图给VR一些洞察力,并显示出可能solutions@Hadi-非常感谢你的帮助。你知道在这种情况下我将如何使用VB代码声明TypeName吗?我想这可能是丢失的那块。我还将尝试先在SQL Server中设置用户定义的TableType对象,然后将其作为脚本任务中的参数传入,如上面的链接所述。@JustinCR使用SQLCommand和ExecuteOnQuery方法。创建一个类型,如我提供的链接中所述,您应该在其中描述datatable结构。@请注意,您收到的错误消息是脚本任务中引发的一般异常。阅读真正的信息。添加一个
尝试。。。Catch
block并在Catch块中使用Dts.firererror方法来重新显示异常。我认为您应该接受或投票支持另一个答案,因为它解决了问题。你可以留下你的答案来提供更多细节。但是这个问题似乎是根据Hadi answerHadi的更新部分解决的。Hadi的回答非常有用,因为它引导我使用存储表类型和过程作为起点。但是,它缺少通过脚本任务执行它所需的附加VB代码,脚本任务是最初的任务执行方法。因此,我认为我的答案是这方面的完整答案。你有权接受你自己的答案。很高兴解决了这个问题。如果答案对你有帮助的话,你可以投上一票,然后接受你自己的答案。好luck@JustinCR因此,你应该接受你的答案,并向上投票另一个,说明你有完整的版本,但另一个是有用的。我向上投票哈迪的答案,因为它非常有用,并接受我的作为最终答案。如果有,请告诉我