#sql #oracle #function #plsql
#sql #Oracle #функция #plsql
Вопрос:
Сейчас я на испытательном сроке, и мой руководитель дал мне такое задание. Хотя он знает, что я не понимаю PL / SQL
Суть задачи: Функция получает идентификатор клиента в качестве входных данных и возвращает имя.
Кроме того, этот код необходимо оптимизировать. Помимо того, что этот код не работает, что нужно сделать, чтобы оптимизировать его и заставить работать?
Извините за, возможно, глупый вопрос.
На данный момент я изучаю PL / SQL, но моих знаний недостаточно для понимания функций.
Таблица без ограничений и первичных ключей.
CREATE TABLE CUSTOMERS(CUSTOMER_ID NUMBER, CUSTOMER_NAME VARCHAR2(255));
CREATE OR REPLACE FUNCTION get_name(customer_id number)
return varchar2
as
result varchar2(50);
BEGIN
select customer_name
into result
from customers c
where c.customers_id = customers_id;
return result;
END;
Извините за мой плохой английский.
Комментарии:
1. Просто предостережение. Ваша функция получает имя клиента, но этот столбец в базе данных имеет размер до 255 байт, но ваша функция (переменная результата) допускает только 50). Любое имя, превышающее 50, выдаст ошибку, это означает, что допустимое значение в базе данных может вызвать ошибку. Будьте в безопасности, установите свои локальные переменные по крайней мере настолько большими, насколько позволяет база данных. Еще лучше привязать ваши локальные переменные к столбцу базы данных. В этом случае вместо «result varchar2(255)» используйте result customers.customer_name%type .
2. Если любой из предоставленных ответов решил вашу проблему, пожалуйста, примите его. Если нет, то укажите проблему с ними. Однако не оставляйте вопрос открытым и без ответа.
Ответ №1:
Написанный вами код почти в порядке. Вы допустили две ошибки:
-
если имя столбца
CUSTOMER_ID
, то не ссылайтесь на него какCUSTOMERS_ID
-
если имя столбца равно
CUSTOMERS_ID
, не называйте параметр функции тем же самым, потому что — при использовании вWHERE
предложении — Oracle не может отличить, что есть что, поэтому это:where customers_id = customers_id
становится
where 1 = 1
это не то, что вы хотели.
Вот пример, который показывает, как это сделать; посмотрим, поможет ли это.
Пример таблицы:
SQL> create table customers as select empno customers_id, ename customer_name
2 from emp
3 where deptno = 10;
Table created.
Функция; обратите внимание на измененное имя параметра:
SQL> CREATE OR REPLACE FUNCTION get_name(par_customers_id number)
2 return varchar2
3 as
4 result varchar2(50);
5 BEGIN
6 select customer_name
7 into result
8 from customers c
9 where c.customers_id = par_customers_id;
10 return result;
11 END;
12 /
Function created.
Тестирование:
SQL> select customers_id, get_name(customers_id) name
2 from customers;
CUSTOMERS_ID NAME
------------ --------------------
7782 CLARK
7839 KING
7934 MILLER
SQL>
Пока все хорошо, не так ли?
Как использовать DUAL
таблицу?
SQL> select get_name(7782) from dual;
GET_NAME(7782)
----------------------------------------
CLARK
SQL>
Комментарии:
1. Привет. Спасибо за вашу помощь. Но на основе примеров, которые вы привели. Если я введу идентификатор клиента, то я должен получить только его имя и идентификатор. И когда я запускаю запрос, если я добавляю идентификатор к получаемому имени, я получаю всех клиентов, это также происходит, если я указываю идентификатор клиента (1, 2, 3). Пример: выберите customer_id, получите имя (customers_id) от клиентов; ИЛИ: выберите customer_id, получите имя (1) от клиентов; ИЛИ: выберите customer_id, получите имя (1) от клиентов; Я получаю один и тот же результат каждый раз. Но каждый раз, когда я ввожу другой идентификатор, я должен получить соответствующее имя. Что не так 🙁 ?
2. Выберите из DUAL, а не из CUSTOMERS
3. Извините, я пытался это сделать, но, похоже, я не понял, как использовать dual в этом случае. Не могли бы вы написать, что делать для отображения информации в соответствии с комментарием выше. Заранее благодарю вас и приношу извинения за неудобства.
4. Я добавил пример с ДВОЙНОЙ таблицей; взгляните.
Ответ №2:
Ваша функция не обрабатывает исключения, и вы уверены, что select возвращает только одно значение.
Потому что, если это не так, функция выдаст ошибку и, следовательно, функция не будет работать так, как ожидалось, поскольку нет обработки исключений.
Выполните приведенный ниже запрос в sql developer, чтобы определить, сколько идентификаторов клиентов имеют более одной записи в таблице.
select customers_id, count(1)
from customers c
group by customers_id;