Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
24 / 22 / 9
Регистрация: 23.09.2014
Сообщений: 326
1

Обновляемый запрос или SET = (SELECT) - (value)

09.11.2017, 14:28. Показов 685. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть 2 запроса. Выглядят следующим образом :
Кликните здесь для просмотра всего текста
Delphi
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
 try
    qr := TADOQuery.Create(DBQ.Owner);
//Первый запрос  
    try
      qr.Connection := DBQ.Connection;
      StrSQL := '(SELECT AlcCode,RegFormB,Kolichestvo FROM ContentSpisanie WHERE SpisanieID IN' +
      '(SELECT SpisanieID FROM SPISANIE WHERE IsEGAIS = False and IsConfirm = False))';
      qr.sql.Text := StrSQL;
 
      qr.Open;
      if qr.RecordCount > 0 then
       begin
         SLSpisProduction := TList<recRestSpis>.Create;
         for I := 0 to qr.RecordCount - 1 do
         begin
           MyRecord.alcCode := qr.FieldByName('AlcCode').AsString;
           MyRecord.RegFormB := qr.FieldByName('RegFormB').AsString;
           MyRecord.Count := qr.FieldByName('Kolichestvo').AsString;
           SLSpisProduction.Add(MyRecord);
         end;
       end;
    finally
      qr.Free;
    end;
