Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Проблема с запросом Insert


Автор: Jonnik 1.3.2011, 00:39
Подскажите насчет запроса.
База находится в Access соедина с делфи через ADO.
Выдает ошибку, что пропущен оператор. Не могу понять какой оператор.
Все поля в таблице текстовые
Сам запрос:

Код

INSERT INTO Oper( N, Val, Date_O )
VALUES ( "'+s+'","SELECT Operator.N FROM Operator WHERE (Operator.ID="'+s2+'")","'+s3+'" ) ;

Автор: Данкинг 1.3.2011, 00:46
А с чего ты взял, что подобная конструкция сработает на Access? Вот я попробовал:
Код

insert into cdrom (info) values (select info from cdrom where q=26)

И Access выдал "ошибка синтаксиса". В то время как простой запрос работает:
Код

insert into cdrom select *  from cdrom where q=26

Автор: Antimol 1.3.2011, 11:45
К тому же эта конструкция если бы работала то только в том случае когда выражение:
Цитата

Код

SELECT Operator.N FROM Operator WHERE (Operator.ID="'+s2+'")


возвратит только одно значение.

Инструкция гласит что синтаксис таков:
Код

INSERT INTO конечный_объект [(поле1[, поле2[, ...]])] VALUES (значение1[, значение2[, ...])

Проверь отдельно каждую часть запроса на выполнение в Access, а потом приступай к реализации.

Автор: Jonnik 1.3.2011, 20:45
Спасибо за объяснения, но у меня всеравно не получается.

В общем необходимо из таблицы Operator перенести три поля в таблицу Otob_Oper.
Первое и третье поле тупо переносятся, а для второго поля надо сначало узнать по ID его значение в таблице Val. Я эту проблему решил, но она решается тремя запросами, а это много писанины. Вопрос как сделать эту операцию одним запросом к базе?
Вот пример кода:
Код

Form1.ADOQuery2.Close;
  Form1.ADOQuery2.SQL.Clear;
  Form1.ADOQuery2.SQL.Add('SELECT Operator.*');
  Form1.ADOQuery2.SQL.Add('FROM Operator ;');
  Form1.ADOQuery2.Open;
  while not Form1.ADOQuery2.Eof do
      begin
        s:=Form1.ADOQuery2.Fields.Fields[1].AsString;
        s1:=Form1.ADOQuery2.Fields.Fields[2].AsString;
        s2:=Form1.ADOQuery2.Fields.Fields[3].AsString;
        Form1.ADOQuery4.Close;
        Form1.ADOQuery4.SQL.Clear;
        Form1.ADOQuery4.SQL.Add('SELECT Val.N_Val');
        Form1.ADOQuery4.SQL.Add('FROM Val WHERE (Val.ID_Val='+s1+') ;');
        Form1.ADOQuery4.Open;
        while not Form1.ADOQuery4.Eof do
          begin
            s1:=Form1.ADOQuery4.Fields.Fields[0].AsString;
            Form1.ADOQuery5.Close;
            Form1.ADOQuery5.SQL.Clear;
            Form1.ADOQuery5.SQL.Add('INSERT INTO Otob_Oper( N_O, Val, Date_O ) ');
            Form1.ADOQuery5.SQL.Add('VALUES ( "'+s+'","'+s1+'","'+s2+'" ) ;');
            if(Form1.ADOQuery5.ExecSQL=1)then qw:=1;
            Form1.ADOQuery4.Next;
          end;
        Form1.ADOQuery2.Next;
      end;

Автор: Antimol 2.3.2011, 14:53
Ну что ж, немного разобравшись с вышеприведенным кодом, создал БД. Думаю она будет похожа на оригинал:
Вы писали что:
Цитата

Все поля в таблице текстовые

Это очень интересно, но все же, создал текстовые поля.
Operator 
N_O
ID_VAL
Date_O
Otob_Oper
N_O
Val
Date_O
Val
ID_VAL
N_VAL

Теперь приступим к кодированию. Тестируем запрос в Аксес.

Код

INSERT INTO Otob_Oper(N_O, VAL, Date_O) SELECT Operator.N_O, Val.N_VAL AS VAL, Operator.Date_O FROM Operator,VAL WHERE VAL.ID_VAL = OPERATOR.ID_VAL


О чудо оно работает, а про это еще писал Данкинг 
Цитата

Код

insert into cdrom select *  from cdrom where q=26 



Ладно, теперь переходим к кодированию на делфи. Размещаем на форме ADOConnection1 - настраиваем подключение к БД. размещаем там же ADOQuery1 - настраиваем. Размещаем кнопку, по нажатию на которою будет выполняться запрос. На событие кнопки onClick пишим код:

Код

  try
    with ADOQuery1 do
    begin
      sql.text:='INSERT INTO Otob_Oper(N_O, VAL, Date_O) SELECT Operator.N_O, Val.N_VAL AS VAL, Operator.Date_O FROM Operator,VAL WHERE VAL.ID_VAL = OPERATOR.ID_VAL';
      ExecSQL;
      ShowMessage('Операция удачно завершена');
    end;
  except
    on E:Exception do ShowMessage('Ошибка:'+E.Message);
  end;

Момент истины пришел. Запускаем, нажимаем и видим что? правильно "Операция удачно завершена". Так смотрим программа правильно работает или нет. Открываем Аксес и что видим - все ОК.

Ну это так у меня, у вас может не получиться, но ничего не расстраиваемся, пробуем снова и снова, пока не получиться. 

Кстати можно писать просто
Код

 with ADOQuery1 do
    begin
      sql.text:='INSERT INTO Otob_Oper(N_O, VAL, Date_O) SELECT Operator.N_O, Val.N_VAL AS VAL, Operator.Date_O FROM Operator,VAL WHERE VAL.ID_VAL = OPERATOR.ID_VAL';
      ExecSQL;
      ShowMessage('Операция удачно завершена');
    end;

Автор: Jonnik 2.3.2011, 19:32
Спасибо. Все верно.
Но есть маленькая проблема в этом месте: VAL.ID_VAL = OPERATOR.ID_VAL

VAL.ID_VAL это цифровой параметр, а OPERATOR.ID_VAL текстовый поэтому  происходит сравнение числа и строки. Как в этом случае быть?

Автор: Antimol 3.3.2011, 12:14
Цитата(Jonnik @ 2.3.2011,  19:32)
Спасибо. Все верно.

Пожалуйста.
Цитата(Jonnik @ 2.3.2011,  19:32)

Но есть маленькая проблема в этом месте: VAL.ID_VAL = OPERATOR.ID_VAL    
VAL.ID_VAL это цифровой параметр, а OPERATOR.ID_VAL текстовый поэтому  происходит сравнение числа и строки. Как в этом случае быть?

План действий:
1. (Изменяем таблицу VAL.ID_VAL - цифровое поле, OPERATOR.ID_VAL - текстовое ). Тестируем запрос в Access:

Код

INSERT INTO Otob_Oper(N_O, VAL, Date_O) SELECT Operator.N_O, Val.N_VAL AS VAL, Operator.Date_O FROM Operator,VAL WHERE VAL.ID_VAL = OPERATOR.ID_VAL

Результат: Говорит что типы у нас разные

2. Задаем вопрос: Что нужно сделать???? Ответ: Преобразовать тип, к примеру с текста в число
3. Ищем как преобразовать параметр. Ответ: находим функцию CInt
4. Тестируем снова, но уже с функией CInt

Код

INSERT INTO Otob_Oper ( N_O, VAL, Date_O )
SELECT Operator.N_O, Val.N_VAL AS VAL, Operator.Date_O
FROM Operator, VAL
WHERE VAL.ID_VAL = CInt(OPERATOR.ID_VAL);

Результат: работает. 

Автор: Jonnik 5.3.2011, 12:44
Спасибо за консультацию

Автор: Jonnik 5.3.2011, 18:04
Я кончно извеняюсь, но что то я никак не могу сделать эти два запроса в один.
Я не могу понять как вставить первый запрос вместо переменно s8?

Код

                                    with Form1.ADOQuery2 do
                                      begin
                                        Close;
                                        sql.text:='SELECT G.ID FROM G WHERE (G.GA="")';
                                        Open;
                                        while not Eof do
                                          begin
                                            s8:=Fields.Fields[0].AsString;     /
                                            Next;
                                          end;
                                      end;
                                     with Form1.ADOQuery2 do
                                      begin
                                        Close;
                                        sql.text:='INSERT INTO S(Kod,ID_Gor) VALUES ("'+kod+'",'+s8+')';
                                        ExecSQL;
                                      end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)