powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
14 сообщений из 14, страница 1 из 1
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39295284
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hi All,

Есть некий справочник.
На него через Foregin Key ссылается куча других таблиц.
Берем из этого справочника строку с кодом 1 (на это поле "код" через FK и ссылаются другие таблицы).

Вопрос: Как получить перечень всех таблиц, в которых есть ссылка на эту
конкретную строку справочника ?
Может у All уже есть какой то готовый код с обходом системных таблиц
и проверкой ссылок для решения этого вопроса ?
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39295568
antand
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stalker4,
Готового кода не встречал.
Вроде как перечень таблиц и полей, на которые есть FK из этой таблицы можно получить одним запросом, посмотрите как централ это делает.
А вот есть ли там записи соответствующие конкретной записи в справочнике это уже надо выдавать запрос к каждой таблице отдельно. В системных таблицах это(наличие ссылки на конкретную запись в другой таблице) по идее не храниться. Системные триггеры, которые создаются с FK, например на удаление, выдают запрос к таблице для поиска ссылок, а не берут готовые данные из какой-то системной таблицы ссылок
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39295656
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
antandГотового кода не встречал.
Вроде как перечень таблиц и полей, на которые есть FK из этой таблицы можно получить одним запросом, посмотрите как централ это делает.Да что то централ не очень делиться своими запросами.
Включил в "Server Message and Execute SQL" опцию "Log queries".
Выбрал таблицу, переключился на закладку "Referencing Constraints", а в логе запрос не появился.

antandА вот есть ли там записи соответствующие конкретной записи в справочнике это уже надо выдавать запрос к каждой таблице отдельно.Это понятно. Просто задача достаточно типовая, и я надеялся что у All уже есть готовый код (скажем в виде SP), который по заданной TableName, ForeginKeyName и значению вернет перечень таблиц, где этот код задействован.
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39295750
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Модератор: Это заведомо неверный ответ, отвечающий перепутал ASA и ASE
Stalker4,

sp_depends ,
фильтрация по виду зависимостей ('logical RI'), и затем проверка простым запросом всех таблиц, которые ссылаются
на данную.

Вместо sp_depends можно использовать напрямую таблицу sysreferences .

Вряд ли это можно сделать автоматически (да и вряд ли нужно), поскольку это потребует динамического формирования
текста запроса, достаточно сложного, и последующего его выполнения через EXEC, а вот в полуавтоматическом режиме (т.е. ручками) это сделать достаточно легко.
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39295751
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
antand... Просто задача достаточно типовая, и я надеялся что у All уже есть готовый код...

Задача НЕ типовая, никто динамически по всем форенкеям таблицы не будет лазить, незачем.
Структуру БД обычно и так знают, и знают, в каких таблицах могут быть ссылки на данную, их и проверяют, статическими запросами.
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39295782
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivantand... Просто задача достаточно типовая, и я надеялся что у All уже есть готовый код...

Задача НЕ типовая, никто динамически по всем форенкеям таблицы не будет лазить, незачем.
Структуру БД обычно и так знают, и знают, в каких таблицах могут быть ссылки на данную, их и проверяют, статическими запросами.Ну в принципе я знаю одну задачу где такое требуется...
Ко мне данные в базу приходят из внешнего источника, и у меня просто нету "правильного" клиента к базе данных. Но при этом хочется посмотреть "что записано в базе по такому-то вопросу?". Тогда, зная что таблица с "вопросами" является более менее центральной в снежинке, можно довольно легко сделать UI которая на основе записи в центральной таблице будет автоматически фильтровать ведомые таблицы.
Очень удобная штука получается для внутреннего исследования данных. И при этом нет нужды делать реальный UI с расшифровкой полей БД в именованные поля на диалоговых окошках. Нет нужды повторять полноценного клиента к БД и не нужно вручную писать по тысячному разу однотипные запросы в dbsiql.

