Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как избавиться от ошибки multiple rows in singleton select? 
:(
    Опции темы
Alex
Дата 13.11.2004, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: 17
Всего: 162



Очевидно что данная ошибка происходит в вашем триггере или хранимой процедуре. Обычный SELECT внутри триггера или процедуры должен возвращать одну строку (row), т.к. при двух и более строках IB не знает куда поместить значения полей этих строк. Если ваш SELECT возвращает несколько записей, то нужно пользоваться конструкцией FOR SELECT ... INTO ... DO ... которая производит обработку возвращаемого набора записей в цикле. 

Если-же вы уверены, что ваш SELECT должен вернуть только одну запись, а ошибка все-таки возникает, то давайте рассмотрим следующую ситуацию: 

существуют таблицы ORDERS (заказы) и CLIENTS (клиенты). 
обе эти таблицы имеют поле связи CLIENT_ID INTEGER. 
для того чтобы вытащить информацию о клиенте используется запрос: 

Код

SELECT CLIENT_ID, CLIENT_NAME  
FROM CLIENTS  
WHERE CLIENT_ID = ?
  

где ? - либо значение либо переменная. 

Теперь представим себе, что этот запрос должен выполняться в триггере при вставке записи в таблицу ORDERS 

Код

CREATE TRIGGER TI_ORDERS FOR ORDERS  
ACTIVE AFTER INSERT POSITION 0  
AS  
DECLARE VARIABLE CID INTEGER;  
DECLARE VARIABLE CNAME CHAR(30);  
BEGIN  
    SELECT C.CLIENT_ID, C.CLIENT_NAME  
    FROM CLIENTS C  
    WHERE C.CLIENT_ID = CLIENT_ID  
    INTO :CID, :CNAME;  
    ...
  

Итак, поскольку в запросе использован псевдоним C (FROM CLIENTS C), то якобы существует гарантия что в предложении WHERE будут сравниваться поле C.CLIENT_ID из таблицы CLIENTS и поле CLIENT_ID из таблицы ORDERS (в триггере доступны имена полей собственной таблицы). На самом деле даже использование псевдонимов не дает гарантии что переменные будут разичаться, и получается что в предложении WHERE сравнивается само с собой поле таблицы CLIENTS.CLIENT_ID, и в запросе возвращается ВСЯ таблица CLIENTS. 

Вот почему возникает вышеупомянутое сообщение об ошибке. 

Избавиться от него можно несколькими путями: 

Использовать разные имена полей для связи между CLIENTS и ORDERS. например OCLIENT_ID и CCLIENT_ID. 
Использовать уточнитель new.CLIENT_ID, несмотря на то что в документации указано что для триггеров последействия (AFTER) он не имеет смысла. 

Код

SELECT C.CLIENT_ID, C.CLIENT_NAME  
FROM CLIENTS C  
WHERE C.CLIENT_ID = new.CLIENT_ID  
...
  

Перед запросом поместить CLIENT_ID в локальную переменную, и в запросе использовать сравнение не с полем, а с этой локальной переменной. 

Код

CID=CLIENT_ID;  
SELECT C.CLIENT_ID, C.CLIENT_NAME  
FROM CLIENTS C  
WHERE C.CLIENT_ID = :CID  
...
  


Borland Interbase / Firebird FAQ 
Borland Interbase / Firebird Q&A, версия 2.02 от 31 мая 1999 
последняя редакция от 17 ноября 1999 года. 
Часто задаваемые вопросы и ответы по Borland Interbase / Firebird 
Материал подготовлен в Демо-центре клиент-серверных технологий. (Epsylon Technologies) 
Материал не является официальной информацией компании Borland. 
E-mail mailto:[email protected] 
www: http://www.ibase.ru/ 
Телефоны: 953-13-34 
источники: Borland International, Борланд АО, релиз Interbase 4.0, 4.1, 4.2, 5.0, 5.1, 5.5, 5.6, различные источники на WWW-серверах, текущая переписка, московский семинар по Delphi и конференции, листсервер ESUNIX1, листсервер mers.com. 
Cоставитель: Дмитрий Кузьменко


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.1005 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.