Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Ошибка в ASE - подзапрос дублирует строки / 9 сообщений из 9, страница 1 из 1
09.09.2005, 17:07
    #33261912
Сергей Васкецов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка в ASE - подзапрос дублирует строки
Обнаружил следующую ошибку на следующих версиях ASE на Win2kAS (из результата select @@version):
1. Adaptive Server Enterprise/12.0.0.8/P/EBF 12452 ESD4/NT (IX86)/OS 4.0/2081/32bit/OPT.
2. Adaptive Server Enterprise/12.5.3/EBF 12599 ESD#3/P/NT (IX86)/OS 4.0/ase1253/1912/32-bit/OPT (и на ESD#2 тоже).

Смысл ошибки – при добавлении в запрос, возвращающий ровно одну строку, в его where clause подзапроса вида «and exists (…)» запрос начинает возвращать эту же строку дважды.

Вот этот запрос.

select t.id_tmc,
t.tmc_code,
t.tmc_descript,
t.id_tmcgrup,
t.tmc_type
from tmc t
where t.id_tmc = 516
and exists(select 1
from sxran sx, planacnt pl
where sx.id_tmcgrup = t.id_tmcgrup
and sx.id_schet = pl.id_schet
and (pl.schet in ('100000','410010')))

Здесь только таблицы (представлений нет). t.id_tmc и pl.id_schet – это первичные ключи (identity) на соответствующих таблицах, поэтому запрос обязан возвращать не более одной строки. В таблице sxran построен уникальный индекс по полям (id_sclad,id_tmcgrup), поэтому для одного t.id_tmcgrup значений в sxran может быть более одного.

Если в подзапросе в IN оставить только одно значение – ошибка исчезает (возможно, это случайность), если убрать подзапрос вообще – тоже исчезает. Если основной from clause переписать без inner join (просто перечислить таблицы, а условия их связи перенести в where clause), то ошибка остается.

БД проверена dbcc checkdb – ошибок нет. На всякий случай выполнены reorg rebuild и плановый update all statistics – улучшения не обнаружилось.

Какие есть мысли у кого на эту тему? Как может подзапрос where exists () увеличить количество строк в результате? Не понимаю.
...
Рейтинг: 0 / 0
09.09.2005, 18:49
    #33262119
newPеpper
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка в ASE - подзапрос дублирует строки
Я пока мало чего понимаю, но вот попробовал запустить такой код на Adaptive Server Enterprise/12.0.0.4/P/SWR - все нормально, дублей нет никаких. Или я чего не так понял?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create table #test
             ( ID numeric identity
              ,name varchar( 25 )
             )
 create table #test1            
             ( ID numeric identity
               ,name varchar( 25 )
              )
insert #test(Name) values('Петров')
insert #test(Name) values('Иванов')
insert #test1(Name) values('Петров')
insert #test1(Name) values('Иванов')

select t.Name
  from #test t
  where exists(select  1  
                 from #test1 t1 
                where t1.ID=t.ID and t1.ID= 1  
              )

drop table #test
          ,#test1 
...
Рейтинг: 0 / 0
09.09.2005, 21:10
    #33262250
vybegallo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка в ASE - подзапрос дублирует строки
Правила хорошего тона требуют в таких случаях предоставить скрипт для воспроизводства проблемы. У меня на Sybase IQ 12.6 повторить не получилось :
create table tmc (id_tmc int, id_tmcgrup int)
;
create table sxran (id_tmcgrup int, id_schet int)
;
create table planacnt (id_schet int, schet char(6))
;
insert into planacnt values (1, '100000')
;
insert into planacnt values (1, '400000')
;
insert into planacnt values (2, '400000')
;
insert into tmc values (1, 1)
;
insert into tmc values (2, 2)
;
insert into tmc values (516, 1)
;
insert into sxran values (1, 1)
;
insert into sxran values (2, 2)
;
select t.id_tmc
from tmc t
where t.id_tmc = 516
and exists(select 1
from sxran sx, planacnt pl
where sx.id_tmcgrup = t.id_tmcgrup
and sx.id_schet = pl.id_schet
and (pl.schet in ('100000','410010')))
;
...
Рейтинг: 0 / 0
09.09.2005, 22:22
    #33262284
guest22222
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка в ASE - подзапрос дублирует строки
Верно, требуют.
Но проблема-то как раз в том, что это ничего не даст, кроме экономии времени. Все же, прошу прощения и привожу скрипт.

Простейший скрипт создания этих таблиц, из которого удалено все, что не относится к делу типа полей, констрейнтов, индексов и триггеров, и заполнение аналогично тому, как это в рабочей БД, ошибку не воспроизводит.

Вот он.

Код: 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.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
create table test_tmc (
     id_tmc               numeric( 16 , 0 )                  identity,
     id_tmcgrup           numeric( 16 , 0 )                  not null,
     tmc_code             varchar( 30 )                    not null,
     tmc_type             int                            default  0  not null
           constraint CKC_TMC_TYPE_TMC check (tmc_type between  0  and  3 ),
     constraint PK_TMC primary key nonclustered (id_tmc)
)
lock DATAROWS
with identity_gap =  1 
go


create unique index tmc_code on test_tmc (
tmc_code ASC
)
go

create index tmc_type on test_tmc (
tmc_type ASC
)
go

create index relation_471_fk on test_tmc (
id_tmcgrup ASC
)
go