Ну а чтобы всю снежинку не прописывать вручную я и использую вариант запроса который хочет Stalker4. Но увы, как это сделать в SA не подскажу, нету у меня ее сейчас. У нас ASE, и при этом в той базе нет фактических внешних ключей, только логические и хватает просто поиска по имени.
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39295793
Марсель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
попробуй вот так, в 11 работало
Код: sql
1.
2.
3.
4.
5.
6.
select ft.table_name, B.column_name
from SYS.SYSFKEY fk, SYS.SYSIDXCOL ic, SYS.SYSIDX i, SYS.SYSTAB pt, SYS.SYSTAB ft key join SYS.SYSTABCOL B
where fk.foreign_table_id=ic.table_id and fk.foreign_index_id =ic.index_id and B.column_id=ic.column_id and
  ic.table_id = i.table_id and ic.index_id = i.index_id and i.index_category = 2 and
  fk.foreign_table_id=ft.table_id and fk.primary_table_id=pt.table_id and
  pt.table_name = 'tablename'



далее делаешь в цикле динамический запрос через EXECUTE IMMEDIATE WITH RESULT SET ON
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39296008
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivsp_depends и sysreferencesЭта SP и таблица в SA 12 нет, они удалены как устаревшие (да и вообще они от ASE).

Марсельпопробуй вот так, в 11 работалоА вот этот запрос в SA12 работает прекрасно, так что за него большое спасибо.
Главное, что бы он и в более новых версиях (16, 17) работал.
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39297166
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Марсель
Еще раз большое спасибо за помощь.

Выкладываю SP которая по имени таблицы и коду строки этой таблицы возвращает названия зависимых таблиц и колонок, причем как сами названия так и примечания к ним.

Код: sql
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.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
CREATE PROCEDURE "DBA"."GetDependedTable"(in cTableName char(30), in nID integer)
BEGIN

 declare curDependedTable dynamic scroll cursor for
 select 
  ft.table_name, 
  b.column_name,
  rt.remarks as table_remarks,
  rc.remarks as column_remarks
 from SYS.SYSFKEY fk, 
 SYS.SYSIDXCOL ic, 
 SYS.SYSIDX i, 
 SYS.SYSTAB pt, 
 SYS.SYSTAB ft 
 key join SYS.SYSTABCOL b
 left outer join SYS.SYSREMARK rc on rc.object_id = b.object_id 
 left outer join SYS.SYSREMARK rt on rt.object_id = ft.object_id 
 where (fk.foreign_table_id = ic.table_id) and 
       (fk.foreign_index_id = ic.index_id) and 
       (B.column_id = ic.column_id) and
       (ic.table_id = i.table_id) and 
       (ic.index_id = i.index_id) and 
       (i.index_category = 2) and
       (fk.foreign_table_id = ft.table_id) and 
       (fk.primary_table_id = pt.table_id) and
       (pt.table_name = cTableName);

 declare local temporary table tmpTable(
   TABLENAME char(30), 
   COLUMNNAME char(50),
   TABLEREMARK long varchar,
   COLUMNREMARK long varchar
   ) on commit delete rows;

 declare cDependTableName char(30);
 declare cDependColumnName char(50); 
 declare cDependTableRemark long varchar;
 declare cDependColumnRemark long varchar;

 declare cSQL long varchar;

 open curDependedTable;
 lab_DependedTable: loop

   fetch next curDependedTable into cDependTableName, cDependColumnName, cDependTableRemark, cDependColumnRemark;
   if @@sqlstatus <> 0 then
     leave lab_DependedTable
   end if;

   set cSQL = 'if exists(select * from dba.'||cDependTableName||' where '||cDependColumnName||'='||cast(nID as char)||') then '||
                'insert into tmpTable(TABLENAME,COLUMNNAME,TABLEREMARK,COLUMNREMARK) '||
                'values('||CHAR(39)||cDependTableName||CHAR(39)||','||CHAR(39)||cDependColumnName||CHAR(39)||','||
                           CHAR(39)||cDependTableRemark||CHAR(39)||','||CHAR(39)||dba.ExtractWord(1, cDependColumnRemark, '(')||CHAR(39)||') '||
              'endif';

   execute immediate cSQL;

 end loop lab_DependedTable;
 close curDependedTable;

 select * from tmpTable;