//    StrSQL := 'UPDATE ContentRest SET Kolichestvo = ((SELECT Kolichestvo FROM ContentRest WHERE (AlcCode = '''+
//     qr.FieldByName('AlcCode').AsString +''') AND (RegFormB = '''+ qr.FieldByName('RegFormB').AsString +''')) - '+ qr.FieldByName('Kolichestvo').AsString +' )'+
//    ' WHERE ((RegFormB = ''' + qr.FieldByName('RegFormB').AsString + ''') AND (AlcCode = ''' + qr.FieldByName('AlcCode').AsString + '''))';
 //Второй запрос  
  try
      qr := TADOQuery.Create(DBQ.Owner);
      qr.Connection := DBQ.Connection;
      for i := 0 to SLSpisProduction.Count - 1 do
      begin
        StrSQL := 'UPDATE ContentRest SET Kolichestvo = ((SELECT Kolichestvo FROM ContentRest WHERE (AlcCode = '''+
              recRestSpis(SLSpisProduction[i]).alcCode +''') AND (RegFormB = '''+ recRestSpis(SLSpisProduction[i]).RegFormB +''')) - '+ recRestSpis(SLSpisProduction[i]).Count +' )'+
             ' WHERE ((RegFormB = ''' + recRestSpis(SLSpisProduction[i]).RegFormB + ''') AND (AlcCode = ''' + recRestSpis(SLSpisProduction[i]).alcCode + '''))';
        qr.sql.Text := StrSQL;
        qr.ExecSQL;
      end;
    finally
      if Assigned(SLSpisProduction) then
      SLSpisProduction.free;
      qr.Free;
    end;
  except
     on e:exception do
     ShowMessage(e.message);
  end;

1. Первый запрос отрабатывает адекватно. Рекорд заполняется всё хорошо. Второй запрос выводит ошибку ©"В операции должен использоваться обновляемый запрос". Погуглив эту ошибку пришел к выводу, что либо разделить второй запрос на два (SELECT и UPDATE). Либо использовать INSERT и DELETE.
2. Мне почему то кажется ,что это можно сделать гораздо меньшим количеством запросов.

PS: что собственно требуется вообще этими запросами сделать:
1. Найти AlcCode,RegFormB,Kolichestvo FROM ContentSpisanie ( в общем смотрите 1ый запрос там всё просто)
2. Найти Kolichestvo в таблице ContentRest По AlcCode,RegFormB.
3. Вычислить разницу ContentRest.Kolichestvo - ContentSpisanie.Kolichestvo.
4. Обновить запись в таблице ContentRest.Kolichestvo на результат разницы.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.11.2017, 14:28
Ответы с готовыми решениями:

Обновляемый запрос
При изминени данных в БД таблице выходит ошибка, вот код к ADOquery SELECT *FROM Трансфера,...

'В операции должен использоваться обновляемый запрос'
Задача стоит казалась бы тривиальная, нужно просто добавить записи в таблицу. Или изменить...

в операции должен использоваться обновляемый запрос
Вылетает ошибка у парня на видео все работает! http://www.youtube.com/watch?v=GK54lgpUbmU

Выводит сообщение: В операции должен использоваться обновляемый запрос
Всем привет!) Суть проблемы: есть приложение, которое работает с файлом БД Акцесс, компиляцию это...

12
5395 / 4323 / 1060
Регистрация: 29.08.2013
Сообщений: 27,130
Записей в блоге: 3
09.11.2017, 19:39 2
а в чем вопрос то?
0
Эксперт Pascal/Delphi
1134 / 615 / 129
Регистрация: 13.02.2009
Сообщений: 3,554
09.11.2017, 21:40 3
Цитата Сообщение от vijer Посмотреть сообщение
2. Мне почему то кажется
Вы как думайте, что при SELECT выполнять UPDATE это нормально ?
1) На каком СУБД вы создали БД ?!
2) Что у вас есть на это БД и что трбутся ?
0
24 / 22 / 9
Регистрация: 23.09.2014
Сообщений: 326
10.11.2017, 08:21  [ТС] 4
qwertehok,
1. Хочу всё сделать минимальным количеством запросов.
2. Определенно кажется что :
Цитата Сообщение от vijer Посмотреть сообщение
1. Найти AlcCode,RegFormB,Kolichestvo FROM ContentSpisanie ( в общем смотрите 1ый запрос там всё просто)
2. Найти Kolichestvo в таблице ContentRest По AlcCode,RegFormB.
как минимум это можно сделать одним запросом .... только вот я не догоняю как)


xxbesoxx,
Цитата Сообщение от xxbesoxx Посмотреть сообщение
1) На каком СУБД вы создали БД ?!
- Access. Создавал не я. Работать приходится мне.
Цитата Сообщение от xxbesoxx Посмотреть сообщение
2) Что у вас есть на это БД?
- там много чего есть и это собственно не важно

Цитата Сообщение от xxbesoxx Посмотреть сообщение
что трбутся ?
-
Цитата Сообщение от vijer Посмотреть сообщение
1. Найти AlcCode,RegFormB,Kolichestvo FROM ContentSpisanie ( в общем смотрите 1ый запрос там всё просто)
2. Найти Kolichestvo в таблице ContentRest По AlcCode,RegFormB.
3. Вычислить разницу ContentRest.Kolichestvo - ContentSpisanie.Kolichestvo.
4. Обновить запись в таблице ContentRest.Kolichestvo на результат разницы.
Минимальным количеством запросов хочу обойтись.
Цитата Сообщение от xxbesoxx Посмотреть сообщение
Вы как думайте, что при SELECT выполнять UPDATE это нормально ?
С SQL знаком плохо ... но учуся потихонечку.
0
Модератор
9267 / 6045 / 2380
Регистрация: 21.01.2014
Сообщений: 25,812
Записей в блоге: 3
10.11.2017, 08:49 5
Цитата Сообщение от vijer Посмотреть сообщение
UPDATE ContentRest SET Kolichestvo = ((SELECT Kolichestvo...
Access не поддерживает вложенные запросы.
0
24 / 22 / 9
Регистрация: 23.09.2014
Сообщений: 326
10.11.2017, 09:25  [ТС] 6
D1973,
Цитата Сообщение от D1973 Посмотреть сообщение
Access не поддерживает вложенные запросы.
Скорее не так. Ведь первый запрос по сути вложенный. Вполне он поддерживает. А вот конструкция UPDATE ... SET ... SELECT (...) - тут является бредом с точки зрения SQL так как SELECT теоретически (да и практически но не в моем случае) может вернуть несколько значений. Или я не прав? И такая конструкция например в MSSQL сработает? хотя как-то сомнительно...
0
1074 / 987 / 340
Регистрация: 07.08.2012
Сообщений: 2,790
10.11.2017, 09:56 7
Второй запрос вполне может быть работоспособным.
Пара замечаний.
Существенная ошибка - значения чисел в текст запроса не могут передаваться заключенными в кавычки (кавычки только для текста и в других СУБД для дат). Если, конечно, типы полей числовые. Если же не числовые, то тогда и выполнять арифметические действия в запросе невозможно.
И следом, зачем вычислять разность в тексте запроса (не всегда и получится), когда лучше это сделать в переменной и это значение передать в текст запроса.
Пусть даже для этого придется преобразовать текстовые представления чисел в числовые значения, а для передачи в запрос значение разности обратно в текст. Все равно в этом случае синтаксис запроса пострадает меньше
0
24 / 22 / 9
Регистрация: 23.09.2014
Сообщений: 326
10.11.2017, 10:19  [ТС] 8
Скандербег,
Цитата Сообщение от Скандербег Посмотреть сообщение
И следом, зачем вычислять разность в тексте запроса
Оюъясню я же хотел обойтись минимальным количеством запросов. А соответсвенно не сделав
Delphi
1
2
((SELECT Kolichestvo FROM ContentRest WHERE (AlcCode = '''+
* * * * * * * recRestSpis(SLSpisProduction[i]).alcCode +''') AND (RegFormB = '''+ recRestSpis(SLSpisProduction[i]).RegFormB +'''))
в отдельном запросе я не смогу присвоить это значение в переменную и вычислить разность...

Цитата Сообщение от Скандербег Посмотреть сообщение
Существенная ошибка - значения чисел в текст запроса не могут передаваться заключенными в кавычки (кавычки только для текста и в других СУБД для дат). Если, конечно, типы полей числовые. Если же не числовые, то тогда и выполнять арифметические действия в запросе невозможно.
А вот тут я не понял... Да я добавляю так
Delphi
1
 '+ recRestSpis(SLSpisProduction[i]).Count +'
но в тексте запроса они будут без ковычек как числовые ... ведь строковые я добавляю так
Delphi
1
'''+ recRestSpis(SLSpisProduction[i]).RegFormB +'''
.
Вот ShowMessage StrSQL.
Обновляемый запрос или SET = (SELECT) - (value)

И да типа полей числовые.
Так что моя вера в то что второй запрос работоспособен как то угасла)
0
1074 / 987 / 340
Регистрация: 07.08.2012
Сообщений: 2,790
10.11.2017, 11:15 9
Уточню.
Если передавать числовое значение в текст запроса, то оно НЕ ДОЛЖНО ОБРАМЛЯТЬСЯ КАВЫЧКАМИ.
Цитата Сообщение от vijer Посмотреть сообщение
ведь строковые я добавляю так
Delphi
1
'''+ recRestSpis(SLSpisProduction[i]).RegFormB +'''
Именно так и нельзя делать, если значение RegFormB - это числовое значение в текстовом представлении.

---
Вот это выражение должно вычислять разность между двумя значениями, которые находятся в строковом представлении:
Delphi
1
...'''+ recRestSpis(SLSpisProduction[i]).RegFormB +''')) - '+ recRestSpis(SLSpisProduction[i]).Count
Его и предлагается вычислить с использованием промежуточной переменной, а НЕ ЗАПРОСОМ.
Примерно так:
Delphi
1
2
3
4
  Vr := StrToInt(recRestSpis(SLSpisProduction[i]).RegFormB) + 
        StrToInt(recRestSpis(SLSpisProduction[i]).Count);
  //затем вычисленное значение вставить в запрос:
  '... AND (RegFormB = '+IntTostr(Vr)+ ' WHERE ...'
Это приводит к лишним преобразованием, но сильно облегчает жизнь тому, кто формирует сложные запросы.
0
24 / 22 / 9
Регистрация: 23.09.2014
Сообщений: 326
10.11.2017, 11:48  [ТС] 10
Скандербег, Эммм.. нет. c RegFormB никаких вычислений не производится. RegFormB строковый. А вычитание я произвожу(Пытался произвести из SELECT`а).
Этого вот селекта :
Цитата Сообщение от vijer Посмотреть сообщение
((SELECT Kolichestvo FROM ContentRest WHERE (AlcCode = '''+
recRestSpis(SLSpisProduction[i]).alcCode +''') AND (RegFormB = '''+ recRestSpis(SLSpisProduction[i]).RegFormB +'''))
На скрине же видно что это текст
Обновляемый запрос или SET = (SELECT) - (value)
0
24 / 22 / 9
Регистрация: 23.09.2014
Сообщений: 326
10.11.2017, 12:06  [ТС] 11
Ещё пожалуй добавлю: чтобы внести ясность Типы полей Все кроме полей [Kolichestvo] Строковые. Поля [Kolichestvo] числовые.
0
Скандербег
10.11.2017, 12:20
  #12

Не по теме:

Без пол-литра и без проекта с базой вряд ли разобрать, что к чему, зачем и в чем причина проблемы.

0
24 / 22 / 9
Регистрация: 23.09.2014
Сообщений: 326
10.11.2017, 13:40  [ТС] 13
В общем сделал 3мя запросами 2 из которых в цикле .
Кликните здесь для просмотра всего текста
Delphi
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
  try
    qr := TADOQuery.Create(DBQ.Owner);
    try
      qr.Connection := DBQ.Connection;
      StrSQL := '(SELECT AlcCode,RegFormB,Kolichestvo FROM ContentSpisanie WHERE SpisanieID IN' +
      '(SELECT SpisanieID FROM SPISANIE WHERE IsEGAIS = False and IsConfirm = False))';
      qr.sql.Text := StrSQL;
 
      qr.Open;
      if qr.RecordCount > 0 then
       begin
         SLSpisProduction := TList<recRestSpis>.Create;
         for I := 0 to qr.RecordCount - 1 do
         begin
           MyRecord.alcCode := qr.FieldByName('AlcCode').AsString;
           MyRecord.RegFormB := qr.FieldByName('RegFormB').AsString;
           MyRecord.Count := qr.FieldByName('Kolichestvo').AsString;
           SLSpisProduction.Add(MyRecord);
         end;
       end;
    finally
      qr.Free;
    end;
//    StrSQL := 'UPDATE ContentRest SET Kolichestvo = ((SELECT Kolichestvo FROM ContentRest WHERE (AlcCode = '''+
//     qr.FieldByName('AlcCode').AsString +''') AND (RegFormB = '''+ qr.FieldByName('RegFormB').AsString +''')) - '+ qr.FieldByName('Kolichestvo').AsString +' )'+
//    ' WHERE ((RegFormB = ''' + qr.FieldByName('RegFormB').AsString + ''') AND (AlcCode = ''' + qr.FieldByName('AlcCode').AsString + '''))';
    if Assigned(SLSpisProduction) then
    begin
      for i := 0 to SLSpisProduction.Count - 1 do
      begin
        try
          qr := TADOQuery.Create(DBQ.Owner);
          qr.Connection := DBQ.Connection;
            StrSQL := 'SELECT Kolichestvo FROM ContentRest WHERE ((AlcCode = '''+
            recRestSpis(SLSpisProduction[i]).alcCode +''') AND (RegFormB = '''+ recRestSpis(SLSpisProduction[i]).RegFormB +'''))';
           // ShowMessage(StrSQL);
            qr.sql.Text := StrSQL;
            qr.Open;
            if qr.RecordCount > 0 then
            begin
              MyRecord.alcCode := recRestSpis(SLSpisProduction[i]).alcCode;
              MyRecord.RegFormB := recRestSpis(SLSpisProduction[i]).RegFormB;
              MyRecord.Count := FloatToStr(qr.FieldByName('Kolichestvo').AsFloat - StrToFloat(recRestSpis(SLSpisProduction[i]).Count));
              SLSpisProduction.Items[i] := MyRecord;
            end;
        finally
          qr.Free;
        end;
 
        try
          qr := TADOQuery.Create(DBQ.Owner);
          qr.Connection := DBQ.Connection;
          StrSQL := 'UPDATE ContentRest SET Kolichestvo = ' + recRestSpis(SLSpisProduction[i]).Count +
               ' WHERE ((RegFormB = ''' + recRestSpis(SLSpisProduction[i]).RegFormB + ''') AND (AlcCode = ''' + recRestSpis(SLSpisProduction[i]).alcCode + '''))';
          qr.sql.Text := StrSQL;
          qr.ExecSQL;
        finally
          qr.Free;
        end;
      end;
 
      if Assigned(SLSpisProduction) then
      SLSpisProduction.free;
    end;
  except
     on e:exception do
     ShowMessage(e.message);
  end;
0
10.11.2017, 13:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.11.2017, 13:40
Помогаю со студенческими работами здесь

В операции должен использоваться обновляемый запрос. Но он и так обновляемый
Здравствуйте, у кипит мозг. &quot;... .CommandText = &quot;Update ...&quot; - это обновляемый запрос? Dim myC...

Почему запрос не обновляемый и как переделать в обновляемый
Уважаемые форумчане, Помогите переделать запрос в обновляемый UPDATE (SELECT P.ArtikID,...

Запрос sql UPDATE .SET поле=м.поле FROM (SELECT.) AS м
Вечер добрый, граждане, подскажите пожалуйста... можно ли в Access реализовать запрос вида ...

Обновляемый запрос в бд
Добрый день.Уже устал мучаться с данной проблемой,может кто знает как исправить ... Если запускать...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru