Sql statement ignored ошибка

I’m doing tutorial from website http://www.plsqltutorial.com/plsql-procedure/. I have run the code on apex:

CREATE OR REPLACE PROCEDURE adjust_salary(
    in_employee IN EMPLOYEES.EMPLOYEE_ID%TYPE,
    in_percent IN NUMBER
) IS
BEGIN
    UPDATE EMPLOYEES
    SET salary = salary + salary * in_percent / 100
    WHERE employee_id = in_employee_id;
END;

but I got error:

Error at line 6: PL/SQL: SQL Statement ignored

4. ) IS
5. BEGIN
6.  UPDATE EMPLOYEES
7.  SET salary = salary + salary * in_percent / 100
8.  WHERE employee_id = in_employee_id;

I have checked and table employees is there. What is the problem and how to fix it?

ZygD's user avatar

ZygD

22.2k40 gold badges80 silver badges102 bronze badges

asked Jan 15, 2012 at 16:06

aretai's user avatar

WHERE employee_id = in_employee_id;

in_employee_id is not declared, neither is it a parameter. The function definition says the parameter is in_employee so your code block should be

CREATE OR REPLACE PROCEDURE adjust_salary(
    in_employee IN EMPLOYEES.EMPLOYEE_ID%TYPE,
    in_percent IN NUMBER
) IS
BEGIN
    UPDATE EMPLOYEES
    SET salary = salary + salary * in_percent / 100
    WHERE employee_id = in_employee;
END;

