![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Пробемы с ADO
DmitryG. © (2009-02-19 22:28:00)При установке запроса вида (запрос к MSSQL 2005):
select top 100 A.IDAdress, A.ADDRESS,
first = (select top 1 I.ID from SLID I where I.TypeID = 'A' and A.IDAdress = I.IDAdress),
second = (select top 1 I.ID from SLID I where I.TypeID = 'B' and A.IDAdress = I.IDAdress),
A.IDOS, A.IDTIP, A.IDDown, D.NMDown
from SLAdress A WITH (NOLOCK)
left join SLDown D WITH (NOLOCK) on A.IDDown = D.IDDown
left join SLTYPE T WITH (NOLOCK) on T.IDTIP = A.IDTIP
left join SLOS O WITH (NOLOCK) on A.IDOS = O.IDOS where A.IDOS = :IDOS;
выводит следующую ошибку (причем, на SQL запросы, в которых ОДНОВРЕМЕННО присутствуют ПОДЗАПРОСЫ И ПАРАМЕТРЫ)
Текст ошибки:
Debug Exception Notification :
Project ADO.exe raised exception class EAccessViolation with message 'Access violation at address 77C3809E in module 'msvcrt.dll'. Write of address 00C9D000'.
Debug Exception Notification :
Project ADO.exe raised exception classEOLeException massage 'Неправильно определен объект Parameter. Представлены несовместимые или неполные сведения'.
ADO ERROR:
'Неправильно определен объект Parameter. Представлены несовместимые или неполные сведения'.
Делаю так:
var
Query : TADOQuery;
Request : string;
begin
Query := TADOQuery.Create(nil);
Query.ConnectionString := 'Provider=SQLOLEDB.1; Initial Catalog = Base; Data Source =SERVER ; User ID = User;'+ 'Password=';
Request := 'select top 100 A.IDAdress, A.ADDRESS, '+
'first = (select top 1 I.ID from SLID I where I.TypeID = 'A' and A.IDAdress = I.IDAdress),'+
'second = (select top 1 I.ID from SLID I where I.TypeID = 'B' and A.IDAdress = I.IDAdress),'+
' A.IDOS, A.IDTIP, A.IDDown, D.NMDown '+
' from SLAdress A WITH (NOLOCK) '+
'left join SLDown D WITH (NOLOCK) on A.IDDown = D.IDDown '+
'left join SLTYPE T WITH (NOLOCK) on T.IDTIP = A.IDTIP '+
' left join SLOS O WITH (NOLOCK) on A.IDOS = O.IDOS where A.IDOS = :IDOS';
Query.SQL.Text := Request ; // ПРИ ВЫПОЛНЕНИИ КОМАНДЫ ВЫВОДИТ ОШИБКУ!!!
Query.Open;
end;
Скачал обновление к ADO - то же самое, только сообщение об ошибке стало на русском :-)
(2009-03-27 13:58:00) [1]Удалено модератором
(2009-03-27 13:58:00) [2]Удалено модератором
DmitryG. (2009-03-25 20:47:00) [3]> Cтранный вывод.
Мда, что-то я конечно же стормозил - спасибо...
ADO такой запрос воспринимает нормально... Хотя что ему в первоначальном не нравилось так и остается загадкой :-)
ЮЮ (2009-03-19 03:42:00) [4]
> мне именно нужно вывести значения полей first и second в
> качестве полей.... Так что Left Join тут не поможет :-(
Cтранный вывод.
Left Join это не UNION. Никто не мешает включать в выборку поля из присоединенных таблиц/подзапросов. Более того, именно для этого соединение обычно и делается
sniknik (2009-03-18 23:41:00) [5]ужас... месяц прошёл, а до автора так и не дошло что параметры нужно заполнять(/инициализировать), хотя это ему в ошибке практически прямым текстом было объявлено...
с работы не уволили? жаль.
DmitryG. (2009-03-18 23:29:00) [6]>какой-то синтаксис для "полей" first и second прикольный. И это работает?
Работает кончено (если не ошибаюсь, то практически полный аналог as first...)
А поводу приведенного Вами подзапроса, есть одна неувязка - мне именно нужно вывести значения полей first и second в качестве полей.... Так что Left Join тут не поможет :-(
ЮЮ (2009-03-12 11:03:00) [7]
> только если из текста запроса убрать поля first и second
какой-то синтаксис для "полей" first и second прикольный. И это работает?
А если попроще и попривычней:
select top 100 A.IDAdress, A.ADDRESS,
(select top 1 I.ID from SLID I where I.TypeID = 'A' and A.IDAdress = I.IDAdress) as first,
(select top 1 I.ID from SLID I where I.TypeID = 'B' and A.IDAdress = I.IDAdress) as second,
A.IDOS, A.IDTIP, A.IDDown, D.NMDown
А если вообще использовать подзапросы правильно, т.е. не в списке полей, а в качестве "таблиц"?
from
SLAdress A
left join SLDown D on A.IDDown = D.IDDown
left join SLTYPE T on T.IDTIP = A.IDTIP
left join SLOS O on A.IDOS = O.IDOS
LEFT JOIN (
select IDAdress, MIN(ID) as First from SLID where TypeID = 'A' GROUP BY IDAdress
) f ON A.IDAdress = f.IDAdress
LEFT JOIN (
select IDAdress, MIN(ID) as Second from SLID where TypeID = 'B' GROUP BY IDAdress
) s ON A.IDAdress = s.IDAdress
where A.IDOS = :IDOS
DmitryG. (2009-03-12 10:45:00) [8]Все открыто и все работает, только если из текста запроса убрать поля first и second. А через BDE все работает и ними!!!
ЮЮ (2009-03-12 03:50:00) [9]
> DataSource подключен к Query у которого есть поле IDOS
по тексту запроса или добавлено в список полей? Кажется второе решает проблему (ух как давно это было :), ибо не факт, что DataSource1.DataSet открыт и есть где взять информацию о поле IDOS
DmitryG. (2009-03-11 20:56:00) [10]Забыл в письме, почему-то указать DataSource, хотя реально в программе есть.... DataSource подключен к Query у которого есть поле IDOS
Все таки на мой взгляд - явный глюк ADO. Может подскажите как исправить?
Еще раз измененный код
var
Query : TADOQuery;
Request : string;
begin
Query := TADOQuery.Create(nil);
try
Query.ConnectionString := 'Provider=SQLOLEDB.1; Initial Catalog = Base; Data Source =SERVER ; User ID = User;'+ 'Password=';
Request := 'select top 100 A.IDAdress, A.ADDRESS, '+
'first = (select top 1 I.ID from SLID I where I.TypeID = 'A' and A.IDAdress = I.IDAdress),'+
'second = (select top 1 I.ID from SLID I where I.TypeID = 'B' and A.IDAdress = I.IDAdress),'+
' A.IDOS, A.IDTIP, A.IDDown, D.NMDown '+
' from SLAdress A WITH (NOLOCK) '+
'left join SLDown D WITH (NOLOCK) on A.IDDown = D.IDDown '+
'left join SLTYPE T WITH (NOLOCK) on T.IDTIP = A.IDTIP '+
' left join SLOS O WITH (NOLOCK) on A.IDOS = O.IDOS where A.IDOS = :IDOS';
Query.Datasource := DataSource1;
Query.SQL.Text := Request ;
Query.Open;
finally
Query.Free;
end;
end;
Anatoly Podgoretsky (2009-02-25 10:13:00) [11]> девушка (25.02.2009 9:23:11) [11]
Это глупый совет, надо наоборот, что бы совпадал, как в приведеном коде
девушка (2009-02-25 09:23:00) [12]
> > ' left join SLOS O WITH (NOLOCK) on A.IDOS = O.IDOS where
> A.IDOS = :IDOS';
>
> вот он параметр, надо с ним чего-нибудь делать.
Я бы для начала попробовала переназвать параметр, чтобы его название не совпадало ни с каким из выбираемых полей... типа :idos_my_tmp
иногда при "странных глюках" может помочь
KSergey (2009-02-24 13:02:00) [13]>
' left join SLOS O WITH (NOLOCK) on A.IDOS = O.IDOS where A.IDOS = :IDOS';
вот он параметр, надо с ним чего-нибудь делать.
Ega23 (2009-02-24 11:46:00) [14]
> Просто точно такой же код для BDE работает очень даже отлично!
> !!
и под BDE не сработает. Сработает, если только немножко "похимичить".
С другой стороны, если немножко "похимичить" - сработает и для ADO.
З.Ы.
Если уж создаёшь TQuery в ран-тайм - будь любезен её потом убить.
ЮЮ (2009-02-24 11:24:00) [15]
> Query.SQL.Text := Request ; // ПРИ ВЫПОЛНЕНИИ КОМАНДЫ ВЫВОДИТ
> ОШИБКУ!!!
При определении текста запроса или при поgытке выполнить запрос с неопределенным параметром?
Если второе, то где
Query.Parameters[0].As... := ...
> Query.Open;
Медвежонок Пятачок (2009-02-20 22:48:00) [16]Просто если в запросе нет параметра, или убрать строчки с подзапросом, то все нормально!!!
ну дык убери
Johnmen (2009-02-20 22:40:00) [17]А я говорю, не скомпилируется.
DmitriyG. (2009-02-20 22:21:00) [18]Просто точно такой же код для BDE работает очень даже отлично!!!
DmitriyG. (2009-02-20 22:20:00) [19]Скомпилируется, еще как...
Единственное, что забыл эту строчку :-)
Query.DataSource := SomDataSource;
Просто если в запросе нет параметра, или убрать строчки с подзапросом, то все нормально!!!
Johnmen (2009-02-19 22:41:00) [20]это даже не скомпилируется.