INSERT SELECT не работает

Используя Informix 11.7, я пытаюсь выполнить запрос INSERT SELECT с позиционными параметрами jdbc в операторе select следующим образом:

INSERT INTO table1(id, code, label) 
SELECT ?, ?, ? FROM table2
WHERE ...

Параметры устанавливаются так:

 stmt.setString(1, "auniqueid");
 stmt.setString(2, "code");
 stmt.setString(3, "coollabel");

Я получаю следующую ошибку:

Исключение в потоке "main" java.sql.SQLException: произошла синтаксическая ошибка.

Когда позиционные параметры "?" размещены в другом месте, он работает нормально. У меня нет этой проблемы с использованием PostgreSQL. Что не так с моим запросом? Я использую Informix JDBC Driver v3.70 JC1.

Спасибо за вашу помощь.

2 ответа

Решение

Предупреждение: у меня нет опыта работы с Informix, ответ основан на общих наблюдениях

При указании параметров база данных должна знать тип каждого параметра. Если параметр присутствует в списке выбора, то у базы данных нет возможности определить тип параметра. Некоторая база данных может быть в состоянии отложить это решение до фактического получения параметров, но большинству баз данных потребуется знать это во время анализа. Это, вероятно, причина, по которой вы получаете ошибку.

Некоторые базы данных - я не знаю, относится ли это к Informix - позволяют вам приводить параметры. Так, например:

SELECT CAST(? AS VARCHAR(20)), CAST(? AS VARCHAR(10)), CAST(? AS VARCHAR(5)) FROM ...

В этом случае база данных сможет вывести типы параметров и сможет правильно проанализировать запрос.

При этом я предполагаю, что вы не пытаетесь указать имена столбцов для списка выбора с помощью параметров, поскольку это невозможно.

Вы ожидаете получить имена столбцов, указанные через заполнители? Если это так, вы прячетесь ни к чему; Вы не можете использовать заполнители для структурных элементов запроса, таких как имена столбцов или таблиц. Они могут только заменить значения. Если вы хотите, чтобы динамический SQL определял столбцы, используйте динамический SQL; создать строку с содержанием:

INSERT INTO table1(id, code, label)
    SELECT auniqueid, code, coollabel
      FROM table2
     WHERE ...

и работать с этим.

Если эти заполнители будут значениями, то вы будете вставлять одни и те же значения снова и снова, по одному разу для каждой строки, возвращаемой запросом, и обычно это не то, что вам нужно; Вы просто вставили бы одну строку с предложением VALUES, где разрешены заполнители:

INSERT INTO table1(id, code, label) VALUES(?, ?, ?);

Это будет работать нормально.

AFAIK, это поведение соответствует стандарту SQL. Если в PostgreSQL все работает иначе, PostgreSQL предоставил расширение к стандарту.

Другие вопросы по тегам