Как использовать переменную связывания в plsql? - PullRequest
0 голосов
/ 19 ноября 2011

Простое задание

variable dept_id NUMBER

DECLARE
    max_deptno NUMBER;
    dept_name departments.department_name%TYPE := 'Education';
BEGIN
    select max(department_id)
      into max_deptno
      from departments;
    :dept_id := max_deptno + 10;
    insert into departments (department_id, department_name, location_id)
      values (:dept_id, dept_name, null);
    DBMS_OUTPUT.PUT_LINE('The maximum department id is ' || max_deptno);
    DBMS_OUTPUT.PUT_LINE('Rows made by insert: ' || SQL%ROWCOUNT);
END;

max_deptno не NULL.Почему dept_id равен NULL после присваивания?Что я делаю не так?

вывод сценария:

MAX(DEPARTMENT_ID)
------------------
               520 

Error starting at line 10 in command:
DECLARE
max_deptno NUMBER;
dept_name departments.department_name%TYPE := 'Education1';
BEGIN
select max(department_id)
into max_deptno
from departments;
:dept_id := max_deptno + 10;
insert into departments (department_id, department_name, location_id)
values (:dept_id, dept_name, null);
DBMS_OUTPUT.PUT_LINE('The maximum department id is ' || max_deptno);
DBMS_OUTPUT.PUT_LINE('Rows made by insert: ' || SQL%ROWCOUNT);
END;

Отчет об ошибке:

ORA-01400: невозможно вставить NULL в ("ANDKOM"."DEPARTMENTS"."DEPARTMENT_ID")
ORA-06512: на  line 9
01400. 00000 -  "cannot insert NULL into (%s)"
*Cause:    
*Action:

Ответы [ 2 ]

6 голосов
/ 19 ноября 2011

Переменная хоста DEPT_ID не равна NULL после назначения.Проблема в том, что ваш оператор INSERT использует локальную переменную NEW_DPT в INSERT, и что локальной переменной не присвоено значение.Если вы действительно хотите использовать переменную хоста в PL / SQL (вы, по сути, никогда не сделаете этого в реальной жизни), вам необходимо использовать это в своем блоке PL / SQL

SQL> ed
Wrote file afiedt.buf

  1  DECLARE
  2    max_deptno NUMBER;
  3    new_dpt NUMBER;
  4    dept_name departments.department_name%TYPE := 'Education';
  5  BEGIN
  6    select max(department_id)
  7      into max_deptno
  8      from departments;
  9    :dept_id := max_deptno + 10;
 10    insert into departments (department_id, department_name, location_id)
 11      values (:dept_id, dept_name, null);
 12    DBMS_OUTPUT.PUT_LINE('The maximum department id is ' || max_deptno);
 13    DBMS_OUTPUT.PUT_LINE('Rows made by insert: ' || SQL%ROWCOUNT);
 14* END;
SQL> /
The maximum department id is 270
Rows made by insert: 1

PL/SQL procedure successfully completed.

SQL> select :dept_id from dual;

  :DEPT_ID
----------
       280

Однако более реалистичнобыло бы полностью исключить переменную подстановки

SQL> ed
Wrote file afiedt.buf

  1  DECLARE
  2    max_deptno NUMBER;
  3    new_dpt NUMBER;
  4    dept_name departments.department_name%TYPE := 'Education';
  5  BEGIN
  6    select max(department_id)
  7      into max_deptno
  8      from departments;
  9    new_dpt := max_deptno + 10;
 10    insert into departments (department_id, department_name, location_id)
 11      values (new_dpt, dept_name, null);
 12    DBMS_OUTPUT.PUT_LINE('The maximum department id is ' || max_deptno);
 13    DBMS_OUTPUT.PUT_LINE('Rows made by insert: ' || SQL%ROWCOUNT);
 14* END;
SQL> /
The maximum department id is 280
Rows made by insert: 1

PL/SQL procedure successfully completed.
0 голосов
/ 22 ноября 2011

Я задал тот же вопрос на форуме оракула и получил ответ:

Привет,

Это известная проблема, которая зависит от ошибки JDBC, которая никогда решено: https://forums.oracle.com/forums/thread.jspa?messageID=9456891&#9456891

Если ваш конкретный случай не подходит для установки переменной связывания в одном анонимном блоке и читая его в другом, то единственный Обходной путь (который также считается хорошей практикой кодирования) заключается в замените переменную SQL * Plus на переменную PL / SQL.

С уважением, Команда разработчиков Gary SQL

...