Определение дня недели для даты заказа в PL / SQL как хранимой функции - PullRequest
1 голос
/ 11 марта 2019

Код:

CREATE OR REPLACE FUNCTION DAY_ORD_SF 
(
  P_DATE_CREATED IN bb_basket.dtcreated%type 
)
RETURN DATE AS
    lv_date_created bb_basket.dtcreated%type;
BEGIN
    SELECT to_char(to_date(P_DATE_CREATED,'yyyy-mm-dd'),'DAY') DAY_CREATED
        INTO lv_date_created
    FROM BB_BASKET
    WHERE lv_date_created <= sysdate
    ORDER BY lv_date_created ASC;
RETURN lv_date_created;
END DAY_ORD_SF;
/

SELECT IDBASKET, dtcreated date_created, to_char(DTCREATED,'DAY') DAY_CREATED, day_ord_sf(dtcreated) weekday_created
FROM BB_BASKET
order by DTCREATED asc;

Это моя сохраненная функция, над которой я работаю в качестве задания для отработки хранимой функции. Я действительно близок к решению этой проблемы, но я получаю сообщение об отсутствии данных. Я не совсем понимаю эту ошибку, потому что когда я запускаю код сам по себе, он работает. В основном эта функция предполагает получение даты и возвращает тип данных varchar2. У меня действительно было "to_date (..., 'yyyy-mm-dd'), .." перед добавлением этого куска кода в функцию. Первая часть этой задачи - создать инструкцию SELECT, в которой перечислены идентификатор корзины и день недели для каждой корзины, а вторая часть задачи - создать инструкцию SELECT, используя предложение GROUP BY для отображения общего количества корзин за день недели. , По результатам какой день покупок самый популярный? Кроме того, я забыл спросить, можете ли вы сказать мне, почему я получаю сообщение об ошибке «Данные не найдены», которое будет высоко ценится!

Спасибо за помощь!

1 Ответ

0 голосов
/ 11 марта 2019

Ну, тут, похоже, много проблем.

Давайте начнем без проблем с данными.Если вы используете INTO в select statment и select не возвращает строк, вы получите исключение «no data found».Это может быть обработано с помощью блока anonymouse begin end с обработчиком исключений внутри, но я считаю, что это не так.Как пример:

declare
  v_value number;
begin
  select null
    into v_value
    from dual
   where 1=2; 
exception 
  when NO_DATA_FOUND then
    null; -- Ignore exception and continue
end;

Условие 1 = 2 никогда не выполняется, и поэтому выборка всегда не возвращает строк, это всегда приводит к ошибке «Обнаруженные данные».С обработчиком исключений мы решаем, что делать дальше.В этом примере Null ничего не сделает.

Возвращаясь к вашей функции, ваше условие, если переменная lv_date_created меньше или равна текущей дате, тогда что-то сделать.Это никогда не сработает, поскольку lv_date_created будет в момент выполнения равным нулю.Он был объявлен в вашей функции, а затем использован в вашем выборе.Это всегда приводит к значению false, и поэтому select всегда будет возвращать не строки и исключение для найденных данных.

Вы также упоминали, что хотите, чтобы функция возвращала varchar2, но в вашем определении говорится, что она возвращает дату.Также переменная lv_date_created имеет тип date, и это переменная, которая возвращается, и вы заполняете ее значением varchar2, так что, очевидно, Oracle выполняет некоторое неконтролируемое преобразование значения, это не вызывает исключения относительно ожидаемых типов данных.

Такжеусловие lv_date_created <= sysdate может указывать на то, что select найдет множественные значения, а с INTO это вызовет исключение слишком большого числа строк, если найдены множественные строки. </p>

Теперь давайте приступим к исправлению этой функции.Главный вопрос - нужно ли что-то выбирать в этом или нет.Выбор чего-то подобного обычно используется, чтобы проверить, существует ли запись в таблице, и никакие найденные данные исключений не скажут нам, что запись не существует.Если это общая функция, которая будет использоваться в нескольких местах в вашей БД, тогда я думаю, что select не нужен.Я включу оба решения в качестве примера.

Обратите внимание, что для этого первого вы больше не должны создавать dtcreated colume при вызове, кроме idbasket.

CREATE OR REPLACE FUNCTION DAY_ORD_SF 
(
  P_IDBASKET IN bb_basket.idbasket%type 
)
RETURN VARCHAR2 AS
    lv_date_created VARCHAR2(240);
BEGIN
    SELECT to_char(dtcreated,'DAY') DAY_CREATED
        INTO lv_date_created
    FROM BB_BASKET
    WHERE IDBASKET = P_IDBASKET;
RETURN lv_date_created;
END DAY_ORD_SF;
/

Или

CREATE OR REPLACE FUNCTION DAY_ORD_SF 
(
  P_DATE_CREATED IN bb_basket.dtcreated%type 
)
RETURN VARCHAR2 AS
BEGIN
RETURN to_char(P_DATE_CREATED,'DAY');
END DAY_ORD_SF;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...