使用 SSIS 脚本任务 (VB) 将 Excel 数据导入现有 SQL 服务器 table 时出现问题
Having issues importing Excel data into existing SQL Server table using SSIS script task (VB)
我已经使用 Excel 文件中 table 的数据成功加载了数据 table 对象。我如何在 UPDATE 查询中使用此数据 table 对象来更新现有的 SQL 服务器 table?
我遇到这个错误:
Exception has been thrown by the target of an invocation.
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()
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
Dim SQLPara As SqlClient.SqlParameter
'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) '<- this datatable object is filled with the data successfully
'using the dtExcel datatable as a table input, update the existing dbo.TEST_INPUT_SIMPLE SQL Server table
SQLCmd = SQLConn.CreateCommand()
SQLCmd.CommandText = "UPDATE TIS SET TIS.MY_COLUMN = TISX.MY_COLUMN " &
"FROM dbo.TEST_INPUT_SIMPLE TIS INNER JOIN @source AS TISX " &
"ON TIS.UPDATE_ID = TISX.UPDATE_ID"
SQLCmd.CommandType = CommandType.Text
SQLCmd.Parameters.AddWithValue("@source", dtExcel).SqlDbType = SqlDbType.Structured
SQLCmd.ExecuteNonQuery() '<-- the program errors on this line
Dts.TaskResult = ScriptResults.Success
End Sub
更新 1
我认为问题在于您没有在 SQL 服务器中声明 table 结构。而不是你使用 SqlDbType.Structured
而不指定类型名称:
SQLCmd.Parameters.AddWithValue("@source", dtExcel).SqlDbType = SqlDbType.Structured
有关如何将数据table 作为参数传递给SQL 服务器的更多信息,请查看以下 SO 问题:
- How to insert a data table into SQL Server database table?
此外,在 link you have mentioned in your comments 他们使用 dbo.tStudent
作为类型名称:
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.tStudent";
初始答案
如果您希望通过加入 Excel 文件来更新 SQL Table,这不是正确的方法。您以这种方式传递 table 作为参数。加入 Excel table 和 SQL Table:
有很多方法
在SQL服务器
- Import Excel to a staging table in SQL Server and then run the query
- 将 Excel 工作表添加为 a Linked Server in SQL Server
- Using OPENROWSET in SQL Server
在 SSIS 中
- 在 SSIS 中,在数据流任务中使用
Excel Source
和 OLEDB Command
,the update command will be written in the OLEDB Command
在VB / C#
- Import data to SQL 然后 运行 更新查询
我没有在此答案中提供太多细节,但我试图提供一些见解,说明您可以使用比脚本任务更好的方法来实现您的目标。每个 link 包含您需要的信息以及更多
我通过执行以下步骤解决了这个问题:
1) 在数据库中创建一个用户定义的表类型:
CREATE TYPE [dbo].[MyTableType] AS TABLE(
[UPDATE_ID] NVARCHAR(255),
[MY_COLUMN] NVARCHAR(255)
)
2) 创建包含先前创建的表类型和更新查询的存储过程:
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
感谢您的帮助!
我已经使用 Excel 文件中 table 的数据成功加载了数据 table 对象。我如何在 UPDATE 查询中使用此数据 table 对象来更新现有的 SQL 服务器 table?
我遇到这个错误:
Exception has been thrown by the target of an invocation.
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()
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
Dim SQLPara As SqlClient.SqlParameter
'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) '<- this datatable object is filled with the data successfully
'using the dtExcel datatable as a table input, update the existing dbo.TEST_INPUT_SIMPLE SQL Server table
SQLCmd = SQLConn.CreateCommand()
SQLCmd.CommandText = "UPDATE TIS SET TIS.MY_COLUMN = TISX.MY_COLUMN " &
"FROM dbo.TEST_INPUT_SIMPLE TIS INNER JOIN @source AS TISX " &
"ON TIS.UPDATE_ID = TISX.UPDATE_ID"
SQLCmd.CommandType = CommandType.Text
SQLCmd.Parameters.AddWithValue("@source", dtExcel).SqlDbType = SqlDbType.Structured
SQLCmd.ExecuteNonQuery() '<-- the program errors on this line
Dts.TaskResult = ScriptResults.Success
End Sub
更新 1
我认为问题在于您没有在 SQL 服务器中声明 table 结构。而不是你使用 SqlDbType.Structured
而不指定类型名称:
SQLCmd.Parameters.AddWithValue("@source", dtExcel).SqlDbType = SqlDbType.Structured
有关如何将数据table 作为参数传递给SQL 服务器的更多信息,请查看以下 SO 问题:
- How to insert a data table into SQL Server database table?
此外,在 link you have mentioned in your comments 他们使用 dbo.tStudent
作为类型名称:
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.tStudent";
初始答案
如果您希望通过加入 Excel 文件来更新 SQL Table,这不是正确的方法。您以这种方式传递 table 作为参数。加入 Excel table 和 SQL Table:
有很多方法在SQL服务器
- Import Excel to a staging table in SQL Server and then run the query
- 将 Excel 工作表添加为 a Linked Server in SQL Server
- Using OPENROWSET in SQL Server
在 SSIS 中
- 在 SSIS 中,在数据流任务中使用
Excel Source
和OLEDB Command
,the update command will be written in theOLEDB Command
在VB / C#
- Import data to SQL 然后 运行 更新查询
我没有在此答案中提供太多细节,但我试图提供一些见解,说明您可以使用比脚本任务更好的方法来实现您的目标。每个 link 包含您需要的信息以及更多
我通过执行以下步骤解决了这个问题:
1) 在数据库中创建一个用户定义的表类型:
CREATE TYPE [dbo].[MyTableType] AS TABLE(
[UPDATE_ID] NVARCHAR(255),
[MY_COLUMN] NVARCHAR(255)
)
2) 创建包含先前创建的表类型和更新查询的存储过程:
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
感谢您的帮助!