#sql #oracle #plsql #dynamic-sql #ora-00904
#sql #Oracle #plsql #dynamic-sql #ora-00904
Вопрос:
я хочу иметь возможность выполнить мой приведенный ниже процесс следующим образом:
exec procname('29-JAN-2011');
код процедуры является:
PROCEDURE procname(pardate VARCHAR2) IS
vardate DATE := to_date(pardate, 'DD-MON-YYYY');
SQLS VARCHAR2(4000);
BEGIN
SQLS := 'SELECT cola, colb
FROM tablea
WHERE TRUNC(coldate) = TRUNC(TO_DATE('''||pardate||''',''DD/MON/YYYY''))';
EXECUTE IMMEDIATE SQLS;
END;
Он продолжает выдавать ошибку:
ORA-00904: «JAN»: недопустимый идентификатор.
Он компилируется, но выдает ошибку при запуске этой команды:
EXEC procname('29-JAN-2011');
Комментарии:
1. Это не настоящий код, верно? Он не будет компилироваться.
2. Я знаю, что это всего лишь пример, но должна ли эта процедура быть динамическим SQL? Это отлично работало бы как обычная процедура.
3. это должно быть динамическим, потому что я собираюсь сделать так, чтобы имена столбцов были неизвестны во время выполнения
Ответ №1:
Вы объявляете переменную, которая преобразует входной параметр в дату: почему бы не использовать ее?
Кроме того, функция TRUNC(), применяемая к дате, удаляет элемент time. Вам это здесь не нужно, потому что передаваемое вами значение не имеет времени.
Итак, ваш код должен быть:
PROCEDURE procname(pardate VARCHAR2) IS
vardate DATE := to_date(pardate, 'DD-MON-YYYY');
SQLS VARCHAR2(4000) := 'select cola, colb FROM tablea
WHERE TRUNC(coldate) = :1';
l_a tablea.cola%type;
l_b tablea.colb%type;
BEGIN
EXECUTE IMMEDIATE SQLS
into l_a, l_b
using vardate;
END;
Указание динамического оператора SQL с помощью переменной bind и выполнение его с использованием синтаксиса USING намного эффективнее. Обратите внимание, что нам все еще нужно выбрать в некоторых переменных.
Комментарии:
1. В качестве дополнительного примечания, этот trunc () может избежать использования индекса вместо coldate . Он может подумать о хитрости «… где coldate между:1 и:2 0.99999» с использованием vardate, vardate .
Ответ №2:
Вы используете две разные нотации в двух вызовах to_date
. Я думаю, что один из них (второй) неверен.
Комментарии:
1. Я имею в виду, что один из них — DD-MON-ГГГГ, а другой — DD / MON / ГГГГ. При вводе используются тире, а не косые черты, поэтому я думаю, что второе неверно.
2. Также может быть проблема с настройкой языка. Вы живете в стране, где январь не сокращается до января?