END



P.S. ИМНО можно ее закинуть в местный FAQ.
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39297260
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalker4P.S. ИМНО можно ее закинуть в местный FAQ.Не, в FAQ это не нужно.
Во первых, это все-же чрезвычайно уникальная задача.
Во вторых, мне жутко не нравится код процедуры.
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39297524
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White OwlStalker4P.S. ИМНО можно ее закинуть в местный FAQ.Не, в FAQ это не нужно.
Во первых, это все-же чрезвычайно уникальная задача.
Во вторых, мне жутко не нравится код процедуры.Если Вам не трудно, то переделайте код процедуры и покажите его здесь.

Весьма интересно, что в нем не так ...
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39298190
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalker4Если Вам не трудно, то переделайте код процедуры и покажите его здесь.

Весьма интересно, что в нем не так ...Я не могу переделать, у меня нет SA. Если я ее перепишу, то только чисто эмпирически и тебе потом придется опечатки править.

Но мне жутко не понравилось в приведенной процедуре использование смешанного синтаксиса в FROM. Либо запятые либо join, но ни в коем случае не смешивать их. Хотя это камень в огород Марселя в первую очередь, но...
Во вторых, мне не нравится использование @@sqlstatus переменной. От нее ТранзактСиквелом воняет :) В SA, я предпочитаю(-ал) использовать FOR CURSOR для итерации по курсору. Удобнее намного.
В третьих, я не очень люблю declare local temporary table команду. На мой взгляд, create table #tmp намного лучше. По сути оно тоже-самое, но знак # в имени таблицы не даст тебе в будущем забыть что это именно локальная временная таблица.
Ну и в четвертых, ты там в процедуре используешь свою собственную функцию ExtractWord(), но не даешь ее кода. А в результате любой кто попытается твою процедуру использовать напрямую - обломается.
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39298397
Stalker4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl
По поводу ExtractWord полностью согласен - забыл ее убрать перед постом сюда SP.

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

Насчет create table #tmp - а это (#tmp) разве не ТранзактСиквел ?
И если дело только в решетке, так можно просто добавить ее в начало имени таблицы.

Вот обновленный вариант этой SP:
Код: sql
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.
49.
50.
51.
52.
53.
54.
55.
ALTER PROCEDURE "DBA"."GetDependedTable"(in cTableName char(30), in nID integer)
BEGIN

 declare curDependedTable dynamic scroll cursor for
 select 
  ft.table_name, 
  b.column_name,
  rt.remarks as table_remarks,
  rc.remarks as column_remarks
 from SYS.SYSFKEY as fk 
 join SYS.SYSIDXCOL as ic on (ic.table_id = fk.foreign_table_id) and (ic.index_id = fk.foreign_index_id) 
 join SYS.SYSIDX as i on (i.table_id = ic.table_id) and (i.index_id = ic.index_id) and (i.index_category = 2)
 join SYS.SYSTAB as pt on (pt.table_id = fk.primary_table_id) 
 join SYS.SYSTAB as ft on (ft.table_id = fk.foreign_table_id)
 key join SYS.SYSTABCOL as b on (b.column_id = ic.column_id)
 left outer join SYS.SYSREMARK rc on (rc.object_id = b.object_id) 
 left outer join SYS.SYSREMARK rt on (rt.object_id = ft.object_id) 
 where pt.table_name = cTableName;

 declare local temporary table #tmpTable(
   TABLENAME char(30), 
   COLUMNNAME char(50),
   TABLEREMARK long varchar,
   COLUMNREMARK long varchar
   ) on commit delete rows;

 declare cDependTableName char(30);
 declare cDependColumnName char(50); 
 declare cDependTableRemark long varchar;
 declare cDependColumnRemark long varchar;

 declare cSQL long varchar;

 open curDependedTable;
 lab_DependedTable: loop

   fetch next curDependedTable into cDependTableName, cDependColumnName, cDependTableRemark, cDependColumnRemark;
   if @@sqlstatus <> 0 then
     leave lab_DependedTable
   end if;

   set cSQL = 'if exists(select * from dba.'||cDependTableName||' where '||cDependColumnName||'='||cast(nID as char)||') then '||
                'insert into #tmpTable(TABLENAME,COLUMNNAME,TABLEREMARK,COLUMNREMARK) '||
                'values('||CHAR(39)||cDependTableName||CHAR(39)||','||CHAR(39)||cDependColumnName||CHAR(39)||','||
                           CHAR(39)||cDependTableRemark||CHAR(39)||','||CHAR(39)||cDependColumnRemark||CHAR(39)||') '||
              'endif';

   execute immediate cSQL;

 end loop lab_DependedTable;
 close curDependedTable;

 select * from #tmpTable;

