Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Как узнать какую таблицу я изменил?


Автор: simanyay 25.5.2005, 10:49
Привет. Как узнать какую таблицу я изменил? Мне нужно изменить таблицу, а потом из неё выдернуть данные (ну SELECT * FROM тырым-пырым).

Код

    // ...что-то таинственное...

    public ResultSet executeQuery(String query) throws SQLException {
        this.statement.execute(query);
        
        if(query.startsWith("SELECT")) return this.statement.getResultSet();
        else return executeUpdate(query);
    }

    public ResultSet executeUpdate(String query) throws SQLException {
        this.statement.executeUpdate(query);
        
        /*
         * TODO: Вот тут-то мне и надо сделать SELECT из affected таблицы.
         */
    }

    // ...что-то таинственное...


Поиск в гугле пока ничего не дал.

Автор: 3,14 25.5.2005, 13:17
А чем тупой парсинг строки query не подходит?
Ежели выполняется executeUpdate то там может быть три варианта:
  • UPDATE <имя таблицы>
  • INSERT INTO <имя таблицы>
  • DELETE FROM <имя таблицы>

Автор: chief39 25.5.2005, 17:59
Утверждать не буду...
Точного ответа не знаю.

Но давайте пораскинем мозгами по асфальту....

Общение с скл-серверами происходит примерно так:
- Мы отправляем запрос (неважно какой), можем ещё сделать prepare
(это не только к джаве относится)
для предкомпиляции на сервере(для ускорения последующих выполнений )
- Сервер его выполняет. Обновляет, вставляет, удаляет, выбирает.
- Возвращает нам результаты. Типично для скл-серверов возвращаются:
* резалтсеты (они же наборы данных)
* аутпут параметры процедур
* результат выполнения
* сообщения сервера(о выполнении или трактование ошибок)

Насколько я знаю, в сообщениях сервера обработанные таблицы не фигурируют.
Поскольку есть много утилит которые могут показать план запроса - логично предположить что план можно вытянуть. НО! опять таки.. разбирать его.....
Возвращаемся к предложению парсить query. Гораздо эффективнее.
Ещё есть журнал транзакций сервера :-). Если кто-то, как-то, когда-то.....
Тогда и мне расскажите :-)

То есть мнение: просто взять и обратиться к чему-то вроде statement.UpdatedTables - вряд ли

Остаётся старый, добрый
Цитата(3)
тупой парсинг строки query


а вообще интересно задание....
передаются неизвестные query, ты их выполняешь... а селект-то зачем потом? куда резалтсет идёт? или необходим подсчёт строк? или статистика? (мол, обновляли такие-то таблицы, теперь в них столько-то строк)
Так легче помозговать будет :-)




Автор: maximb 25.5.2005, 18:42
Цитата(simanyay @ 25.5.2005, 10:49)
тырым-пырым

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

Автор: simanyay 25.5.2005, 20:51
Собственно проблема в задании. Сейчас попробую сформулировать:
Необходимо разработать систему проверки правильности SQL запросов при экзамене. Т.е. у нас есть заготовки SQL запросов и сам вопрос. Пользователь, как ответ, шлёт свою версию запроса и система должная проверить - решит ли запрос поставленную проблему. Если кто имел дело с чемпионатом по программированию (ACM ICPC), то примерно то и надо сделать.

Просто тупое сравнение не пойдёт, поскольку несколько вариантов запросов могут одинаково решить проблему. Я думал о том, чтобы просто последовательно выполнить заготовок и тестируемый запросы и посмотреть результат. Но опять же, надо будет парсить запрос из-за INSERT, UPDATE, CREATE, DELETE, etc.

Только парсинг?

Автор: hatsumeika 25.5.2005, 22:46
Задача напоминает задачу тестирования: есть тестируемый код, нужно проверить 1) для select, что он вернул правильный ResultSet, 2) для insert, update, delete что БД пришла в должное (эталонное) состояние.

Мне кажется, решить задачу можно вот таким способом: с каждым заданием ассоциируется
1) код, приводящий БД в начальное состояние (иначе не понятно, что делать после выполнения каждого тестируемого запроса, как убедиться, что БД в правильном состоянии и т.п.)
2а) код проверяющий, что БД находится в правильном состоянии
ИЛИ
2b) код проверяющий, что ResultSet правильный

2b можно свести к 2а, если обязать результат всегда записывать в таблицу (т.е. оборачивать select insert-ом).

(1) можно писать как попало. Для (2) чтобы получить универсальное решение, я бы сделал класс эталон таблицы, который бы инициировался именем таблицы, структурой и наборами кортежей (строк). Набор таких эталонов "сам" бы проверял, что в БД все как должно или возвращал расхождение.

Автор: simanyay 25.5.2005, 22:56
hatsumeika, спасибо, я о постоянстве состояния как-то и не подумал

Автор: hatsumeika 26.5.2005, 09:00
я еще немного подумал, и теперь мне кажется, что нужно сводить не 2b к 2а а наоборот, 2а к 2b. т.к. так в обоих случаях мы будем работать с ResultSet-ом

Автор: simanyay 26.5.2005, 20:51
Короче, решил сделать так.

UPDATE, DELETE, INSERT:
1. Вызываю запрос, введенный тестируемым
2. Сохраняю состояние измененной таблицы
3. Восстанавливаю таблицу
4. Вызываю шаблонный запрос
5. Сохраняю состояние измененной таблицы
6. Восстанавливаю таблицу
7. Сравниваю два сохраненных состояния

SELECT:
Просто сравниваю два результат. От тестируемого и от шаблонного

CREATE, DROP:
А хз... DESC что-ли как-нибудь заюзать?

Автор: LSD 26.5.2005, 20:54
При желании можно обойтись чистым SQL-ем.
- изначально имеем 2 комплекта таблиц, половина содержит начальное состояние, половина итоговое
- выполняем DML, а затем выполняем что то вроде:
Код
select count(*) from tab_orig t1, tab_mod t2
where t1.id = t2.ID and t1.field1 <> t2.field1 and t1.field2 <> t2.field2 ...

- для select можно выполнять:
Код
select count(*) from tab_orig t1, (select...) t2
where t1.id = t2.ID and t1.field1 <> t2.field1 and t1.field2 <> t2.field2 ...

- для того чтобы не возвращать таблицы в начальное состояние использовать rollback

Автор: simanyay 26.5.2005, 21:19
Цитата(LSD @ 26.5.2005, 22:54)
- для того чтобы не возвращать таблицы в начальное состояние использовать rollback


MySQL используется... какой rollback smile

Автор: LSD 26.5.2005, 21:51
Цитата(simanyay @ 26.5.2005, 22:19)
MySQL используется... какой rollback

А это обязательно? Тем более, что MySQL не полность SQL92 (по части хранимок, триггеров и вложенных запросов) поддерживает. Может лучше Firebird или PostgreSQL.

Автор: simanyay 26.5.2005, 21:58
Цитата(LSD @ 26.5.2005, 23:51)

А это обязательно? Тем более, что MySQL не полность SQL92 (по части хранимок, триггеров и вложенных запросов) поддерживает. Может лучше Firebird или PostgreSQL.


Пока да. Мне надо пока это показать, чтобы раскрутить. И это нужно к концу недели smile Потом уже будут не только базы и будем думать о выборе.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)