|
|
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Народ, сидевший за IB, помогите справиться. Глюка такая: есть хранимая процедура которая возвращает несколько строк. В дебаггере (IBExpert 2.5.0.53) всё работает путём, а если скриптом Код: plaintext или из Query дельфей то она ничего не возвращает. Встречаю такую траблу неоднократно. Стоит Delphi 6, Firebird 1, 1.5, Interbase 6.5, win2k, 98. Пробовали во всех возможных сочетаниях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 11:42 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
давай свой ХП и свой параметр... заодно дельфевый код давай, как данные их хп читаешь.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 11:49 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
И какое сообщение вылетает ? А то уж совсем не понятно что происходит ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 11:52 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Чтобы вызвать из Дельфей, по моему нужно двоеточие, для начала! select * from Proc_Name( : Param) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 11:58 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Тока не пугайтесь !) Это всё надо для организации упорядоченного дерева в одной таблице Tree , где ID - понятно PARENT_ID - тоже понятно (у корневых элементов null) NODE_NAME - просто строка NODE_TYPE - тип узла (D - директорий, F - папка) NODE_ORDER - порядок элемента Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. Дельфёвый код простой: Код: plaintext 1. 2. 3. В Query1.SQL Код: plaintext 1. Проблема снимается если вызывать GET_TREE не с NULL. Но интересно получить именно с корневыми разделами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 12:00 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Ну так если ты прередаёшь NULL, то вытаскивай не (node_parent_id = :PARENT_ID), а (node_parent_id is null ). И вообще проверь, есть там такие node_parent_id, которые null . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 12:06 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
во-во 0 и null разные весчи... все операции с null дают null так что вот, принимай к сведению ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 12:09 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
ПИП!!!! Мать его IB!!!!! Убивай топик! Забыл, млин, что ИБ не умеет так сравнивать: A=null; B=null; if (a=b) then зен зен зен мать его никогда он не будет !) Всем сенкс ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 12:13 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Вобщем конечно не фонтан, но жить можно Избавился разнесением на две процы (если подскажите как короче буду премного благодарен) блин код пришлось дублировать, не люблю я это :( Проца 1: GetTree - возвращает всё дерево целиком Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. Проца 2: GetSubTree(parent_id) - возвращает поддерево с вершиной в ID=parent_ID Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 12:24 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
избавься от порочной практики использования NULL замени на 0 везде, и поле объяви not null (но не наоборот, а то огребешься) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 13:19 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Не только короче, но и по скорости быстрее будет так: 1. Все NULL замени на 0 2. Верхнее звено замкни само на себя т.е. ID = 0 и ID_PARENT = 0 3. Построй внешний ключ FK ID_PARENT на ID этой же таблицы. Таким образом никто не сможет удалить родителя пока есть потомки. IB не даст. 4. Добавь дополнительный столбец количество потомков KID_COUNT integer. Не надо будет каждый раз сажать скорость процедуры select count(*)! 5. Напиши три триггера 5.1 AFTER INSERT update tree set kid_count = kid_count + 1 where id = new.id_parent 5.2 AFTER APDATE if(old.id_parent <> new.id_parent) then begin update tree set kid_count = kid_count + 1 where id = new.id_parent update tree set kid_count = kid_count - 1 where id = old.id_parent end 5.3 AFTER DELETE update tree set kid_count = kid_count - 1 where id = old.id_parent 5.4 Триггеры проверь внимательно, я их воспроизвёл по памяти не глядя в свою базу! 6. Процедуру переделай. Теперь сам сообразишь как. NULL больше нет. 7. Наслаждайся скоростью. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 13:29 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Спасиба огромное, друзья, но из всего приму тока создать корень с ID=PARENT_ID=0, ибо Fk уже висит, а вводить поле количество детей - грозит громадными тормозами триггеров при перемещении ветвей друг в друга (а у меня их с полторы тысячи) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 13:54 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Смотрю я на текст ХП и диву даюсь ... А слабо GET_TREE в 6 строках ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 14:08 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Да есть тут с десяток идей.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 14:24 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
В скорости ты уж точно не выиграешь... вроде бы :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 14:32 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Gallagher > грозит громадными тормозами триггеров при перемещении ветвей друг в друга (а у меня их с полторы тысячи) При перемещении одной ветви в другую триггер отработает всего две операции чтения, да и то по первичному ключу!!! Dnico > А слабо GET_TREE в 6 строках ? Оно конечно можно и в одну, но каждый привык к своему стилю оформления текста процедур, ну чтобы читаемо было. А вот по объёму текста в целом, то раза в три меньше это легко! Можем обменяться алгоритмами - очень даже интересно. Но я не раньше понедельника. У меня эта процедура на домашнем компе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 14:34 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Сорри, насчёт триггера протупил. Ты прав ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 14:38 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Есть вот такой простой вариант .... может подойдет? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 14:50 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
P.S! Соответственно 0 в параметрах - все дерево, если ХХХ, то поддерево. ISFOLDER[ISF] = 1 /* Папка */ ISFOLDER[ISF] = 2 /* файл */ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 14:53 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Похоже, но у меня не так. 1. Поскольку верхнее звено ID = 0 и ID_PARENT = 0, то твой вариант будет херачить без остановки в силу рекурсии, когда входной параметр будет 0. 2. У меня вместо NODE_ISFOLDER используется KID_COUNT. KID_COUNT = 0 файл, KID_COUNT > 0 папка. Но это не принципиально 3. Мне непонятна конструкция. SUSPEND; IF (:NODE_ISFOLDER = 1) THEN FOR рекурсия get_tree SUSPEND; ELSE SUSPEND; Т.е. если файл, то два раза suspend. Или я чего-то подзабыл? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 15:08 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
второй суспенд лишний стопудов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 15:17 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
а в верхнем звене дерева должно быть: Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 15:22 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
АГА. Согласен, пропустил ... у меня там была своя обработка. По поводу верхнего звена - тоже ! Данный вариант работает с несколькими верхними звеньями, т.е. ID PARENTID 1 0 2 0 3 0 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 15:27 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
ZAI > ParentID=null > ID=0 Этот вариант уже обсудили, он геморройный. см. выше! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 15:33 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Поскольку верхнее звено ID = 0 и ID_PARENT = 0, то твой вариант будет херачить без остановки в силу рекурсии, когда входной параметр будет 0. Не должно вообще-то ... Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 15:35 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Zmeishe , Извиняюсь ... видимо заработался ... ID = 0 - будет цикл по верхнему звену. Но смысла делать ID = 0 как мне кажется нет. PARENTID = 0 это и есть корень и какой у него ID вообщем-то по барабану. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 15:41 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
херачить будет - будет. 4Змеище А чтобы не херачил, надо именно так Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 15:43 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Dnico > Не должно вообще-то ... Давай рассуждать логически по шагам. Параметр = 0 первый for select вытащит все PID равные 0, в том числе и тот который ID = 0. присвоит :node_id в 0. поскольку САМОЕ верхнее звено это папка, то далее рекурсия с :node_id = 0. И понеслась 'душа в рай'. Но это частный случай. Если у тебя нет такого звена ID=ID_PARENT=0, то циклить до бесконечности естественно не будет. Я это звено делаю для того, чтобы 1. Избавиться от NULL 2. Создать внешний ключ для контроля целостности данных самим IB. 3. Это звено служебное. Его даже можно не показывать юзеру в программе. Все остальные ветви юзеру только кажуться САМЫМИ верхними. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 15:47 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Zmeishe, ты не прав! Чел согласился, что корнем должен быть ID=0 PID= null Тогда при вызове процы с параметром 0 вытаскиваются все записи, лежащие в корне (сам корень не вытащится т.к. у него ещё раз повторяю, PID=null <> 0) потом рекурсия. Всё путём, Dnico. Змеище тоже молодец за идею с рутом. Gallagher ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 16:01 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Я решил эту задачу в общем виде. И мне необходимо вытаскивать и вершину и всё остальное. Поскольку ID_PARENT участвует в WHERE, то для быстродействия нужен индекс. Если там будет NULL, то для индекса это ДЫРРРКА, что не есть хорошо. К тому же ссылочную целостность в дереве контролировать надо. Мне надо, а вы как хотите. Чтобы это не делать руками, я избавился от NULL и построил внешний ключ. В нём и индекс и ссылочная целостность. Один единственный нолик избавил меня от кучи лишних телодвижений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 16:12 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Так! Предлагаю самое простое решение: Вершина ID PARENTID 1 0 Ветви: ID PARENTID 2 1 3 1 4 1 5 2 6 2 и т.д. GET_TREE будет прекрасно работать с любым номерм PARENTID. + Zmeishe Я это звено делаю для того, чтобы 1. Избавиться от NULL 2. Создать внешний ключ для контроля целостности данных самим IB. 3. Это звено служебное. Его даже можно не показывать юзеру в программе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 16:25 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Поправим Gallaher'a Ну ладно. Если хочешь, чтобы был FK , тогда первая запись в таблице ID=0 PID=0 name='root' следующая запись ID=1 PID=0 name='root' ID=2 PID=1 name='dir1' ID=3 PID=1 name='dir2' ............................ Выполняй процедуру get_tree c параметром 1 Код: plaintext Вытащатся все с PID>=1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 16:26 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Всё гораздо проще. Я эту процедуру вызываю не с одним параметром, а с двумя. Первый это ID или ID_PARENT кому, что нравиться, а вот воторой это флажок. При самом первом вызове процедуры флажок = 0, при рекусии 1 Если процедуру Dnico дополнить if(:flag = 0) then тогда получится моя процедура. Но не ломайте голову в понедельник принесу полный текст. Он больше текста Dnico буквально на пару, тройку коротких строчек. Не помню я сейчас. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 16:36 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Кстати, есть еще одна задачка не тему Tree . Требуется процедура, которая выдает сумму по некоему полю на всех уровнях дерева. Есть ли какие соображения? Я вот задумался, как сделать эффективнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 16:54 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Есть! И работает не один год. Причём считанные секунды по всему дереву сверху до низу. Но дарить или продавать - я ещё не решил! Я мерзкий и противный. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.08.2003, 18:00 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Таблица ID ID_PARENT 0 0 // То без чего FK весьма проблематично построить, чтобы работал быстро. С Null тормоза жуткие! 1 0 2 0 3 1 4 1 и т.д. Итак единственное принципиальное отличие от процедуры Dnico это WHERE (D.ID <> D.ID_PARENT) AND Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. Смысл FLAG следующий: В моей задаче иногда необходимо вытаскивать одим набором данных не только потомков, но и самого родителя. Если get_tree( 1, 0 ) то результат 1 0 // Родитель 3 1 // Потомок 1 4 1 // Потомок 1 Если get_tree( 1, 1 ) то результат 3 1 // Потомок 1 4 1 // Потомок 1 Если get_tree( 0, 0 ) то результат 0 0 // Родитель 1 0 // Потомок 0 2 0 // Потомок 0 3 1 // Потомок 1 4 1 // Потомок 1 Если get_tree( 0, 1 ) то результат 1 0 // Потомок 0 2 0 // Потомок 0 3 1 // Потомок 1 4 1 // Потомок 1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.08.2003, 08:51 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Zmeishe , Да, по поводу вытаскивания и родителя и потомков, это тоже хорошо, иногда требуется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.08.2003, 08:57 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
В своё оправдание хотел только напомнить, что мне нужно было вытаскивать упорядоченное по полю order дерево, причём папки по своему order 'у а файлы по своему. Этим и обуславливалась громоздкость. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.08.2003, 11:10 |
|
||
|
Interbase VS Firebird Heeeeeelp!
|
|||
|---|---|---|---|
|
#18+
Сорри конечно что опаздал... но могу сказать, что для корневого узла parent=null так же прекрасно работает.... равно как и работает условие where D.SubId = :RootId где RootId=null только что специально смотрел процу... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.08.2003, 11:46 |
|
||
|
|

start [/forum/topic.php?all=1&fid=40&tid=1580132]: |
0ms |
get settings: |
4ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
295ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
41ms |
get tp. blocked users: |
1ms |
| others: | 194ms |
| total: | 564ms |

| 0 / 0 |
