Я попытался запустить динамически сгенерированный SQL-запрос в PHP, нацеленный на базу данных Sybase SQL-Anywhere, и получил следующую ошибку:
Warning: sybase_query(): message: SQL Anywhere Error -680: Invalid expression in WHERE clause of Transact-SQL outer join (severity 16) in /path/to/file.php
Строка запроса SQL:
SELECT DISTINCT v_InventoryMaster.INV_ScanCode, v_InventoryMaster.INV_ReceiptAlias
FROM ecrs.v_InventoryMaster
WHERE ( v_InventoryMaster.INV_PK NOT IN (
SELECT DISTINCT v_InventoryMaster.INV_PK
FROM ecrs.v_InventoryMaster, ecrs.StockInventoryLinkDiscounts
WHERE v_InventoryMaster.INV_PK = StockInventoryLinkDiscounts.ILD_INV_FK
AND StockInventoryLinkDiscounts.ILD_DIS_FK = 6
)
OR v_InventoryMaster.INV_PK NOT IN (
SELECT DISTINCT v_InventoryMaster.INV_PK
FROM ecrs.v_InventoryMaster, ecrs.StockInventoryLinkDiscounts
WHERE v_InventoryMaster.INV_PK = StockInventoryLinkDiscounts.ILD_INV_FK
AND StockInventoryLinkDiscounts.ILD_DIS_FK = 14
)
OR v_InventoryMaster.INV_PK NOT IN (
SELECT DISTINCT v_InventoryMaster.INV_PK
FROM ecrs.v_InventoryMaster, ecrs.StockInventoryLinkDiscounts
WHERE v_InventoryMaster.INV_PK = StockInventoryLinkDiscounts.ILD_INV_FK
AND StockInventoryLinkDiscounts.ILD_DIS_FK = 25
)
-- more OR clause subqueries with different ILD_DIS_FK values
)
ORDER BY v_InventoryMaster.INV_ScanCode
Я не совсем новичок в SQL или взаимодействии с базой данных, но это сообщение поставило меня в тупик. Он утверждает, что в предложении WHERE
есть недопустимое выражение, но я не вижу, как неправильно структурирован запрос. Я предполагаю, что ошибка связана с OR
и объединением двух результатов поиска.
Кроме того, выполнение этих трех отдельных запросов и объединение результатов (в Excel) возвращает правильный набор результатов:
Запрос А:
SELECT DISTINCT v_InventoryMaster.INV_ScanCode, v_InventoryMaster.INV_ReceiptAlias
FROM ecrs.v_InventoryMaster
WHERE ( v_InventoryMaster.INV_PK NOT IN (
SELECT DISTINCT v_InventoryMaster.INV_PK
FROM ecrs.v_InventoryMaster, ecrs.StockInventoryLinkDiscounts
WHERE v_InventoryMaster.INV_PK = StockInventoryLinkDiscounts.ILD_INV_FK
AND StockInventoryLinkDiscounts.ILD_DIS_FK = 6
)
ORDER BY v_InventoryMaster.INV_ScanCode
Запрос Б
SELECT DISTINCT v_InventoryMaster.INV_ScanCode, v_InventoryMaster.INV_ReceiptAlias
FROM ecrs.v_InventoryMaster
WHERE ( v_InventoryMaster.INV_PK NOT IN (
SELECT DISTINCT v_InventoryMaster.INV_PK
FROM ecrs.v_InventoryMaster, ecrs.StockInventoryLinkDiscounts
WHERE v_InventoryMaster.INV_PK = StockInventoryLinkDiscounts.ILD_INV_FK
AND StockInventoryLinkDiscounts.ILD_DIS_FK = 14
)
ORDER BY v_InventoryMaster.INV_ScanCode
Запрос C
SELECT DISTINCT v_InventoryMaster.INV_ScanCode, v_InventoryMaster.INV_ReceiptAlias
FROM ecrs.v_InventoryMaster
WHERE ( v_InventoryMaster.INV_PK NOT IN (
SELECT DISTINCT v_InventoryMaster.INV_PK
FROM ecrs.v_InventoryMaster, ecrs.StockInventoryLinkDiscounts
WHERE v_InventoryMaster.INV_PK = StockInventoryLinkDiscounts.ILD_INV_FK
AND StockInventoryLinkDiscounts.ILD_DIS_FK = 25
)
ORDER BY v_InventoryMaster.INV_ScanCode
Чтобы уточнить, какие результаты возврата я хочу:
В документации Sybase о error -680
говорится следующее:
Выражение в предложении WHERE запроса, использующего синтаксис Transact-SQL, содержит сравнение столбца из таблицы, предоставляющей NULL, с подзапросом или выражением, которое ссылается на столбец из другой таблицы.
Что неверно в исходном SQL-запросе?
Что означает документированное объяснение?
Как я могу отредактировать исходный SQL-запрос, чтобы получить желаемые результаты?
Обратите внимание, что, поскольку этот запрос был сгенерирован динамически, я хочу знать, как я могу изменить операторы между предложениями OR
:
Структура заявления:
v_InventoryMaster.INV_PK NOT IN (
SELECT DISTINCT v_InventoryMaster.INV_PK
FROM ecrs.v_InventoryMaster, ecrs.StockInventoryLinkDiscounts
WHERE v_InventoryMaster.INV_PK = StockInventoryLinkDiscounts.ILD_INV_FK
AND StockInventoryLinkDiscounts.ILD_DIS_FK = value -- value dynamically chosen by user
)
InventoryMaster
, которые не связаны с всеми предоставленными идентификаторами скидок (ILD_DIS_FK
), эквивалентнымиNOT(INV_PK IN (...ILD_DIS_FK=14) AND INV_PK IN (...ILD_DIS_FK=6) ...)
? - person pascal   schedule 04.01.2013InventoryMaster
, которые не связаны с каким-либо одним или несколькими предоставленными идентификаторами скидок (ILD_DIS_FK
). Отсюда иOR
заявления. - person recursion.ninja   schedule 13.01.2013IN
илиEXISTS
в лучшем случае избыточно указыватьDISTINCT
, в худшем случае движок будет тупо работать и фактически выполнит работу по устранению дубликатов. - person Damien_The_Unbeliever   schedule 13.01.2013-680
) и такое же сообщение об ошибке от dbisql. - person recursion.ninja   schedule 14.01.2013