Проблемы с импортом данных Excel в существующую таблицу SQL Server с помощью задачи сценария служб SSIS (VB) - PullRequest
0 голосов
/ 13 февраля 2019

Я успешно загрузил объект данных с данными из таблицы в файл Excel.Как использовать этот объект таблицы данных в запросе UPDATE для обновления существующей таблицы SQL Server?

Я сталкиваюсь с этой ошибкой:

Исключение было выдано целью вызова.

в System.RuntimeMethodHandle.InvokeMethod (Object target, Object []аргументы, сигнатура sig, логический конструктор) в System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal (параметры объекта, параметры объекта [], аргументы объекта [], аргументы) в System.Reflection.RuntimeMethodInfo.Invoke (объектный объект, BindingFlags invokeAttr, связыватель связующего, объект [] параметры, CultureInfo culture) в System.RuntimeType.InvokeMember (имя строки, BindingFlags bindingFlags, связыватель Binder, объектная цель, модификаторы Object [] provideArgs, ParameterModifier [], CultureInfo culture, String [] namedParams) в 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

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Я решил эту проблему, выполнив следующие шаги:

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

Спасибо за помощь!

0 голосов
/ 13 февраля 2019

Обновление 1

Мне кажется, проблема в том, что вы не объявили структуру таблицы в SQL Server.И вместо этого вы используете SqlDbType.Structured без указания имени типа:

SQLCmd.Parameters.AddWithValue("@source", dtExcel).SqlDbType = SqlDbType.Structured

Для получения дополнительной информации о том, как передавать данные в качестве параметра в SQL Server, проверьте следующий вопрос SO:

Кроме того, в ссылке , которую вы упомянули в своих комментариях онииспользовал dbo.tStudent в качестве имени типа:

param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.tStudent";

Начальный ответ

Если вы хотите обновить таблицу SQL, присоединив файл Excel, это неправильный путь.Таким образом вы передаете таблицу в качестве параметра.Существует множество подходов к объединению таблицы Excel с таблицей SQL:

В SQL Server

В SSIS

В VB / C #

Я не предоставил слишком много подробностей в этом ответе, но я попытался дать некоторое представление о подходах, которые вы можете использовать лучше, чем задача сценария для достижения своей цели.Каждая ссылка содержит необходимую информацию и многое другое

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...