Я действительно новичок в Oracle PL/SQL, но опытный в Sql Server, и я пытаюсь изучить все это. Для вводного я решил оптимизировать запрос, который генерируется как строка C#, а затем выполняется как текст SqlCommand. Поэтому я пытаюсь создать сохраненный процесс, но для включения всех вариантов того, как может быть создано предложение where, оно запустило его на 40 секунд, а сгенерированная строка C# - через 3 секунды. Вот пример того, что я имею в виду вариаций где п ...PL SQL - динамический SQL в предложении where оператора select
declare
searchType nvarchar2(3); -- options are 'x', 'y', 'z'
searchDesc nvarchar2(4); -- options are '1', '2', '3'
searchValue nvarchar2(5);
begin
select count(*)
from tbl_A a
where ((searchType = 'x'
and ((a.desc_X = searchDesc and a.value_1 = searchValue)
or (a.desc_X = searchDesc and a.value_2 = searchValue)
or (a.desc_X = searchDesc and a.value_3 = searchValue)
)
)
or (searchType = 'y'
and ((a.desc_Y = searchDesc and a.value_1 = searchValue)
or (a.desc_Y = searchDesc and a.value_2 = searchValue)
or (a.desc_Y = searchDesc and a.value_3 = searchValue)
)
)
or (searchType = 'z'
and ((a.desc_Z = searchDesc and a.value_1 = searchValue)
or (a.desc_Z = searchDesc and a.value_2 = searchValue)
or (a.desc_Z = searchDesc and a.value_3 = searchValue)
)
)
)
end;
Так что мне интересно, можно ли иметь оператор выбора, который может выполнить динамический SQL в ИНЕКЕ. Или весь оператор должен быть динамическим sql. Ниже приведен пример того, что я под сомнение ...
declare
whereClause varchar2(500);
searchType nvarchar2(3); -- options are 'x', 'y', 'z'
searchDesc nvarchar2(4); -- options are '1', '2', '3'
searchValue nvarchar2(5);
begin
select case
when searchType = 'x' then 'a.desc_X = :desc and a.value_1 = :val'
when searchType = 'y' then 'a.desc_Y = :desc and a.value_2 = :val'
when searchType = 'z' then 'a.desc_Z = :desc and a.value_3 = :val'
end
into whereClause
from dual;
select count(*)
from tbl_A a
where (
execute immediately whereClause using searchDesc, searchValue
)
end;
Когда я попытался запустить его, как и все динамического SQL, все еще потребовалось ~ 15 секунд, чтобы выполнить. Поэтому, если у кого-то есть лучший способ справиться со многими вариантами предложения, я открыт для предложений.
Что касается вашего вопроса «все ли заявление должно быть динамическим sql», то да. Основываясь на первом примере процедуры и разнице во времени между C# -генерированной версией и proc, я предполагаю, что предложение WHERE в версии proc убивает любые шансы на оптимизацию - возможно, версия C# имеет гораздо более целенаправленную ' WHERE'. Вы можете попробовать дублировать логику C# в процедуре и выполнить «EXECUTE IMMEDIATE» в результирующей строке, но я сомневаюсь, что это даст вам большой импульс. Это может быть случай, когда вам нужно искать оптимизацию в другом месте. –