Массовое копирование с динамически созданной временной таблицей в ADO.NET

Мне нужно создать через ADO.NET временную таблицу, выполнить BulkCopy, а затем Merge на сервере между временной и реальной таблицей.

Проблема заключается в динамическом создании временной таблицы с использованием чистого ADO.NET. Схема должна быть такой же, как у существующей таблицы, но эта таблица создана с использованием ORM (NHibernate или Entity Framework, мы еще не уверены). Это также означает, что схема может измениться в будущем.

Есть ли способ создать таблицу в базе данных с помощью простых объектов ADO.NET? Например, DataTable, содержащий схему исходной таблицы?

Любая информация, указывающая мне в правильном направлении, приветствуется.


person Ronald    schedule 10.04.2013    source источник


Ответы (2)


Вы можете создать временную таблицу, используя select into #somename.

connection_ = New SqlClient.SqlConnection(connection_string_)
connection_.Open()
If connection_.State = ConnectionState.Open Then

    command_.Connection = connection_
    command_.CommandType = CommandType.Text
    command_.CommandText = "select * into #some_table from some_table where some_id = 0"
    command_.ExecuteNonQuery()

    Dim line_index_ As Integer = 0
    Dim data_table_ As DataTable = New DataTable()
    Using parser_ As FileIO.TextFieldParser = New FileIO.TextFieldParser(path_)
        parser_.SetDelimiters(delimiter_)
        parser_.HasFieldsEnclosedInQuotes = False
        While Not parser_.EndOfData
            If line_index_ = 0 Then
                Dim headers_ As String() = parser_.ReadFields()
                For Each header_ In headers_
                    data_table_.Columns.Add(header_)
                Next
            Else
                Dim row_ As DataRow = data_table_.NewRow()
                row_.ItemArray = parser_.ReadFields()
                data_table_.Rows.Add(row_)
            End If
            line_index_ += 1
        End While
     End Using

     Using bulkCopy_ As SqlBulkCopy = New SqlBulkCopy(connection_)
           bulkCopy_.DestinationTableName = "#some_table"
           bulkCopy_.WriteToServer(data_table_)
     End Using

    ' proof
    command_.CommandText = "select * from #some_table"
    Dim reader_ As SqlDataReader = Nothing
    reader_ = command_.ExecuteReader
    line_index_ = 0
    While reader_.Read
        line_index_ += 0
    End While

 End If
person Keith John Hutchison    schedule 14.11.2013
comment
Вы можете использовать TOP 0 вместо предложения WHERE, чтобы гарантировать отсутствие результатов. SELECT TOP 0 * INTO #TmpTable FROM SomeTable; - person Robert; 08.08.2014
comment
Это решение кажется идеальным, но оно может потерпеть неудачу в зависимости от ваших ограничений. Например, у меня есть поле creation DATETIME NOT NULL DEFAULT GETDATE(). Однако временная таблица хранит NOT NULL, но не DEFAULT GETDATE(), что означает, что мне придется учитывать это при массовой вставке. - person atheaos; 09.05.2016
comment
Если вы оставите тот же сеанс открытым, у вас будет доступ к только что созданной временной таблице. Вы можете создать хранимую процедуру для работы с этой временной таблицей и взять ее оттуда. - person Keith John Hutchison; 10.05.2016
comment
Вы также можете сначала создать временную таблицу с вашими ограничениями и выполнить вставку вместо выбора. - person Keith John Hutchison; 10.05.2016

Мне удалось создать временную таблицу на основе существующей схемы.

Записал решение на своем сайте.

person Ronald    schedule 25.04.2013
comment
Вы можете использовать TOP 0 вместо предложения WHERE, чтобы гарантировать отсутствие результатов. SELECT TOP 0 * INTO #TmpTable FROM SomeTable; - person Robert; 08.08.2014
comment
Вы перебираете список столбцов 3 раза, что можно было бы сделать за один раз. Большая часть вашего кода собирается вставить столбцы в построитель строк, который вы даже нигде не используете. - person Daniel Leiszen; 24.10.2017
comment
@ Даниэль Лейзен, ты прав. Я рад сказать 5 лет спустя, что тогда я писал плохой код :) Надеюсь, что смогу продолжать говорить это в следующие 5 лет о сегодняшнем коде :) - person Ronald; 10.01.2018
comment
@ Рональд, да, это всегда хорошо. Тем не менее, я немного верю, что мои навыки программирования наконец достигли определенного уровня, и есть другие области, над которыми я могу работать :) - person Daniel Leiszen; 14.02.2018