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 предоставил расширение к стандарту.