Использование переменной даты SQL с TOAD

Я хочу использовать переменную в TOAD для оператора WITH-SQL, потому что сегодняшняя дата используется несколько раз.

Я пробовал с переменной, DEFINE и Declare для настройки переменной, но это еще не сработало.

Скрипт должен выглядеть примерно так:

DECLARE TODAY date := SYSDATE();

BEGIN
WITH

SUBQUERY1 AS (
SELECT *
FROM TABLE
WHERE TABLE.DATE = &TODAY
),

SUBQUERY2 AS (
SELECT *
FROM TABLE2
WHERE TABLE2.DATE = &TODAY
),

SELECT *
FROM TABLE3 
JOIN SUBQUERY1 ON TABLE3.PRIMARYKEY = SUBQUERY1.PRIMARYKEY
JOIN SUBQUERY2 ON TABLE3.PRIMARYKEY = SUBQUERY2.PRIMARYKEY

END;

Во время исследования я кое-что прочитал об операторе into, но я думаю, что он используется, когда вы хотите определить вывод запроса к переменной? Может быть, кто-то может также предоставить мне полезную статью или что-то в этом роде.

Совет: посчитайте ( и ). Такое же количество?

jarlh 03.04.2023 20:52

Не мой вопрос... но спасибо, что обратили мое внимание на это. Я отредактировал пример.

Hisager 04.04.2023 09:27
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
2
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Не используйте PL/SQL, просто используйте запрос (и убедитесь, что у вас есть закрывающие скобки для предложений факторинга подзапроса и запятая между ними):

WITH dates (dt) AS (
  SELECT SYSDATE
  FROM   DUAL
),
SUBQUERY1 AS (
  SELECT t.*
  FROM   TABLE t
         INNER JOIN dates d
         ON (t.DATE = d.dt)
),
SUBQUERY2 AS (
  SELECT t2.*
  FROM   TABLE2 t2
         INNER JOIN dates d
         ON (t2.DATE = d.dt)
)
SELECT *
FROM   TABLE3 
       JOIN SUBQUERY1 ON TABLE3.PRIMARYKEY = SUBQUERY1.PRIMARYKEY
       JOIN SUBQUERY2 ON TABLE3.PRIMARYKEY = SUBQUERY2.PRIMARYKEY

Примечание. Вам не нужна переменная для даты.

В Oracle DATE всегда имеет компоненты даты и времени (даже если клиентское приложение не всегда их показывает). Если вам нужны результаты за весь день (а не за текущий момент), используйте:

WITH dates (dt) AS (
  SELECT TRUNC(SYSDATE)
  FROM   DUAL
),
SUBQUERY1 AS (
  SELECT t.*
  FROM   TABLE t
         INNER JOIN dates d
         ON (   t.DATE >= dt
            AND t.DATE <  dt + INTERVAL '1' DAY)
),
SUBQUERY2 AS (
  SELECT t2.*
  FROM   TABLE2 t2
         INNER JOIN dates d
         ON (   t2.DATE >= dt
            AND t2.DATE <  dt + INTERVAL '1' DAY)
)
SELECT *
FROM   TABLE3 
       JOIN SUBQUERY1 ON TABLE3.PRIMARYKEY = SUBQUERY1.PRIMARYKEY
       JOIN SUBQUERY2 ON TABLE3.PRIMARYKEY = SUBQUERY2.PRIMARYKEY

Я бы избавился от PL/SQL, но мне нужна переменная. Мой пример кода укорочен, и должна быть возможность вручную настроить дату на что-то еще, чем сегодня. Я также просто использую TRUNC(TABLE.DATE) = TO_DATE('04.04.2023', 'DD.MM.YYYY')

Hisager 04.04.2023 09:23

@Hisager Обновлено, определите дату в предложении факторинга подзапроса перед двумя вашими подзапросами.

MT0 04.04.2023 09:31

Это тоже полезная идея. Спасибо!

Hisager 04.04.2023 09:54

Нет никакого улучшения в том, что ты сделал, совсем нет. Какую пользу вы видите в использовании today в своем коде вместо sysdate? Печатать 5 букв вместо 7?

В любом случае:

  • опустите &, вы не используете здесь переменные подстановки
  • убедитесь, что открывающая и закрывающая скобки совпадают
  • select в PL/SQL требуется into, поэтому вы должны сначала объявить его
  • остерегайтесь различных исключений, таких как no_data_found и too_many_rows

Что-то вроде этого:

DECLARE 
  TODAY date := SYSDATE();
  l_tab3_row table3%rowtype;
BEGIN
  WITH
  SUBQUERY1 AS (
  SELECT *
  FROM TABLE
  WHERE TABLE.DATE = TODAY
  ),
  SUBQUERY2 AS (
  SELECT *
  FROM TABLE2
  WHERE TABLE2.DATE = TODAY
  )
  SELECT *
  INTO l_tab3_row        --> this
  FROM TABLE3 
  JOIN SUBQUERY1 ON TABLE3.PRIMARYKEY = SUBQUERY1.PRIMARYKEY
  JOIN SUBQUERY2 ON TABLE3.PRIMARYKEY = SUBQUERY2.PRIMARYKEY;
EXCEPTION
  WHEN NO_DATA_FOUND OR TOO_MANY_ROWS THEN 
    NULL;
  WHEN OTHERS THEN
    RAISE;
END;

Судя по вашему комментарию, вам может понадобиться переменная связывания. Он «объявлен» непосредственно в коде, и перед его именем стоит двоеточие. Вот пример:


По ошибке вы получили:

ORA-16000: база данных открыта только для чтения

Причина. База данных открыта только для чтения. Эта ошибка возникает при попытках изменить базу данных с помощью неподходящих операторов DML или DDL.

Действие: Чтобы изменить базу данных, ее необходимо сначала закрыть и снова открыть для чтения и записи.

Да, в моем реальном коде есть все скобки и запятые. Дело в переменной, потому что у меня около 9 подзапросов, и также должна быть возможность вручную изменить дату на что-то другое, чем сегодня.

Hisager 04.04.2023 09:14

Моя проблема заключается в том, что я не понимаю PL/SQL и декларацию в части. Но если я реализую это, как вы, я получаю это сообщение об ошибке: ORA-16000: база данных или подключаемая база данных открыта для доступа только для чтения.

Hisager 04.04.2023 09:18

Я добавил пример, который показывает, что вы можете попытаться сделать.

Littlefoot 04.04.2023 09:23

Спасибо. У меня нет права что-то менять на уровне базы данных. Но переменная связывания действительно полезна. В настоящее время не планируется планировать sql, но если это так, я думаю, что переменная связывания больше не будет работать...

Hisager 04.04.2023 09:52

Другие вопросы по теме