Looking at the article, I see that you’ve made a typo while creating the function, the function declaration as per the article is

 CREATE OR REPLACE PROCEDURE adjust_salary(
    in_employee_id IN EMPLOYEES.EMPLOYEE_ID%TYPE,

So, if you change your code to the above, no changes are required to the update statement.

answered Jan 15, 2012 at 16:14

Sathyajith Bhat's user avatar

Sathyajith BhatSathyajith Bhat

21.3k22 gold badges95 silver badges134 bronze badges

1

To avoid such typos, it is better to use Dot Notation (or namespaces) instead of the prefixes. In the context of a procedure, this is the name of the procedure.

Check out the following code:

create or replace procedure adjust_salary(
    employee_id hr.employees.employee_id%type, percent number) is
begin
    update hr.employees set 
        salary = salary + salary * percent / 100
    where employee_id = adjust_salary.employee_id;
end;
/
Procedure ADJUST_SALARY compiled

answered Oct 9, 2020 at 11:46

0xdb's user avatar

0xdb0xdb

3,5391 gold badge21 silver badges37 bronze badges

The parameter is in_employee but you’re using in_employee_id in your update. Change to:

CREATE OR REPLACE PROCEDURE adjust_salary(
    in_employee IN EMPLOYEES.EMPLOYEE_ID%TYPE,
    in_percent IN NUMBER
) IS
BEGIN
    UPDATE EMPLOYEES
    SET salary = salary + salary * in_percent / 100
    WHERE employee_id = in_employee;
END;

answered Jan 15, 2012 at 16:14

John Doyle's user avatar

John DoyleJohn Doyle

7,4855 gold badges33 silver badges40 bronze badges

The parameter name «in_employee» is different while you are using different variable name «in_employee_id» in the query

CREATE OR REPLACE PROCEDURE adjust_salary(
in_employee IN EMPLOYEES.EMPLOYEE_ID%TYPE,
in_percent IN NUMBER

) IS
BEGIN
UPDATE EMPLOYEES
SET salary = salary + salary * in_percent / 100
WHERE employee_id = in_employee;
END;

answered Aug 26, 2020 at 6:28

Sachin Patidar's user avatar

In my case (Oracle SQL Developer 19.2, Oracle version 12c), I just had to save the procedure and the error was gone.

E.g., enter some key, delete it (the procedure wasn’t changed, but now you can save it using Ctrl+s). After the save the error disappeared and I was able to run the procedure.

answered Jul 13, 2021 at 12:54

ZygD's user avatar

ZygDZygD

22.2k40 gold badges80 silver badges102 bronze badges

totn Oracle Error Messages


Learn the cause and how to resolve the ORA-06550 error message in Oracle.

Description

When you encounter an ORA-06550 error, the following error message will appear:

  • ORA-06550: line num, column num: str

Cause

You tried to execute an invalid block of PLSQL code (like a stored procedure or function), but a compilation error occurred.

Resolution

The option(s) to resolve this Oracle error are:

Option #1

Refer to the line and column numbers (in the error message) to find the compilation error and correct it. Then try recompiling your code.

Let’s look at an example of how to resolve an ORA-06550 error. For example, if you created a procedure called TestProc as follows:

SQL> CREATE OR REPLACE PROCEDURE TestProc
  2  AS
  3    vnum number;
  4  BEGIN
  5    vnum := vAnotherNum;
  6  END;
  7  /

Warning: Procedure created with compilation errors.

This procedure was created with compilation errors. So if we try to execute this procedure, we will get an ORA-06550 error as follows:

SQL> execute TestProc();
BEGIN TestProc(); END;

*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object EXAMPLE.TESTPROC is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

You can run the SHOW ERROR command to view the errors as follows:

SQL> show error procedure TestProc;
Errors for PROCEDURE TESTPROC:

LINE/COL ERROR
-------- -----------------------------------------------------------------
5/1	 PL/SQL: Statement ignored
5/9	 PLS-00201: identifier 'VANOTHERNUM' must be declared

As you can see, the error is caused by the variable called VANOTHERNUM not being declared. To resolve this error, we can modify our TestProc procedure to declare the variable as follows:

SQL> CREATE OR REPLACE PROCEDURE TestProc
  2  AS
  3    vnum number;
  4    vAnotherNumber number;
  5  BEGIN
  6    vAnotherNum := 999;
  7    vnum := vAnotherNum;
  8  END;
  9  /

Procedure created.

And now when we execute our TestProc procedure, the ORA-06550 error has been resolved.

SQL> execute TestProc();

PL/SQL procedure successfully completed.

totn Oracle Error Messages


Learn the cause and how to resolve the ORA-06550 error message in Oracle.

Description

When you encounter an ORA-06550 error, the following error message will appear:

  • ORA-06550: line num, column num: str

Cause

You tried to execute an invalid block of PLSQL code (like a stored procedure or function), but a compilation error occurred.

Resolution

The option(s) to resolve this Oracle error are:

Option #1

Refer to the line and column numbers (in the error message) to find the compilation error and correct it. Then try recompiling your code.

Let’s look at an example of how to resolve an ORA-06550 error. For example, if you created a procedure called TestProc as follows:

SQL> CREATE OR REPLACE PROCEDURE TestProc
  2  AS
  3    vnum number;
  4  BEGIN
  5    vnum := vAnotherNum;
  6  END;
  7  /

Warning: Procedure created with compilation errors.

This procedure was created with compilation errors. So if we try to execute this procedure, we will get an ORA-06550 error as follows:

SQL> execute TestProc();
BEGIN TestProc(); END;

*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00905: object EXAMPLE.TESTPROC is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored

You can run the SHOW ERROR command to view the errors as follows:

SQL> show error procedure TestProc;
Errors for PROCEDURE TESTPROC:

LINE/COL ERROR
-------- -----------------------------------------------------------------
5/1	 PL/SQL: Statement ignored
5/9	 PLS-00201: identifier 'VANOTHERNUM' must be declared

As you can see, the error is caused by the variable called VANOTHERNUM not being declared. To resolve this error, we can modify our TestProc procedure to declare the variable as follows:

SQL> CREATE OR REPLACE PROCEDURE TestProc
  2  AS
  3    vnum number;
  4    vAnotherNumber number;
  5  BEGIN
  6    vAnotherNum := 999;
  7    vnum := vAnotherNum;
  8  END;
  9  /

Procedure created.

And now when we execute our TestProc procedure, the ORA-06550 error has been resolved.

SQL> execute TestProc();

PL/SQL procedure successfully completed.

Этот код SQL выдает мне ошибку «Ошибка в строке 2: PL / SQL: инструкция проигнорирована». Я работаю над приложением SQL oracle express / APEX: я пробовал все, что мог придумать, и каждый раз это вызывает у меня разные проблемы.

CREATE or replace TRIGGER remove_artista 
   instead of delete on V_ARTISTA
REFERENCING old AS orow
FOR EACH ROW
BEGIN
if exists(select * from Utilizadores where pessoaID = orow.pessoaID) then
        delete from Pessoas where pessoaID = orow.pessoaID;
ELSE
        delete from Artistas where pessoaID = orow.pessoaID;
        delete from Pessoas where pessoaID = orow.pessoaID;
end if;
END;

Вид:

create or replace view v_artista as 
 select 
pessoaID, nome_p, sexo, data_nasc, nome_art, biografica
from Pessoas natural inner join Artistas;

РЕДАКТИРОВАТЬ: исправлена ​​небольшая опечатка в коде.

2 ответа

Лучший ответ

Полная ошибка, которую я получаю от вашего триггера, выглядит следующим образом:

LINE/COL ERROR
-------- -----------------------------------------------------------------
2/1      PL/SQL: Statement ignored
2/4      PLS-00204: function or pseudo-column 'EXISTS' may be used inside
         a SQL statement only

По сути, проблема в том, что вы не можете сказать if exists(...), как вы это делаете. Oracle не позволяет вам.

Вместо этого попробуйте выбрать количество совпадающих строк в таблице Utilizadores в локальной переменной, а затем использовать это в своем операторе if:

CREATE or replace TRIGGER remove_artista 
   instead of delete on V_ARTISTA
REFERENCING old AS orow
FOR EACH ROW
DECLARE
  l_count       INTEGER;
BEGIN
  select count(*) 
    into l_count
    from Utilizadores
   where pessoaID = :orow.pessoaID;

  if l_count > 0 then
        delete from Pessoas where pessoaID = :orow.pessoaID;
  ELSE
        delete from Artistas where pessoaID = :orow.pessoaID;
        delete from Pessoas where pessoaID = :orow.pessoaID;
  end if;
END;

Мне также нужно было заменить orow на :orow. После внесения этого изменения ваш триггер скомпилирован для меня.


4

Luke Woodward
24 Май 2014 в 00:06

Я не думаю, что вы можете использовать конструкцию IF EXISTS, чтобы проверить, существует ли строка. Вы можете использовать SELECT COUNT(*) INTO <a variable>. Однако вам может не понадобиться проверять, существует ли строка. Следующий код, вероятно, подойдет:

CREATE OR REPLACE TRIGGER remove_artista 
INSTEAD OF DELETE ON V_ARTISTA
FOR EACH ROW
BEGIN
  DELETE FROM PESSOAS
  WHERE PESSOAID = :OLD.PESSOAID;

  DELETE FROM Artistas
  WHERE PESSOAID = :OLD.PESSOAID
  AND NOT EXISTS (SELECT 1 FROM UTILIZADORES WHERE PESSOAID = :OLD.PESSOAID);  

END;

Строка из PESSOAS в любом случае будет удалена. Строка из ARTISTAS будет удалена, только если PESSOAID не существует в UTILIZADORES.

Ссылки :

Проверить, существует ли запись на форуме OTN


2

Joseph B
24 Май 2014 в 00:11

Summary

After
restoring an Oracle backup the Bizagi application does not start and
the Event Viewer displays errors with code ORA-06550 and PLS-00905.

Applies to

Bizagi
Engine 10.x using Oracle Database

Symptoms

After
restoring an Oracle backup, the Bizagi application does not start and
the Event Viewer displays the a trace like:

ORA-06550: line 1, column 7:
PLS-00905:
object BIZAGIGO.SPBA_WFE_GETNEXTASYNCWIFORRUN is invalid

ORA-06550: line
1, column 7:

PL/SQL:
Statement ignored

The
affected stored procedure may vary and the failed line and column as
well.

Cause

The
problem occurs due to some of the stored procedures may have
compilation errors. To identify the failing procedure, you may use an
Oracle database tool for SQL development.

Solution

1.
Run the following procedure in your database

grant execute on
sys.dbms_lock to [usrBizagi]

In
which, [usrBizagi]
is the Bizagi user for the schema

2.
Recompile the stored procedures that are failing.

3.
Restart Bizagi services and test.

Yesterday, while learning oracle stored procedures, I wrote a demo of stored procedures. The statement is as follows:


CREATE OR REPLACE PROCEDURE RAISESALARY(PNAME IN VARCHAR2(20))
AS
    psssal TESTDELETE.TESTID%TYPE;
BEGIN
    SELECT TESTID INTO psssal FROM TESTDELETE WHERE TESTNAME=PNAME;
    UPDATE TESTDELETE SET TESTID=(TESTID+10000) WHERE TESTNAME=PNAME;
    DBMS_OUTPUT.PUT_LINE('The original salary'||psssal||'    After the raise'||(psssal+1000));
end;
/

The idea is to find the number type field through the varchar(20) type field of the table, and then change the number type field. The table structure is as follows:

create table TESTDELETE
(
    TESTID   NUMBER,
    TESTNAME VARCHAR2(20)
)

Call the stored procedure, and the result is as follows:


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

CREATE OR REPLACE PROCEDURE RAISESALARY(PNAME IN VARCHAR2(20))
  2  AS
  3      psssal TESTDELETE.TESTID%TYPE;
  4  BEGIN
  5      SELECT TESTID INTO psssal FROM TESTDELETE WHERE TESTNAME=PNAME;
    UPDATE TESTDELETE SET TESTID=(TESTID+10000) WHERE TESTNAME=PNAME;
    DBMS_OUTPUT.PUT_LINE('The original salary'||psssal||'    After the raise'||(psssal+1000));
  8  end;
  9  /

Warning: Procedure created with compilation errors.

SET SERVEROUTPUT ON;
BEGIN
    RAISESALARY('name2091');
    COMMIT;
END;
SQL>   2    3    4    5  /
    RAISESALARY('name2091');
    *
ERROR at line 2:
ORA-06550: line 2, column 5:
PLS-00905: object TEST.RAISESALARY is invalid
ORA-06550: line 2, column 5:
PL/SQL: Statement ignored


SQL> 

An error occurred: the stored procedure is not valid.

what? The stored procedure that Mingming just established. Then I turn to the above sentence after creation, Warning: Procedure created with compilation errors.

That is to say, there is an error in creating the stored procedure. OK, look for the stored procedure to see what is wrong.

emmmm, looking back for a long time, just a few lines, I can’t see what’s wrong, baidu, google.

Later, I saw this in StackOverFlow. The original link is as follows:

https://stackoverflow.com/questions/48497140/oracle-sql-stored-procedure-object-invalid

The landlord found a saying in it:

You can’t give a size or precision restriction for the data type of a formal parameter to a function or procedure, so NUMBER(10,0) should just be NUMBER;

That is, you cannot specify the size or precision of the data for the parameters of functions and stored procedures. OK, looking back at my parameter, I see that varchar2(20) clearly specifies the precision for the parameter type. You need to change to varchar2.

Or write the table name. Field% TYPE directly.

After the change, run as follows:

CREATE OR REPLACE PROCEDURE RAISESALARY(PNAME IN VARCHAR)
  2  AS
  3      psssal TESTDELETE.TESTID%TYPE;
  4  BEGIN
  5      SELECT TESTID INTO psssal FROM TESTDELETE WHERE TESTNAME=PNAME;
    UPDATE TESTDELETE SET TESTID=(TESTID+10000) WHERE TESTNAME=PNAME;
    DBMS_OUTPUT.PUT_LINE('The original salary'||psssal||'    After the raise'||(psssal+1000));
  8  end;
  9  /

Procedure created.

BEGIN
    RAISESALARY('name2091');
  3      COMMIT;
  4  END;
  5  /
The original salary2091    After the raise3091

PL/SQL procedure successfully completed.

SQL> 

After the modification, it is clear that there is no warning. The Procedure created appears

Run successfully! Problem solving.


Вы почти все сделали нормально. Немного о процедуре,

Выполните приведенную ниже команду (возможно, вы пропустили ошибку)

ALTER PROCEDURE student_grade COMPILE;
Warning: Procedure altered with compilation errors

вам не нужно делать p_average параметр как IN OUT, OUT должно быть достаточно, так как вы рассчитываете его внутри.

чтобы присвоить какое-либо значение параметру OUT, вам не нужно использовать SET. Допускается только присваивание с использованием оператора присваивания. Смотри ниже

CREATE OR REPLACE PROCEDURE student_grade
(
   p_school_no IN lessons.school_number%TYPE
  ,p_lesson    OUT lessons.lesson_name%TYPE
  ,p_midterm_1 OUT lessons.midterm_notu_1%TYPE
  ,p_midterm_2 OUT lessons.midterm_notu_2%TYPE
  ,p_final     OUT lessons.final_notu%TYPE
  ,p_average   OUT NUMBER
) IS
BEGIN
   SELECT d.lesson
         ,d.midterm_notu_1
         ,d.midterm_notu_2
         ,d.final_notu
   INTO   p_lesson
         ,p_midterm_1
         ,p_midterm_2
         ,p_final
   FROM   lessons d
   WHERE  d.shool_number = p_school_no;
   --assign to the output variable for average
   p_average := (((d.midterm_notu_1 * 25) / 100) + ((d.midterm_notu_2 * 30) / 100) + ((d.final_notu * 45) / 100));
END;
/

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

Вы также можете протестировать его с помощью анонимного блока PL/SQL вместо окна команд SQL, что было бы проще. Например

DECLARE
    --assign the input directly here in the declare section
    v_school_no lessons.school_number%type := 10;
    v_lesson lessons.lesson_name%type;
    v_midterm_1 lessons.midterm_notu_1%type;
    v_midterm_2  lessons.midterm_notu_2%type;
    v_final lessons.final_notu%type;
    v_average NUMBER;
BEGIN
    -- call the procedure
    student_grade(  
        v_lesson,
        v_midterm_1,
        v_midterm_2  ,
        v_final,
        v_average );
    DBMS_OUTPUT.put_line ('Student Grade');
    DBMS_OUTPUT.put_line ('School Number: ' ||v_school_no);
    DBMS_OUTPUT.put_line ('Midterm 1: ' || v_midterm_1);
    DBMS_OUTPUT.put_line ('Midterm 2: ' || v_midterm_2  );
    DBMS_OUTPUT.put_line ('Final: ' || v_final);
    DBMS_OUTPUT.put_line ('Average: ' || v_average );
END;
/

Сообщите мне, если это решит вашу проблему;


ПЕРЕСМОТРЕННЫЙ ОТВЕТ О КОНКРЕТНОЙ ПРОБЛЕМЕ ИСПОЛЬЗОВАНИЯ И ИСПОЛЬЗОВАНИЯ ИНСТРУМЕНТА

Я настоятельно рекомендую / предлагаю вам изучить документацию PL/SQL перед тем, как продолжить выполнение следующего задания. Это поможет вам понять возникающие ошибки и исправить их. Также есть много видеороликов об инструменте SQL Developer, как их эффективно использовать. Проверьте их тоже.

Возвращаясь к проблеме, которую я пробовал на своей машине, в скрипте есть много проблем, которые мне приходилось исправлять одно за другим, просматривая сообщения об ошибках. Пожалуйста, найдите пункты и окончательное решение, которые должны работать, иначе я закончу.

Проблемы: есть отличия в названиях столбцов в таблице от написанного вами кода

  1. WHERE d.shool_number = p_school_no; -> shool_number не существующий столбец, вероятно, d.school_number
  2. v_lesson lessons.lesson_name%type; -> фактический столбец lesson и нет lesson_name. Я могу сказать это из вашего пункта select в процедуре
  3. p_lesson OUT lessons.lesson_name%type, -> то же, что и в пункте 2
  4. p_average := (((d.midterm_notu_1 * 25)/100) + ((d.midterm_notu_2 * 30)/100) + ((d.final_notu * 45)/100)); — нельзя ссылаться на столбцы таким образом, что это значит с "d." где код не знает, к чему он относится. d вы использовали в запросе выбора как псевдоним таблицы lessons и с помощью оператора select заканчивается область действия dзаканчивает там сам. Поскольку вы уже перенесли значения в выходные переменные, такие какp_midterm_1, p_midterm_2, p_finalиспользуйте их вместо них.
  5. Кроме того, убедитесь, что оператор select возвращает только одну строку для каждого school_number=20201754 иначе вы закончите с ошибкой ORA-01422: exact fetch returns more than requested number of rowsи есть другие способы справиться с этим. (пока ничего не скажу по этому поводу)
  6. Заключительный момент, когда вы пытаетесь протестировать процедуру, например student_grade( v_lesson, v_midterm_1, v_midterm_2 , v_final, v_average ); -> вы передаете неправильное количество аргументов в процедуру, не включая v_school_no в качестве первого параметра.

Однако я создал свою собственную настройку и соответственно изменил процедуру и тест, см. Ниже.

--table definition
create table lessons (school_number number,lesson varchar2(100),midterm_notu_1 number,midterm_notu_2 number,final_notu number);
--inserting unique rows per school_number
insert into lessons values(20201754,'Maths',35,55,85);
insert into lessons values(20201755,'Science',45,65,95);

-- to enable the dbms_output
SET SERVEROUTPUT ON;

--procedure definition
CREATE OR REPLACE PROCEDURE student_grade(
        p_school_no IN lessons.school_number%type,
        p_lesson OUT lessons.lesson%type,
        p_midterm_1 OUT lessons.midterm_notu_1%type,
        p_midterm_2  OUT lessons.midterm_notu_2%type,
        p_final OUT lessons.final_notu%type,
        p_average OUT NUMBER
    )
IS
BEGIN
    SELECT
    d.lesson,
    d.midterm_notu_1,
    d.midterm_notu_2,
    d.final_notu
    INTO
        p_lesson,
        p_midterm_1,
        p_midterm_2,
        p_final
    FROM lessons d
    WHERE d.school_number = p_school_no;
    p_average := (((p_midterm_1 * 25)/100) + ((p_midterm_2 * 30)/100) + ((p_final * 45)/100));
END student_grade;
/

--testing the procedure    
DECLARE
    v_school_no lessons.school_number%type := 20201754;
    v_lesson lessons.lesson%type;
    v_midterm_1 lessons.midterm_notu_1%type;
    v_midterm_2  lessons.midterm_notu_2%type;
    v_final lessons.final_notu%type;
    v_average NUMBER;
BEGIN
    student_grade(
        v_school_no,
        v_lesson,
        v_midterm_1,
        v_midterm_2  ,
        v_final,
        v_average );
    DBMS_OUTPUT.put_line ('Student Grade');
    DBMS_OUTPUT.put_line ('School Number: ' ||v_school_no);
    DBMS_OUTPUT.put_line ('Midterm 1: ' || v_midterm_1);
    DBMS_OUTPUT.put_line ('Midterm 2: ' || v_midterm_2  );
    DBMS_OUTPUT.put_line ('Final: ' || v_final);
    DBMS_OUTPUT.put_line ('Average: ' || v_average );
END;
/

vova_garmo6kin

0 / 0 / 0

Регистрация: 12.11.2013

Сообщений: 6

1

Ошибка при создании триггера

12.11.2013, 00:37. Показов 4150. Ответов 15

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Добрый вечер!
Помогите пожалуйста новичку!

Есть 2 таблицы:
1) Товар (ID_товара, наименование, цена)
2) Фактура(ID_товара, количество, цена_реализации)

