Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 13.01.2011, 19:55
Iros Iros вне форума
Прохожий
 
Регистрация: 13.01.2011
Сообщения: 4
Репутация: 10
По умолчанию Запрос на копирование данных

Помогите, пожалуйста, написать запрос!
Есть две таблицы, Table1, Table2.
В одной из них есть столбцы a1, b1, c1, но c1 не заполнен. В другой a2,b2,c2, заполнены все три.
Как перенести значения из с2 в с1?

При таком запросе:
UPDATE Table1
SET с1 = (SELECT с2 FROM Table2 where Table1.a1=Table2.a2 and Table1.b1=Table2.b2)
выдаёт ошибку
"Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression."

Как правильно написать запрос, чтобы каждому конкретному значению возвращалось только одно?
Ответить с цитированием
  #2  
Старый 13.01.2011, 20:05
Аватар для Pilot_Red
Pilot_Red Pilot_Red вне форума
Продвинутый
 
Регистрация: 01.11.2006
Адрес: Карелия
Сообщения: 702
Версия Delphi: D7
Репутация: 11581
По умолчанию

А можно ли вообще средствами SQL делать такие операции????
Таблицы могут быть разными по размеру. Поэтому тут вряд ли можно написать универсальный запрос.
Я думаю без цикла здесь не обойтись
Ответить с цитированием
  #3  
Старый 14.01.2011, 00:54
Iros Iros вне форума
Прохожий
 
Регистрация: 13.01.2011
Сообщения: 4
Репутация: 10
По умолчанию

В каком смысле, разные?
какая разница, какого они размера?

Ну, если конкретный пример, в первой таблице - 1000 записей, одни из столбцов - дата и код метеостанции. Ещё есть поле температуры, которое по 5-ти метеостанциям заполнено, а по 6-ой - нет. Это, например, 100записей.
А в другой таблице 200 записей, по 5 и 6 метеостанции, из которых как раз можно пополнить пропуски в первой таблице: там идёт дата, код метеостанции, температура. Осталось соответственно перенести по каждой дате 6-ой метеостанции данные во первую таблицу, т.е. берётся первая запись из второй таблицы, например 1.01.2010, код 6, ищется в первой таблице запись с таким же сочетанием даты и кода, и помещается туда температура. И т.д.

Вроде кажется просто, но обычным Update этого не сделать, т.к., как я понимаю, в написанном мной запросе он отбирает сразу все записи, для которых пара полей в одной таблице равны паре в другой, а не по очереди по одной записи... Но может я ошибаюсь...
Ответить с цитированием
  #4  
Старый 14.01.2011, 01:44
stil stil вне форума
Новичок
 
Регистрация: 24.11.2010
Сообщения: 91
Репутация: 41
По умолчанию

Код:
UPDATE Table1, Table2
SET Table1.с1 = Table2.с2 
WHERE Table1.a1=Table2.a2 and Table1.b1=Table2.b2
значения полей Table1.a1=Table2.a2 and Table1.b1=Table2.b2 должны быть одинаковые
Ответить с цитированием
  #5  
Старый 14.01.2011, 02:14
Iros Iros вне форума
Прохожий
 
Регистрация: 13.01.2011
Сообщения: 4
Репутация: 10
По умолчанию

Цитата:
Сообщение от stil
Код:
UPDATE Table1, Table2
SET Table1.с1 = Table2.с2 
WHERE Table1.a1=Table2.a2 and Table1.b1=Table2.b2
значения полей Table1.a1=Table2.a2 and Table1.b1=Table2.b2 должны быть одинаковые

Ошибка в первой строке "UPDATE Table1, Table2" на перечислении двух таблиц..
Ответить с цитированием
  #6  
Старый 14.01.2011, 06:40
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Проблема в том, что для Update, твой подзапрос должен вернуть всего одну строчку, а у тебя, похоже, коды повторяются (a1 и b1).

Теперь о задаче.
Вариант 1. Если это разрвая операция, то лучше просто удалить данные о 6 станции из первой таблицы и скопировать туда данные из второй.
Код:
begin

delete from table1 where a1 = 6;
insert into table1 (a1, b1, c1) values (select a1, b1, c1 from table2 where a1 = 6);

commit;

Вариант 2. Если это постоянная проблема, то:
а) решаем ее как и в в.1, но только делаем процку, которую периодически и запускаем.
б) делаем view так, что в нее попадают данные для всх станций кроме 6 из первой таблицы и данные из второй таблицы, но только о 6ой станции:
Код:
create view table_view as
select a1, b1, c1 from table1 where a1 <> 6
union all
select a1, b1, c1 from table2 where a1 = 6;
Если ты собираешься делать обновление через эту view, то тебе еще придется создать триггера на insert, update и delete. что бы объяснить БД с какой из таблиц ты будешь работать.
Ответить с цитированием
  #7  
Старый 14.01.2011, 12:27
Iros Iros вне форума
Прохожий
 
Регистрация: 13.01.2011
Сообщения: 4
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Проблема в том, что для Update, твой подзапрос должен вернуть всего одну строчку, а у тебя, похоже, коды повторяются (a1 и b1).

Теперь о задаче.
Вариант 1. Если это разрвая операция, то лучше просто удалить данные о 6 станции из первой таблицы и скопировать туда данные из второй.
Код:
begin

delete from table1 where a1 = 6;
insert into table1 (a1, b1, c1) values (select a1, b1, c1 from table2 where a1 = 6);

commit;

Вариант 2. Если это постоянная проблема, то:
а) решаем ее как и в в.1, но только делаем процку, которую периодически и запускаем.
б) делаем view так, что в нее попадают данные для всх станций кроме 6 из первой таблицы и данные из второй таблицы, но только о 6ой станции:

Вообще, комбинации a1 и b1 не повторяются. Но даже если повторяются, что плохого? Значит, во все строки первой таблицы, где встречается сочетание a1-b1 вставлять одно и тоже значение с1. (Во второй таблице точно повторяющихся сочетаний нет).

Вариант с удалением не подходит, т.к. в первой таблице помимо этих трёх полей содержится ещё огромное количество других... Просто так оказалось, что кусок одного из этих полей не заполнен, и его можно заполнить, взяв данные из другой таблицы.
Делать новую таблицу и в неё перемещать данные из обеих таблиц проблематично, т.к. получается, что нужно для части записей перенести данные полностью из первой таблицы, а для части (например, с 201ой по 301ую) - все, кроме этого поля, из первой, а это поле из второй.
Кроме того, проблемно будет восстанавливать ключи и связи к этой таблице. Да и из старой удалить записи невозможно, т.к. на них ссылаются другие таблицы.

Неужели никак нельзя просто вставить записи в этот столбец по определённому условию?...

Ну может циклом..
Ответить с цитированием
  #8  
Старый 14.01.2011, 20:16
Аватар для Pilot_Red
Pilot_Red Pilot_Red вне форума
Продвинутый
 
Регистрация: 01.11.2006
Адрес: Карелия
Сообщения: 702
Версия Delphi: D7
Репутация: 11581
По умолчанию

Здесь пахнет вложенным подзапросом.
Если используется локальный SQL (таблицы типа paradox), то я бы сделал циклом, от безысходности.
А подзапросы можно делать вроде на IB и на ADO ...
Ответить с цитированием
  #9  
Старый 14.01.2011, 20:56
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Что не устраивает?
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:06.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter