Нужна помощь в запуске этого оператора MS SQL Server на Informix - PullRequest
1 голос
/ 10 февраля 2011

Мне нужна помощь в выполнении этого оператора UPDATE для MS SQL Server в Informix (версия 11):

update b  
set Colname = 'StringValue'
from Table1 b right join Table1 c 
on ((b.Col1 = c.Col1) and (b.Col2 = c.Col2)) 
where ((b.Col3 = 'S' and b.Col4 <> 'S') and (c.Col3 = 'Z' and c.Col4 <> 'S'))

Я получаю номер ошибки -201 (синтаксическая ошибка).

Можете ли вы увидеть синтаксическую ошибку? Есть идеи?

1 Ответ

1 голос
/ 10 февраля 2011

Какую версию Informix вы используете?

На самом деле, я не думаю, что это имеет значение ... IDS не поддерживает нотации объединения в операторе UPDATE , даже в последней версии. Итак, проблема в том, что вы пытаетесь использовать нотацию, которая не поддерживается СУБД, и, следовательно, вы получаете раздражающий (но в данном случае точный) универсальный «-201: Произошла синтаксическая ошибка». Я не думаю, что даже IDS 11.70.xC1, последняя версия GA, также поддерживает псевдонимы таблиц в операторе UPDATE (что усложняет запрос).

Признаюсь, что ПРАВИЛЬНОЕ СОЕДИНЕНИЕ ошеломило меня - я не уверен, что понимаю, как это должно работать. Тем не менее, вот умеренное приближение к запрашиваемому обновлению:

UPDATE Table1
   SET Colname = 'StringValue'
 WHERE Table1.Col3 = 'S'
   AND Table1.Col4 <> 'S'
   AND EXISTS(SELECT * FROM Table1 AS C
               WHERE C.Col1 = Table1.Col1 AND C.Col2 = Table1.Col2
                 AND C.Col3 = 'Z'
                 AND C.Col4 <> 'S'
             )

Ноющие сомнения двояки:

  • Правильно ли IDS устранит неоднозначность ссылок на Таблицу 1 в подзапросе EXISTS?
  • Что означает это ПРАВОЕ СОЕДИНЕНИЕ?

К сожалению, когда запрос выполняется, я получаю обратно:

SQL -360: Cannot modify table or view used in subquery.

Есть обходные пути для этого, использующие временные таблицы, но они неприятны. Однако этот пример кода, кажется, работает в соответствии с моими ожиданиями (учитывая, что я все еще не могу сосредоточиться на том, что RIGHT JOIN делает в оригинале).

CREATE TABLE table1
(
    col1    INTEGER NOT NULL,
    col2    INTEGER NOT NULL,
    col3    CHAR(1) NOT NULL,
    col4    CHAR(1) NOT NULL,
    colname VARCHAR(32) NOT NULL
);

-- The first row shown is updated - the others are unchanged
INSERT INTO table1 VALUES(1, 1, 'S', 'A', 'Old value'); 
INSERT INTO table1 VALUES(1, 1, 'Z', 'A', 'Old value'); 
INSERT INTO table1 VALUES(1, 2, 'S', 'A', 'Old value'); 
INSERT INTO table1 VALUES(1, 2, 'Z', 'S', 'Old value'); 
INSERT INTO table1 VALUES(1, 3, 'S', 'S', 'Old value'); 
INSERT INTO table1 VALUES(1, 3, 'Z', 'S', 'Old value'); 
INSERT INTO table1 VALUES(1, 4, 'S', 'S', 'Old value'); 
INSERT INTO table1 VALUES(1, 4, 'Z', 'A', 'Old value');     

SELECT * FROM Table1 WHERE Col3 = 'Z' AND Col4 <> 'S' INTO TEMP C;

UPDATE Table1
   SET Colname = 'StringValue'
 WHERE Table1.Col3 = 'S'
   AND Table1.Col4 <> 'S'
   AND EXISTS(SELECT * FROM {Table1 AS} C
               WHERE C.Col1 = Table1.Col1 AND C.Col2 = Table1.Col2
                 AND C.Col3 = 'Z'
                 AND C.Col4 <> 'S'
             );

Фрагмент '{Table1 AS}' - это комментарий в Informix. Условия для Col3 и Col4 не являются строго необходимыми из-за способа создания временной таблицы C.

Результаты, полученные от SELECT * FROM Table1 ORDER BY Col1, Col2, Col3, Col4 до и после оператора UPDATE:

Before
1   1   S   A   Old value
1   1   Z   A   Old value
1   2   S   A   Old value
1   2   Z   S   Old value
1   3   S   S   Old value
1   3   Z   S   Old value
1   4   S   S   Old value
1   4   Z   A   Old value

After
1   1   S   A   StringValue
1   1   Z   A   Old value
1   2   S   A   Old value
1   2   Z   S   Old value
1   3   S   S   Old value
1   3   Z   S   Old value
1   4   S   S   Old value
1   4   Z   A   Old value
...