обновить таблицу Informix с помощью соединений

это правильный синтаксис для обновления Informix?

update table1
set table1.code = 100
from table1 a, table2 b, table3 c
where a.key = c.key
a.no = b.no
a.key = c.key
a.code = 10
b.tor = 'THE'
a.group = 4183
a.no in ('1111','1331','1345')

Я получаю сообщение generic -201 "произошла синтаксическая ошибка", но я не вижу, что не так.

5 ответов


ваша синтаксическая ошибка-table1.код

set table1.code = 100

изменить это

set a.code = 100

код

update table1
set a.code = 100
from table1 a, table2 b, table3 c
where a.key = c.key
and a.no = b.no
and a.key = c.key
and a.code = 10
and b.tor = 'THE'
and a.group = 4183
and a.no in ('1111','1331','1345')

к сожалению, принятый ответ вызывает синтаксическую ошибку в Informix Dynamic Server версии 11.50.

Это единственный способ избежать ошибки синтаксис:

update table1
set code = (
  select 100
  from table2 b, table3 c
  where table1.key = c.key
  and table1.no = b.no
  and table1.key = c.key
  and table1.code = 10
  and b.tor = 'THE'
  and table1.group = 4183
  and table1.no in ('1111','1331','1345')
)

кстати, к получить версию Informix, запустите следующий SQL:

select first 1 dbinfo("version", "full") from systables;

исходный SQL в вопросе был:

update table1
set table1.code = 100
from table1 a, table2 b, table3 c
where a.key = c.key
a.no = b.no
a.key = c.key
a.code = 10
b.tor = 'THE'
a.group = 4183
a.no in ('1111','1331','1345')

это безусловно отсутствует ряд и ключевых слов. Принятое решение также определяет проблему в предложении SET с использованием table1 вместо своего псевдонима a. Это может быть материал, я не могу проверить это (см. обсуждение ниже). Таким образом, предполагая, что обновление join принято вообще, исправленный SQL должен читать:

UPDATE table1
   SET a.code = 100
  FROM table1 a, table2 b, table3 c
 WHERE a.key = c.key
   AND a.no = b.no
   AND a.key = c.key
   AND a.code = 10
   AND b.tor = 'THE'
   AND a.group = 4183
   AND a.no IN ('1111','1331','1345')

это то же самое, что и (исправленный синтаксис) принятый ответ. Тем не менее, мне интересно узнать, какую версию Informix вы используете, которая принимает синтаксис FROM (возможно, XPS?). Я использую IDS 11.70.FC2 (3 пакета исправлений за текущим 11.70.Версия FC5) на Mac OS X 10.7.4, и я не могу получить обновление с помощью синтаксиса для работы. Далее руководство по эксплуатации у IBM Как Informix 11.70 Информационный Центр для обновления не упоминает об этом. Я не уверен, будет ли иметь значение, если вы используете ODBC или JDBC; это не должно, но я использую ESQL/C, который отправляет SQL без изменений на сервер.

обозначение, которое я пробовал (+ - это подсказка):

+ BEGIN;
+ CREATE TABLE a(a INTEGER NOT NULL, x CHAR(10) NOT NULL, y DATE NOT NULL);
+ INSERT INTO a(a, x, y) VALUES(1, 'obsoletely', '2012-04-01');
+ INSERT INTO a(a, x, y) VALUES(2, 'absolutely', '2012-06-01');
+ CREATE TABLE b(b INTEGER NOT NULL, p CHAR(10) NOT NULL, q DATE NOT NULL);
+ INSERT INTO b(b, p, q) VALUES(3, 'daemonic', '2012-07-01');
+ SELECT * FROM a;
1|obsoletely|2012-04-01
2|absolutely|2012-06-01
+ SELECT * FROM b;
3|daemonic|2012-07-01
+ SELECT *
  FROM a, b
  WHERE a.a < b.b
    AND b.p MATCHES '*a*e*';
1|obsoletely|2012-04-01|3|daemonic|2012-07-01
2|absolutely|2012-06-01|3|daemonic|2012-07-01
+ UPDATE a
  SET x = 'crumpet'
  FROM a, b
  WHERE a.a < b.b
    AND b.p MATCHES '*a*e*';
SQL -201: A syntax error has occurred.
SQLSTATE: 42000 at <<temp>>:23
+ SELECT * FROM a;
1|obsoletely|2012-04-01
2|absolutely|2012-06-01
+ ROLLBACK;

для Informix SE 7.25...

  1. обновление ... ОТ... синтаксис не существует
  2. вы также " не можете изменить таблицу или представление, используемые в подзапросе" который дается при использовании Rockallite это

другим решением было бы разбить его на два запроса:

во-первых, получите ROWIDs для необходимых записей (отфильтрованных на нескольких таблицах):

SELECT a.ROWID
  FROM table1 a, table2 b, table3 c
 WHERE a.key = c.key
   AND a.no = b.no
   AND a.key = c.key
   AND a.code = 10
   AND b.tor = 'THE'
   AND a.group = 4183
   AND a.no IN ('1111','1331','1345')

поместите результат в запятую строка.

затем обновите только те записи для основной таблицы, где ROWID был найден в первом запросе:

UPDATE table1 a
   SET a.code = 100
WHERE a.ROWID in ([comma separated ROWIDs found above])

Это зависит от версии, которую вы используете. Если вы используете хотя бы 11.50, лучшим решением будет:

MERGE INTO table1 as t1
USING table2 as t2
   ON t1.ID = t2.ID
WHEN MATCHED THEN UPDATE set (t1.col1, t1.col2) = (t2.col1, t2.col2);

синтаксис UPDATE-SET-FROM-был удален в версиях, превышающих 11.50.

Если вы используете более раннюю версию, вы можете пойти с

UPDATE t SET a = t2.a FROM t, t2 WHERE t.b = t2.b;