Проверьте, существует ли таблица PostgreSQL с Npgsql

До сих пор я не вижу никакой разницы в использовании драйвера Npgsql вместо ODBC при работе с базой данных PostgreSQL в Windows. Но теперь я нахожу один.

У меня есть такой код, чтобы проверить, существует ли таблица с ODBC:

Public Function dbTableExists(ByVal dbTable As String, ByVal dbName As String) As Boolean

    Dim retval As Boolean = False
    Dim nCon As New OdbcConnection
    Dim btCommand As OdbcCommand = Nothing
    nCon.ConnectionString = "Dsn=" + dbDsn + _
                            ";database=" + dbName & _
                            ";server=" + dbServer + _
                            ";port=" + dbPort + _
                            ";uid=" + dbUser + _
                            ";pwd=" + dbPass
    Try
        nCon.Open()
        btCommand = New OdbcCommand("SELECT 1 FROM pg_tables WHERE tablename='" & dbTable + "'", nCon)
        retval = CBool(btCommand.ExecuteNonQuery())

    Catch ex As Exception
        MsgBox(ex.Message, MsgBoxStyle.Critical)
        retval = False
    End Try

    Return retval
End Function

С помощью этого кода я получаю True, если конкретная таблица существует в определенной базе данных, или False в противном случае.
Когда я пытаюсь использовать Npgsql вместо ODBC, функция очень похожа:

Public Function tExists(ByVal dbTable As String, ByVal dbName As String) As Boolean

    Dim retval As Boolean = False
    Dim btCommand As NpgsqlCommand = Nothing
    Dim nCon As New NpgsqlConnection(String.Format( _
                    "Server={0};Port={1};User Id={2};Password={3};Database={4};", _
                    dbServer, dbPort, dbUser, dbPass, dbName))
    Try
        nCon.Open()
        btCommand = New NpgsqlCommand("SELECT 1 FROM pg_tables WHERE tablename='" & dbTable + "'", nCon)
        retval = CBool(btCommand.ExecuteNonQuery())

    Catch ex As Exception
        MsgBox(ex.Message, MsgBoxStyle.Critical)
        retval = False
    End Try

    Return retval
End Function

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

Есть идеи, как заставить работать функцию Npgsql?


person Wine Too    schedule 07.02.2013    source источник
comment
Почему вы используете executeNonQuery()? Вы выполняете запрос, поэтому не следует ли вам использовать executeQuery() (или что-то подобное - я не знаю .Net)   -  person a_horse_with_no_name    schedule 07.02.2013
comment
Здравствуй имя. Ваша логика, как обычно, превосходна. По какой-то причине MS ODBC возвращает значение запроса с executeNonQuery, но Npgsql неожиданно этого не делает. Я не знал об этой разнице до сих пор. Но вот ExecuteScalar, которые возвращают первую строку или значение (такого рода) запроса. Таким образом, с помощью ExecuteScalar я получаю ожидаемый результат показанного запроса и заставляю свою функцию Npgsql работать. Спасибо, что указали мне правильное направление.   -  person Wine Too    schedule 07.02.2013
comment
Не могли бы вы включить это в качестве примера? Я был бы рад проголосовать.   -  person Chris Travers    schedule 24.04.2013
comment
сработал метод с information_schema?   -  person Tobia Zambon    schedule 02.08.2013


Ответы (1)


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

 public override bool TableExists(string tableName)
    {
        string sql = "SELECT * FROM information_schema.tables WHERE table_name = '" + tableName + "'";
        using (var con = new NpgsqlConnection(preparedConnectionString))
        {
            using (var cmd = new NpgsqlCommand(sql))
            {
                if (cmd.Connection == null)
                    cmd.Connection = con;
                if (cmd.Connection.State != ConnectionState.Open)
                    cmd.Connection.Open();

                lock (cmd)
                {
                    using (NpgsqlDataReader rdr = cmd.ExecuteReader())
                    {
                        try
                        {
                            if (rdr != null && rdr.HasRows)
                                return true;
                            return false;
                        }
                        catch (Exception)
                        {
                            return false;
                        }
                    }
                }
            }
        }
    }

(Не заботьтесь об инъекции или подобном)

person Tobia Zambon    schedule 15.07.2013