create table test_sxran (
     id_sxran             numeric( 16 , 0 )                      identity,
     id_sclad             numeric( 16 , 0 )                      not null,
     id_schet             numeric( 16 , 0 )                      not null,
     id_tmcgrup           numeric( 16 , 0 )                      not null,
     constraint PK_SXRAN primary key nonclustered (id_sxran)
)
lock DATAROWS
with identity_gap =  1 
go


create unique index sxran_uniq on test_sxran (
id_sclad ASC,
id_tmcgrup ASC
)
go


create index relation_459_fk on test_sxran (
id_sclad ASC
)
go


create index relation_460_fk on test_sxran (
id_schet ASC
)
go


create index relation_464_fk on test_sxran (
id_tmcgrup ASC
)
go


create index sxran_complex on test_sxran (
id_sclad ASC,
id_schet ASC,
id_tmcgrup ASC
)
go


create table test_planacnt (
     id_schet             numeric( 16 , 0 )                      identity,
     schet                varchar( 10 )                        not null,
     constraint PK_PLANACNT primary key nonclustered (id_schet)
)
lock DATAROWS
with identity_gap =  1 
go

create unique index schet_code on test_planacnt (
schet ASC
)
go

Вот как его можно заполнить.

Код: 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.
insert into test_tmc (tmc_code, id_tmcgrup) values ('08',  110 )
go

insert into test_planacnt (schet) values ('101003')
go

insert into test_planacnt (schet) values ('101001')
go

insert into test_planacnt (schet) values ('150000')
go


insert into test_sxran (id_tmcgrup, id_sclad, id_schet) values ( 110 ,  38 ,  1 )
go

insert into test_sxran (id_tmcgrup, id_sclad, id_schet) values ( 110 ,  13 ,  2 )
go

insert into test_sxran (id_tmcgrup, id_sclad, id_schet) values ( 110 ,  39 ,  2 )
go

insert into test_sxran (id_tmcgrup, id_sclad, id_schet) values ( 110 ,  40 ,  2 )
go

insert into test_sxran (id_tmcgrup, id_sclad, id_schet) values ( 110 ,  41 ,  2 )
go

insert into test_sxran (id_tmcgrup, id_sclad, id_schet) values ( 110 ,  42 ,  2 )
go

insert into test_sxran (id_tmcgrup, id_sclad, id_schet) values ( 110 ,  47 ,  3 )
go

А вот запрос
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
select t.*
from test_tmc t
where t.tmc_code = '08'
 and exists (select  1 
               from test_sxran v, test_planacnt p
              where v.id_tmcgrup = t.id_tmcgrup
                and v.id_schet = p.id_schet
                and p.schet in ('101003','101001'))
go

Но на тестовом примере ошибка не воспроизводится.

Однако она воспроизводится на 2-х совершенно различных БД, одна наша тестовая, другая - клиентская. Обе БД проверены dbcc, одинаковая ошибка в данных, даже если ее не определяет сервер при проверке, крайне маловероятна, БД из совершенно разных источников.

Но я допускаю, что что-то криво с настройкой экземпляров серверов, потому что оба ставил и настраивал я один. Потому и спрашиваю, может кто сталкивался с подобной ошибкой. А не то придется в Sybase обращаться.

Еще раз кратко суть ошибки. При добавлении в запрос, возвращающий одну строку, условия where exists () запрос начинает возвращать исходную строку 2 раза. Вот как это на рабочей БД выглядит:

Код: plaintext
1.
2.
3.
4.
5.
select id_tmc, tmc_code, id_tmcgrup
from tmc
where tmc_code = '08'
 and exists (select  1  from v_sxran v where v.id_tmcgrup = tmc.id_tmcgrup and v.schet in ('101003','101001'))
go

Результат:
id_tmc tmc_code id_tmcgrup
14665 08 110
14665 08 110
...
Рейтинг: 0 / 0
09.09.2005, 22:24
    #33262287
guest22222
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка в ASE - подзапрос дублирует строки
Здесь v_sxran - представление на основе таблиц из exists с прямым join-ом. Разницы нет, что с представлением, что без.
...
Рейтинг: 0 / 0
10.09.2005, 00:07
    #33262349
vybegallo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка в ASE - подзапрос дублирует строки
ну хотелось бы увидеть скрипт, который ошибку таки воспроизводит. Тем более, что саппорт Сайбейса его все равно потребует.
...
Рейтинг: 0 / 0
10.09.2005, 09:02
    #33262385
guest22222
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка в ASE - подзапрос дублирует строки
Support у sybase и без скрипта может обойтись, тем более что не всегда ошибка может быть именно в запросе. Дампик порезанный дам или к нам кто-нибудь приедет "вживую" поглядеть. С sybase договориться-то не проблема, я просто думал, что тут кто-то знает в чем беда, если уже сталкивался, так было бы быстрее.

Еще. Согласно запросу, для всех tmc с одинаковым значением id_tmcgrup (в подзапросе участвует только это поле) ошибка должна либо быть, либо отсутствовать, но это не так. Для некоторых tmc она наблюдается, для некоторых нет.
...
Рейтинг: 0 / 0
16.09.2005, 14:51
    #33273822
Сергей Васкецов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка в ASE - подзапрос дублирует строки
Отсылал дампик в sybase.
Пришел ответ, что это баг и он будет исправлен в версии 12.5.4.
Сейчас будем настаивать, чтоб это было раньше.
...
Рейтинг: 0 / 0
17.09.2005, 13:24
    #33274858
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка в ASE - подзапрос дублирует строки
Проблема в том, что это баги в ASE. Мы тоже на них напарывались, да так, что пришлось отказаться от новой версии.
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Ошибка в ASE - подзапрос дублирует строки / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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