Получение ошибки при присвоении одного значения из таблицы объявленной переменной в ORACLE PL/SQL

#sql #oracle #plsql #oracle11g #oracle10g

Вопрос:

Я пишу процедуру для Oracle DB 10g/11g, и мне нужно присвоить переменной определенное значение даты. Код приведен ниже.

 DECLARE 
    date_from DATE := NULL;
DECLARE 
    d_count NUMBER := 0;
BEGIN
    SELECT COUNT(*) INTO d_count FROM TABLE_X;

    IF d_count = 0 THEN
        SELECT MIN(TRX_DATE) INTO date_from FROM TABLE_Y;
    ELSE
        SELECT MAX(TRX_DATE) INTO date_from FROM TABLE_X;
    END IF;
END;
 

Когда я запускаю это, я получаю эту ошибку.

 Error starting at line : 1 in command -
DECLARE 
    date_from DATE := NULL;
DECLARE 
    d_count NUMBER := 0;
BEGIN
    SELECT COUNT(*) INTO d_count FROM TABLE_X;

    IF d_count = 0 THEN
        SELECT MIN(TRX_DATE) INTO date_from FROM TABLE_Y;
    ELSE
        SELECT MAX(TRX_DATE) INTO date_from FROM TABLE_X;
    END IF;
END;
Error report -
ORA-06550: line 3, column 1:
PLS-00103: Encountered the symbol "DECLARE" when expecting one of the following:

    begin function pragma procedure subtype type <and identifier>
    <a double-quoted delimited-identifier> current cursor delete
    exist prior
The symbol "begin" was substituted for "DECLARE" to continue.
ORA-06550: line 13, column 4:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
    
    ( begin case declare and exception exit for goto if loop mod
    null pragma raise return select update while with
    <an identifier><a double-quoted
06550. 00000 - "line %s, column %s:n%s"
*Cause: Usuallz a PL/SQL compilation error.
*Action:
 

У меня есть опыт работы с T-SQL, однако я очень новичок в PL/SQL в OracleDB.
Заранее спасибо.

Комментарии:

1. И на что вы можете посмотреть line 3, column 1 ? Правильно, еще declare одно ключевое слово, которого там не должно быть. Пожалуйста, ознакомьтесь с документацией о синтаксисе, она не требует никаких вопросов.

2. Спасибо, мне следует быть более осторожным, и спасибо, что поделились документацией. Я только начал использовать Oracle DB с задачей, обычно мне нравится читать документацию, прежде чем начинать что-то новое.

Ответ №1:

Вы использовали дополнительное объявление. Это должно быть нормально:

 DECLARE 
    date_from DATE := NULL; 
    d_count NUMBER := 0;
BEGIN
    SELECT COUNT(*) INTO d_count FROM TABLE_X;

    IF d_count = 0 THEN
        SELECT MIN(TRX_DATE) INTO date_from FROM TABLE_Y;
    ELSE
        SELECT MAX(TRX_DATE) INTO date_from FROM TABLE_X;
    END IF;
END;
 

Базовый шаблон для сценариев:

 declare 
  -- Local variables here
  i integer;
begin
  --  statements here
end;
 

Базовый шаблон для процедур:

 procedure TEST(Name in out type, Name in out type, ...) is
begin
  
end TEST;
 

Комментарии:

1. Спасибо за ваш ответ. Несмотря на то, что мой вопрос был немного глупым, ваш ответ и шаблоны хороши для меня, чтобы понять структуру сценариев и процедур.

2. да, это очень похоже на TSQL . Если у вас есть возможность использовать среду разработки PL/SQL, в ней есть действительно хороший раздел готовых шаблонов , который вы можете использовать, это также может повысить вашу скорость. просто совет. я желаю вам всего наилучшего в вашей новой области 🙂

3. @nedensel в любом случае было бы неплохо проверить документацию. Каждая инструкция SQL в нем содержит множество примеров, демонстрирующих базовый синтаксис, различное использование элементов синтаксиса, различия в производительности. Например, блок PL/SQL

4. @Али Фиданли, я проверю это, еще раз спасибо. Я тоже немного поторопился, не проверив все должным образом 🙂

5. @astentx Я просто использовал привычки T-SQL, не читая сначала документацию. Тем не менее, я обязательно прочитаю, чтобы предотвратить такого рода синтаксические ошибки.

Ответ №2:

В вашем случае достаточно только одного DECLARE .

Кроме того (хотя и не ошибка),

  • переменная, которая объявлена NULL по умолчанию; вам не нужно ее указывать (это DATE_FROM )
  • d_count используется для принятия результата count функции; если ничего не найдено table_x , счетчик будет 0 в любом случае, так что вам также не нужно указывать d_count начальное значение

Так:

 DECLARE
   date_from  DATE;
   d_count    NUMBER;
BEGIN
   SELECT COUNT (*) INTO d_count FROM TABLE_X;

   IF d_count = 0 THEN
      SELECT MIN(TRX_DATE) INTO date_from FROM TABLE_Y;
   ELSE
      SELECT MAX(TRX_DATE) INTO date_from FROM TABLE_X;
   END IF;
END;
 

Комментарии:

1. Примечание: SELECT MAX(TRX_DATE) INTO date_from FROM TABLE_X; можно избежать, если вы добавите max(trx_date) к первому утверждению.