| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Oracle > Определить наличие данных в таблицах |
| Автор: Castro 22.5.2009, 17:54 |
| Привет всем. Появилась надобность ежедневно проверять наличие данный в таблицах базы. Но не во всех, а в определённых и этот список будет хранится в отдельной таблице. Получить список таблиц которые будеи проверять легко, но я не могу понять как написать процедуру которая бы подставляла этот список в запрос проверки данных. Только начал учить PL/SQL. Это цикл какой-то дожен быть? |
| Автор: ToshaCh 22.5.2009, 18:55 |
| Если просто нужно узнать количество строк то можно воспользоваться вьюхой all_tables (поле num_rows). Но! для этого статистика по таблице должна быть актуальной. Если же нужно узнавать наличие каких-то определённых данных, то можно воспользоваться динамическим sql: http://mab.h1.ru/OTHER/dplsql.html |
| Автор: Castro 25.5.2009, 11:10 |
| Чёрт, не работает ваша ссылка но похоже, что динамический sql - это оно. Но всё равно хотелось бы конкретных советов от человека, который занимался динамическим sql-ом. Я нашёл всего пару примеров но они какие-то неявные, а очень хочется и нужно разобраться во всём этом. Хотелось бы начать с простого. Например, есть 2 таблицы a и b, к обоих есть поле time_info хранящее дату. Запросом узнаю, есть ли какоя-то запись в таблице за сегодня. Если нет - пишу в таблицу result , например, дату и название таблицы с отсутствующей датой. Как сделать такую схему с помощью динамического запроса? |
| Автор: ToshaCh 25.5.2009, 13:14 | ||||
| Странно я щас по сслыке перешёл, походу она перманентно оживает. Твой пример можно разобрать где-то вот так. (не судите строго написал за 5 минут, мимоходом левой задней ногой)
В результате:
Добавлено через 2 минуты и 44 секунды З.Ы. Ну уж со вставкой в таблицу result думаю и сам разберёшься. |
| Автор: Castro 25.5.2009, 13:59 |
| Так-так. А вот это мне уже нравится |
| Автор: Castro 25.5.2009, 15:11 | ||
| Так. Теперь чтобы дать гибкости, нужно передавать как параметр проверять наличии значений ещё по одному полю в некоторых таблицах (По идее будет так - в таблице С лежат список таблиц(как сделали Вы), а таблице D - список полей каждой из этих таблиц, таблицы связаны по id (c.id = d.id)). Как научить процедуру принимать внешние параметры, или же можно сделать как-то изнутри всё это, как это сделали Вы? Попробовал вот такОбернул всё это дело в процедуру
|
| Автор: ToshaCh 25.5.2009, 15:24 |
declare здесь не надо Пробелов не хватает - синтаксическая ошибка будет. А вот в чём вопрос я не понял. Сейчас у тебя получилось, что для всех таблиц будет один и тот же вариант дополнительного поля, зависящий от того как ты вызовешь проседуру. |
| Автор: Castro 25.5.2009, 15:31 |
| Идея в том что есть, как Вы создали уже, таблица С, где будет хранится список исследуемых таблиц, и будет ещё связанная с ней таблица D, в которой будут хранится имена полей какждой из исследуемых таблиц. Количество полей во всех таблицах разное, для упрощения скажем что их будет 10 (точно сам пока не знаю). Эти таблицы связаны по id. Мне нужно чтобы процедура брала с таблицы С имя исследуемой таблицы, и в WHERE проверяла связаныне на пустоту поля из таблицы D. |
| Автор: ToshaCh 25.5.2009, 15:41 | ||
Ну тогда как-нить так:
|
| Автор: Castro 25.5.2009, 16:07 | ||||
| Похоже на правду. Правда, не понял строчку 4
Что должно по идее вернуть
? |
| Автор: ToshaCh 25.5.2009, 16:11 | ||
Ну дык!
|
| Автор: Castro 25.5.2009, 16:47 | ||||
Нет, меня смутило то, что из
я не понял откуда возьмётся переменная column_name ? А строка 4, когда подставиться имя колонки, например
|
| Автор: ToshaCh 25.5.2009, 16:52 |
| Это не переменная это поле таблицы d |
| Автор: Castro 25.5.2009, 17:06 | ||
Гляньте, пожалуйста, ещё раз на конечный вариант процедуры и проверте всё ли на месте и ничего я не напутал ли. Идею я понял, но мог что-то напутать с реализацией
|
| Автор: ToshaCh 25.5.2009, 17:13 |
С чего это? Представь что там получается в переменной stmt сейчас? |
| Автор: Castro 25.5.2009, 17:23 | ||
Ммм.... Это да. Но условие where ведь дальше выстраиваться будет, значит так?
|
| Автор: ToshaCh 25.5.2009, 17:35 |
| Мдя а вот тут проблема. Я предполагал, что будет одно статичекое условие и n динамических: щас вообще ерунда получается: where and ..... Это надо исправлять. |
| Автор: ToshaCh 25.5.2009, 17:51 | ||
Наверное так.
|
| Автор: Castro 25.5.2009, 17:59 | ||
А, вот теперь я понял почему такая конструкция была
+1 вам в карму! Спасибо огромное за помощь, буду докручивать завтра, уже сегодня голова не варит. |
| Автор: Zloxa 26.5.2009, 09:58 | ||
| ToshaCh, 1) dbms_sql тут лишний, без него, ИМХО проще. 2) для того чтобы проверить наличие, считать count() это оверхед, достаточно лишь одного фетча
|
| Автор: ToshaCh 26.5.2009, 13:12 |
| О! Никогда не видел, чтобы курсор та компоновали (в смысле как строку). Спасибо. |
| Автор: Zloxa 27.5.2009, 11:07 |
Весьма странно, обычно для народа dbms_sql - открытие Раз так - http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_dynamic_sql.htm#ADFNS008 |
| Автор: Castro 27.5.2009, 11:29 | ||
| А вот теперь нужен совет, потому что правила игры как оказалось уже изменились. Оказалось, что таблицы разные и в основном они связаны друг с другом по айдишникам, что вполне понятно, ну конечно что же поле даты присутсвует только в одной из таблиц. По сути элементарная связаная выборка получается. Запросы будут меняться вероятно? В чём вопрос: как это всё хранить теперь? Создать одну таблицу с полями table_name и query_str, где хранить сами условия, и подставлять в цикле в шаблон
Или, возможно, есть смысл хранить толко названия полей, по которым связаны таблицы? Или есть какое мудрое решение и в тоже время гибкое? |
| Автор: Zloxa 27.5.2009, 12:47 |
Думаю так правильнее Любая гибкость достигается, как правило, за счет потери прочности. Я за железобетонные решения. По сему, я не рекомендовал бы хранить запросы в данных. В любом случае, при добавлении таблицы нужно писать запрос. Запрос должен писать программист, не пользователь. Меньше шансов ошибиться у программиста будет, если он будет редактировать текст ХП, которая, будет еще на этапе компиляции проверяться. От того бросайте вы это баловство с универсальными гибкими решениями, пракитика показывает, что ни к чему хорошему они не приводят. Автомобиль амфибия плохо ездиит и плохо плавает, от того их производят так мало и лишь по частным заказам. |
| Автор: Castro 18.6.2009, 18:48 | ||||||
Появилось вот время занятся сново с эти заданием и уже почти но всё ещё не всё
Вроде всё ок. Но помоему не приходит ничсего в курсор, потому что постоянно идёт вставка "has no data" и не может получить foo.time_info (мож там ксатати чёто с кавычками напутал). DBG - функция дебага, просто пишет в табличку переменную нужную. DBG('j: '||j.tname) вернуло правильно, DBG('cursor query: SELEC...) - тоже правильный запрос, который если скопировать из таблицы и выполнить, то выполнится правильно. Но
возвращает пустоту в таблице и соотвественно всегда срабатывает
Oracle не умеет работать со вложенными циклами? Или в чём может быить причина? Как ещё можно отдебажить курсор. Работаю в SQL Navigator и все приблуды c SQL * plus к сожалению не могу испытать (или не знаю просто как это сделать :(( ) |
| Автор: Zloxa 18.6.2009, 18:58 | ||||
Это не код это бред.
Должно поднимать эксепшн.
если попытаться выполнить это, тоже должен быть эксепшн. |
| Автор: Castro 19.6.2009, 10:04 | ||||
это бред - я это понял сразу, но эксепшна не вываливается. Как парвильно встать в таблицу содержмое курсора?
а что здесь не так? |
| Автор: Zloxa 19.6.2009, 10:41 | ||
считай кавычки, ну или хотябы смотри на то как подсвечен синтаксис. |
| Автор: Castro 19.6.2009, 11:08 | ||||
| Спасибо. Использовал Вашу процедуру, но она не успела отработать Так, упростил всё что только можно.
В цикле делается один проход (в дебаге видны данные) и всё валится на строке
с ошибкой Error executing statement: ORA-06502: PL/SQL: numeric or value error Погуглил и нашёл что http://www.mydatabasesupport.com/ora-06502-pl-sql-numeric-or-value-error.html Это попытка записать большой объём данных в переменную foo, больший чем оно может вместить? В смысле в DUAL не может влезть? Илия ошибаюсь? Как это побороть? |
| Автор: Zloxa 19.6.2009, 11:20 |
структура переменной foo не соответствует структуре, возвращенной курсором. Вы в переменную типа чар(1) пытаеесь впихнуть дату |
| Автор: Castro 19.6.2009, 11:31 |
| Спасибо большое. Глаз замылился уже, пока пишу пост, в голове решаю задачу, потом отправляю пост и за 10 секунд решаю проблемму Хотел ещё по поводу кавычек спросить - иногда применяются 2 кавычки, а иногда 3. 2 кавычки - это чтобы экарнировать одну кавычку при вложенности, а когда применяют 3? |
| Автор: Zloxa 19.6.2009, 11:57 |
3=2+1 т.е. кавычка внутри строки+закрывающая кавычка Добавлено через 2 минуты и 4 секунды Это говорит лишь о том, что Вы сначала спрашиваете а потом думаете, что не делает Вам чести. |
| Автор: Castro 19.6.2009, 12:47 |
| Согласен, но: 1) Это для меня новое поле деятельности и не у кого спросить так чтобы быстро получить вразумительный ответ. 2) Правилоно сформулированый вопрос - это уже половина ответа. Формулирую вопрос я обдумаваю проблемму. Значит нужно научится заставлять себя писать суть вопроса но не отправлять его на форум. В любом случае спасибо. Процедура заработала и гребёт данные. +1 вам в карму! |