!!! цена_реализации = цена * количество
Для того чтобы поле вычислялось создаю триггер:

Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
CREATE TRIGGER test
after INSERT ON товар
 REFERENCING OLD AS old NEW AS NEW
      FOR EACH ROW
      BEGIN
IF inserting THEN UPDATE фактура
SET цена_реализации=количество+:NEW.цена
WHERE id_товара=:NEW.id_товара;
END IF;
END;

Но выдает следующую ошибку: Error at line 2: PL/SQL: SQL Statement ignored
Подскажите в чем проблема? скорее всего я налажал(((



0



Grossmeister

Модератор

4214 / 3054 / 582

Регистрация: 21.01.2011

Сообщений: 13,205

12.11.2013, 09:55

2

Так триггер не создался вообще или создался с ошибками? Если создался с ошибками, то посмотри

SQL
1
2
SELECT *
FROM user_errors

Возможно там более вразумительное сообщение.

На будущее:
1. ради интереса: почему у тебя триггер after, а не before?
2. обычно пишут CREATE OR REPLACE, поскольку возможно потребуется триггер изменять
3. REFERENCING OLD AS old NEW AS new — обычно это пишут, если хотят заменить old и new на что-то другое, иначе написанное тобой действует по дефолту
4. зачем писать if inserting, если у тебя триггер только на insert? Это условие и так будет всегда истинно
5. русские названия таблиц и колонок не шибко хорошо. Прямого запрета на это нет, но это источник потенциальных глюков. Конечно, если у вас так в институте, с этим ничего не поделаешь, но на будущее…



1



32 / 32 / 4

Регистрация: 01.07.2013

Сообщений: 230

12.11.2013, 11:10

3

Цитата
Сообщение от vova_garmo6kin
Посмотреть сообщение

end;

Нужно end trigger test;

Добавлено через 29 секунд
Вы end-ом триггер не закрыли так сказать



0



Модератор

4214 / 3054 / 582

Регистрация: 21.01.2011

Сообщений: 13,205

12.11.2013, 11:39

4

Цитата
Сообщение от Denis91
Посмотреть сообщение

Нужно end trigger test;

Совершенно необязательно. Закрытие любого PL/SQL блока — это END, все остальное — типа комментария. Лично я после END никогда больше ничего не пишу, но это дело вкуса.



0



32 / 32 / 4

Регистрация: 01.07.2013

Сообщений: 230

12.11.2013, 11:50

5

Никогда не пробовал писать просто END; Буду иметь ввиду, хотя врятли так буду писать.



0



Модератор

4214 / 3054 / 582

Регистрация: 21.01.2011

Сообщений: 13,205

12.11.2013, 12:02

6

К слову сказать, если посмотреть примеры в оф. доке (SQL Reference, Application Developers Guide), то там как раз просто END.
А чтобы легко различать конец процедур (скажем, в пакете) от других END, я просто после конца процедуры ставлю горизонтальную черту. ИМХО это гораздо наглядней, чем END procname;



0



32 / 32 / 4

Регистрация: 01.07.2013

Сообщений: 230

12.11.2013, 12:08

7

Да, но как вы говорили

Цитата
Сообщение от Grossmeister
Посмотреть сообщение

это дело вкуса.



0



vova_garmo6kin

0 / 0 / 0

Регистрация: 12.11.2013

Сообщений: 6

12.11.2013, 12:55

 [ТС]

8

Воспользовавшись советами Grossmeister решил создать триггер по-новому:

Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
11
CREATE OR REPLACE TRIGGER test1
BEFORE INSERT ON фактура
FOR EACH ROW
DECLARE 
  a NUMBER; 
  b NUMBER;
BEGIN
  SELECT ID_товара,цена INTO a,b FROM товар;
  UPDATE фактура SET цена_реализации=количество*b 
  WHERE a = ID_товара;
END;

Триггер создается без ошибок. Заполняю таблицу товар. Когда пытаюсь заполнить таблицу фактура выходит следующая ошибка:
error ORA-01422: exact fetch returns more than requested number of rows ORA-06512: at «SKLAD.TEST1», line 6 ORA-04088: error during execution of trigger ‘SKLAD.TEST1’

Где я опять налажал?



0



Модератор

4214 / 3054 / 582

Регистрация: 21.01.2011

Сообщений: 13,205

12.11.2013, 13:07

9

Не понял. Первый триггер у тебя был на таблицу Товар, второй на таблицу Фактура. Так как в результате надо?



0



0 / 0 / 0

Регистрация: 12.11.2013

Сообщений: 6

12.11.2013, 13:37

 [ТС]

10

Мне нужно вычислить значение в поле цена_реализации из таблицы фактура. поэтому я подумал,что лучше создать триггер для таблицы фактура,но я могу ошибаться



0



Модератор

4214 / 3054 / 582

Регистрация: 21.01.2011

Сообщений: 13,205

12.11.2013, 13:49

11

Опиши бизнес-процесс, что за чем следует. Когда формируется запись по товару, когда по фактуре. Тогда проще будет определиться, какие и где триггера нужны.



0



0 / 0 / 0

Регистрация: 12.11.2013

Сообщений: 6

12.11.2013, 13:54

 [ТС]

12

Сначала я получаю товар на склад, следовательно первой я заполняю таблицу товар. затем я оформляю заказ, т.е. заполняю фактуру(ввожу код нужного мне товара и его количество). Поэтому я и подумал,что триггер мне нужен для таблицы фактура, чтобы он мне вычислил общую сумму заказа.



0



Модератор

4214 / 3054 / 582

Регистрация: 21.01.2011

Сообщений: 13,205

12.11.2013, 15:01

13

ОК. У тебя по каждому товару только 1 запись? А то, судя по ошибке, SELECT…INTO вернул несколько строк.
И второе. Зачем в триггере на insert делать UPDATE фактуры? Если достаточно присвоить нужные значения :NEW?



0



vova_garmo6kin

0 / 0 / 0

Регистрация: 12.11.2013

Сообщений: 6

12.11.2013, 15:55

 [ТС]

14

Триггер я опять изменил, но я понимаю как присвоить нужные значения :NEW…
Сейчас он хотя бы добавляет данные в таблицу, но есть одно НО: допустим я добавляю строчку в фактуру с кодом товара 1 и количеством 10 — общую сумму он не высчитывает. когда я добавляю еще одну строчку с кодом товара 1 и количеством 2, он вычисляет общую сумму для первой строчки, а для второй нет

Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
11
12
CREATE OR REPLACE TRIGGER test1
before INSERT ON factura
referencing NEW AS NEW
FOR EACH ROW
DECLARE 
  a NUMBER; 
BEGIN
  SELECT tsena_za_ed INTO a FROM tovar 
  WHERE id_tovara =  :NEW.id_tovara;
  UPDATE factura SET tsena_realezatsii=kolvo*a 
  WHERE id_tovara = :NEW.id_tovara;
END;



0



Grossmeister

Модератор

4214 / 3054 / 582

Регистрация: 21.01.2011

Сообщений: 13,205

12.11.2013, 16:04

15

вместо этого

Цитата
Сообщение от vova_garmo6kin

UPDATE factura SET tsena_realezatsii=kolvo*a
WHERE id_tovara = :new.id_tovara;

надо так

SQL
1
:NEW.tsena_realezatsii:= :NEW.kolvo * a;



0



0 / 0 / 0

Регистрация: 12.11.2013

Сообщений: 6

12.11.2013, 16:10

 [ТС]

16

Спасибо большое!Очень помогли!!!



0



Понравилась статья? Поделить с друзьями:
  • Sql state im003 native 160 ошибка 182
  • Sql state 42p01 ошибка
  • Sql state 28000 native 18452 ошибка входа пользователя
  • Spore ошибка 1004 пиратка
  • Sql state 28000 native 18456 ошибка входа пользователя