У меня есть функция Oracle 18c PL/SQL, которую я могу использовать для поиска значений задачи в определяемом пользователем пространственном типе под названием SDE.ST_GEOMETRY.
Найдите строку с проблемной формой (пространственный тип SDE.ST_GEOMETRY)
with function check_shape(anno_shape sde.st_geometry, boundary_shape sde.st_geometry) return varchar2
is
v_test_result varchar2(10); --<--look here
begin
select
sde.st_intersects (boundary_shape, anno_shape)
into --<--look here
v_test_result --<--look here
from
dual;
return 'no error';
exception
when others then
return 'error';
end;
select
anno.objectid,
anno.shape as anno_shape,
check_shape(anno.shape, boundary.shape) as check_shape
from
city.boundary boundary
cross join
infrastr.gcsm_hc_anno anno
where
check_shape(anno.shape, boundary.shape) = 'error'
Я собрал эту функцию из примеров онлайн-скриптов, и она работает так, как ожидалось. С учетом вышесказанного я хочу, чтобы код был максимально простым и правильным.
Моему неопытному глазу into
и v_test_result
кажутся ненужными; они, кажется, ничего не делают. Функция выбирает значение в переменной, но переменная, похоже, не используется return
.
Моя интуиция состоит в том, чтобы удалить эти строки:
v_test_result varchar2(10);
...
into
v_test_result
Но когда я удаляю эти строки, я получаю сообщение об ошибке:
with function check_shape(anno_shape sde.st_geometry, boundary_shape sde.st_geometry) return varchar2
is
-- v_test_result varchar2(10); --<--look here
begin
select
sde.st_intersects (boundary_shape, anno_shape)
-- into --<--look here
-- v_test_result --<--look here
from
dual;
return 'no error';
exception
when others then
return 'error';
end;
select
anno.objectid,
anno.shape as anno_shape,
check_shape(anno.shape, boundary.shape) as check_shape
from
city.boundary boundary
cross join
infrastr.gcsm_hc_anno anno
where
check_shape(anno.shape, boundary.shape) = 'error'
ORA-06553: PLS-428: an INTO clause is expected in this SELECT statement
06553. 00000 - "PLS-%s: %s"
Зачем нужен into
в этой функции? Есть ли способ упростить функцию, удалив ее?
Зачем нужен
into
в этой функции?
Потому что язык PL/SQL требует, чтобы оператор SELECT
всегда содержал либо предложение INTO
, либо предложение BULK COLLECT INTO
.
В Справочнике по языку баз данных PL/SQL синтаксис оператора SELECT
следующий:
select_into_statement ::=
Из чего видно, что предложение INTO
или BULK COLLECT INTO
является обязательным.
Если у вас нет ни одного из этих предложений, ваш код синтаксически недействителен и будет возбуждено исключение.
Есть ли способ упростить функцию, удалив ее?
Если вы выполняете запрос в области PL/SQL, нет, его нельзя удалить.
Единственный способ не использовать оператор INTO
(или BULK COLLECT INTO
) — это выполнить SELECT
в области SQL, что потребует использования чего-то вроде EXECUTE IMMEDIATE
:
WITH function check_shape(
anno_shape infrastr.gcsm_hc_anno.shape%TYPE,
boundary_shape city.boundary.shape%TYPE
) return varchar2
is
begin
EXECUTE IMMEDIATE 'select sde.st_intersects (:1, :2) from dual'
USING boundary_shape, anno_shape;
RETURN 'no error';
EXCEPTION
WHEN OTHERS THEN
RETURN 'error';
END;
select anno.objectid,
anno.shape as anno_shape,
check_shape(anno.shape, boundary.shape) as check_shape
from city.boundary boundary
inner join infrastr.gcsm_hc_anno anno
on check_shape(anno.shape, boundary.shape) = 'error';
PL/SQL select
требуется предложение into
, но вы можете встроить запрос через loop
:
with function check_shape(anno_shape sde.st_geometry, boundary_shape sde.st_geometry) return varchar2
is
begin
for x in (select sde.st_intersects (boundary_shape, anno_shape) from dual) loop
return 'no error';
end if;
exception
when others then
return 'error';
end;
В PL/SQL не может быть оператора
select
, который не преобразует выходные данные во что-либо. Это настолько просто, насколько это возможно.