END


А вот по поводу @@sqlstatus мне не совсем понятно.
Все же хотелось бы увидеть пример правильной версии этой SP ...
...
Рейтинг: 0 / 0
Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
    #39298837
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalker4Насчет create table #tmp - а это (#tmp) разве не ТранзактСиквел ?Да, это наследие TSQL, но если копать чуть поглубже, то там все-же есть разница. Она запряталась в дефолтном поведении временных таблиц.
В общем, читать тут: http://infocenter.sybase.com/help/topic/com.sybase.help.sqlanywhere.12.0.0/dbreference/declare-local-temporary-table-statement.html про что является дефолтом при коммите и/или конце транзакции.
Хотя в данном случае эти тонкости наверное не очень важны, но так-как ты в дальнейшем используешь execute immediate у которого тоже куча подводных камней, on commit preserve rows становится очень полезным.
Ну и в конце концов, create table #tmp писать меньше :)

Stalker4И если дело только в решетке, так можно просто добавить ее в начало имени таблицы.Нет, так делать не стоит. Сейчас уже я не могу предсказать поведение этой таблицы в конце транзакции. Не описано в документации что будет если совместить declare и #.

Stalker4А вот по поводу @@sqlstatus мне не совсем понятно.Читай тут:
http://infocenter.sybase.com/help/topic/com.sybase.help.sqlanywhere.12.0.0/dbreference/for-statement.html


Stalker4Все же хотелось бы увидеть пример правильной версии этой SP ...Ну.... Что-то в духе:
Код: sql
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.
CREATE PROCEDURE "DBA"."GetDependedTable"(in cTableName char(30), in nID integer)
BEGIN
 select 
  ft.table_name, 
  b.column_name,
  rt.remarks as table_remarks,
  rc.remarks as column_remarks,
  0 as has_data
 into #tmpTable
 from SYS.SYSFKEY as fk 
 join SYS.SYSIDXCOL as ic on (ic.table_id = fk.foreign_table_id) and (ic.index_id = fk.foreign_index_id) 
 join SYS.SYSIDX as i on (i.table_id = ic.table_id) and (i.index_id = ic.index_id) and (i.index_category = 2)
 join SYS.SYSTAB as pt on (pt.table_id = fk.primary_table_id) 
 join SYS.SYSTAB as ft on (ft.table_id = fk.foreign_table_id)
 key join SYS.SYSTABCOL as b on (b.column_id = ic.column_id)
 left outer join SYS.SYSREMARK rc on (rc.object_id = b.object_id) 
 left outer join SYS.SYSREMARK rt on (rt.object_id = ft.object_id) 
 where pt.table_name = cTableName;

declare @sql long varchar;
for loop1 as crsr1 for select table_name, column_name from #tmpTable do
  set @sql = 'update #tmpTable set has_data=1 where table_name=' ||CHAR(39)|| table_name ||CHAR(39)|| ' and ' ||
                 'exists (select * from ' || table_name || ' where ' || column_name || '=' ||cast(nID as char)||')';
   execute immediate @sql;
end for;

select * from #tmpTable where has_data=1;
end; --- procedure


Могут быть опечатки.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Sybase SA 12.0.1: Как найти все ссылки на конкретную строку справочника ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]