Скопируйте таблицу доступа с первичными ключами

#c# #ms-access #odbc

Вопрос:

Использование C#, ODBC и движка Jet 4.0 для работы с (старой) базой данных Access. Задача требует, чтобы я не использовал DAO.

Ядро базы данных Microsoft Jet 4.0, к сожалению, не поддерживает ключевое слово «ПЕРЕИМЕНОВАТЬ». Все следующие действия создают исключение:

  • ПЕРЕИМЕНУЙТЕ ТАБЛИЦУ old_name В new_name;
  • ПЕРЕИМЕНУЙТЕ старое имя В новое;
  • ИЗМЕНИТЬ СТАРОЕ имя ТАБЛИЦЫ ПЕРЕИМЕНОВАТЬ В новое имя;

Но следующий синтаксис работает:

 SELECT * INTO new_name FROM old_name;
 

Проблема в том, что первичные ключи не копируются.

Есть ли способ создать копию таблицы и в хранилище копий указать, какие поля являются первичными ключами?

Комментарии:

1. Эх… Задача требует, чтобы я не использовал DAO , почему? DAO поставляется вместе с ядром базы данных Access, поэтому, если вы можете устанавливать подключения ODBC, вы обычно можете использовать DAO, а доступ имеет ограниченную поддержку DDL, для многих операций вам нужен DAO.

2. Спасибо @ErikA. Это вполне может оказаться плохим требованием! Наша цель-создать универсальный интерфейс, который позволяет нам поддерживать как доступ, так и другие типы баз данных, такие как MySQL. Старший разработчик здесь установил требование, чтобы мы вообще НЕ использовали DAO. Поэтому я пытаюсь сделать это в сыром SQL и драйвере ODBC, если это вообще возможно. Теперь я могу делать почти все на языке raw SQL с помощью ODBC. Если эта конкретная задача действительно невозможна без ДАО, это было бы очень полезно знать!

Ответ №1:

С помощью ODBC вы можете получать/захватывать индексы. В большинстве случаев столбец PK имеет индекс, называемый первичным ключом. Это не гарантируется на 100%.

Таким образом, это будет работать «большую часть» времени:

напр.:

 Sub Test22()

    Using con As New OdbcConnection(My.Settings.Test44ODBC2)
        '            Using cmdSQL As New OdbcCommand("SELECT TOP 1 * From PKTEST", con)

        con.Open()

        Dim schemaTable As New DataTable
        schemaTable = con.GetSchema("Indexes", New String() {Nothing, Nothing, "PKTEST"})
        Me.DataGridView1.DataSource = schemaTable

    End Using

 End Sub
 

Выход:

введите описание изображения здесь

Однако пользователь мог создать индекс и присвоить ему другое имя.

Так, например, я могу перейти к приведенной выше таблице и переименовать первичный ключ на все, что я хочу,-скажите это:

введите описание изображения здесь

Так что, не очень здорово.

Однако, в то время как приложение и «большая часть» вашего кода могут придерживаться ODBC?

Если вы используете oleDB, то вы МОЖЕТЕ СО 100% надежностью получить PK, и вам не нужно было ссылаться на DAO.

Итак, хотя выше показано, что мы переименовали PK с «zoo» в конце, этот oleDB-код ВСЕ равно вернет столбец PK следующим образом:

 Sub GetoleDBGetKey()

    Using con As New OleDbConnection(My.Settings.TESTAce)
        Using cmdSQL As New OleDbCommand("SELECT * from PKTEST", con)

            con.Open()
            Dim schemaTable As DataTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys,
                            New Object() {Nothing, Nothing, "PKTEST"})

            Me.DataGridView1.DataSource = schemaTable
        End Using
    End Using
End Sub
 

введите описание изображения здесь

Таким образом, oleDB будет работать на 100%.

Снип ODBC выше? Ну, мы должны были бы предположить «PrimaryKey», и это на самом деле не является обязательным требованием (то, что он/был назван «PrimaryKey»).

Итак, вы могли бы рассмотреть возможность oleDB.

Я не копал очень глубоко, но я не думаю, что ODBC может получить PK с надежностью.

Вы могли бы поиграть с гетшемой odbc, которую я привел выше. Есть некоторые фрагменты кода, которые предполагают, что вы открываете соединение, открываете считыватель и используете getschema считывателя данных, и это ДЕЙСТВИТЕЛЬНО работает — но у меня нет рабочего примера (или даже знаю, может ли это сработать — но есть некоторые предположения, что это может/работает).

Комментарии:

1. Это может быть адаптировано к моим потребностям, спасибо! Я проверил OdbcConnection::GetSchema . В таблицах, которые я просматриваю, все первичные ключи по-прежнему называются «PrimaryKey», поэтому ODBC будет работать. Но спасибо за комментарий, что это не гарантировано, если индекс был переименован…отмечено! Я также протестировал OleDbConnection::GetOleDbSchemaTable , и это работает именно так, как было предложено.

2. Как уже отмечалось, некоторые предположили, что GetSchema против читателя odbc может работать, но я не пошел дальше получения индексов. В схеме для odbc есть флаг первичного ключа, но, к сожалению, он не установлен. Первичный ключ, вероятно, в порядке, но, как уже отмечалось, это предположение не на 100%. Кроме того, в том первом фрагменте кода не было необходимости создавать объект команды — это было просто вырезание вставка некоторого кода, который у меня был.