Как я могу в целом определить, является ли база данных «пустой» из Java

Может ли кто-нибудь предложить хороший способ определить, пуста ли база данных из Java (должна поддерживать как минимум Microsoft SQL Server, Derby и Oracle)?

Под пустым я подразумеваю, что в состоянии было бы, если бы база данных была только что создана с новым оператором создания базы данных, хотя проверка не должна быть на 100% идеальной, если охватывает 99% случаев.

Первой моей мыслью было сделать что-то подобное ...

tables = metadata.getTables(null, null, null, null);
Boolean isEmpty = !tables.next();
return isEmpty;

... но, к сожалению, это дает мне кучу базовых системных таблиц (по крайней мере, в Microsoft SQL Server).

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
2 513
5

Ответы 5

Вы всегда проверяете базы данных, созданные одинаково? Если это так, вы могли бы просто выбрать из подмножества таблиц, с которыми вы знакомы, для поиска данных.

Возможно, вам также придется беспокоиться о статических данных, которые, возможно, добавлены в таблицу поиска, которая на первый взгляд выглядит как «данные», но на самом деле может не быть «данными» в интересном смысле этого слова.

Можете ли вы предоставить дополнительную информацию о конкретной проблеме, которую вы пытаетесь решить? Интересно, можно ли с большим количеством данных дать более простой и надежный ответ.

Вы создаете эти базы данных?
Вы создаете их каждый раз примерно с одним и тем же конструктором? Какой процесс заставляет этих ребят слоняться без дела и может ли этот конструктор разрушиться?

Конечно, существует процесс метаданных для циклического просмотра таблиц, просто может существовать что-то более нестандартное.

По сути, я хочу убедиться, что база данных пуста, прежде чем я начну запускать процесс установки (чтобы защитить пользователей от случайного нацеливания на базу данных, которая уже содержит другие данные по ошибке). Возможно, возможно более простое решение, но я могу создать его сам, если нет хорошего универсального решения.

Matt Sheppard 23.09.2008 08:16

Существуют некоторые стандарты запросов схемы SQL-92 между базами данных - возможности для этого, конечно, варьируются в зависимости от поставщика.

SELECT COUNT(*) FROM [INFORMATION_SCHEMA].[TABLES] WHERE [TABLE_TYPE] = <tabletype>

Их поддержка зависит от поставщика, как и содержимое столбцов в представлении «Таблицы». Реализация документации по информационной схеме на языке SQL находится здесь:

http://msdn.microsoft.com/en-us/library/aa933204(SQL.80).aspx

В частности, в SQL Server метаданные sysobjects появились раньше инициативы стандартов SQL92.

SELECT COUNT(*) FROM [sysobjects] WHERE [type] = 'U'

Запрос выше возвращает количество пользовательских таблиц в базе данных. Подробнее о таблице sysobjects здесь:

http://msdn.microsoft.com/en-us/library/aa260447(SQL.80).aspx

Я не знаю, является ли это полным решением ... но вы можете определить, является ли таблица системной, прочитав столбец table_type в ResultSet, возвращаемом getTables:

int nonSystemTableCount = 0;
tables = metadata.getTables(null, null, null, null);
while( tables.next () ) {
    if ( !"SYSTEM TABLE".equals( tables.getString( "table_type" ) ) ) {
        nonSystemTableCount++;
    }
}
boolean isEmpty = nonSystemTableCount == 0;
return isEmpty;

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

По крайней мере, в Oracle вы можете выбрать USER_TABLES, чтобы исключить любые системные таблицы.

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

Например, для Oracle я проверял таблицы, последовательности и индексы:

select count(*) from user_tables
select count(*) from user_sequences
select count(*) from user_indexes

Для SqlServer я использовал для проверки таблиц, представлений и хранимых процедур:

SELECT * FROM sys.all_objects where type_desc in ('USER_TABLE', 'SQL_STORED_PROCEDURE', 'VIEW')

Лучшее универсальное (и интуитивно понятное) решение, которое я получил, - использовать задачу ANT SQL - все, что мне нужно было сделать, это передать разные параметры для каждого типа базы данных.

т.е. файл сборки ANT выглядит так:

<project name = "run_sql_query" basedir = "." default = "main">
    <!-- run_sql_query: --> 
    <target name = "run_sql_query">
        <echo message = "=== running sql query from file ${database.src.file}; check the result in ${database.out.file} == = "/>
        <sql classpath = "${jdbc.jar.file}" 
            driver = "${database.driver.class}" 
            url = "${database.url}" 
            userid = "${database.user}" 
            password = "${database.password}" 
            src = "${database.src.file}"
            output = "${database.out.file}"
            print = "yes"/>
    </target>

    <!-- Main: --> 
    <target name = "main" depends = "run_sql_query"/>   
</project> 

Для получения более подробной информации, пожалуйста, обратитесь к ANT:

https://ant.apache.org/manual/Tasks/sql.html

Другие вопросы по теме