2012-05-31 5 views
1

как я могу превратить этот код в функцию с тем же выходом?создать функцию из блока кода

declare 
    record_name employees%ROWTYPE; 
begin 
    FOR record_name IN (SELECT (a.first_name || ' ' || a.last_name) complete_name, 
         b.DEPARTMENT_NAME complete_name2 
        FROM employees a , departments b 
        WHERE ROWNUM < 1000 and a.DEPARTMENT_ID=b.DEPARTMENT_ID) 
    LOOP 
    DBMS_OUTPUT.PUT_LINE('Employee name: ' || record_name.complete_name 
          ||'DEPARTMENT name: '||record_name.complete_name2); 
    END LOOP; 
END; 
+0

Вы хотите только напечатать или хотите, чтобы функция возвращала набор записей для дальнейших операций? Для первого используйте ответ @Sajmon, заменив кумулятивную конкатенацию на Put_Line. Для последнего вам нужно создать табличную функцию. – SQLCurious

ответ

0
create or replace function SOME_FUNCTION 
RETURN VARCHAR 
AS 
    record_name employees%ROWTYPE; 
    out_stmt varchar(4000); 
    TOO_LONG EXCEPTION; 
BEGIN 
    FOR record_name IN (SELECT (a.first_name || ' ' || a.last_name) complete_name, 
         b.DEPARTMENT_NAME complete_name2 
        FROM employees a , departments b 
        WHERE ROWNUM < 1000 and a.DEPARTMENT_ID=b.DEPARTMENT_ID) 
    LOOP 
    IF (LENGTH(out_stmt) < 4000) THEN 
     out_stmt := out_stmt || 'Employee name: ' || record_name.complete_name || 'DEPARTMENT name: '||record_name.complete_name2; 
    ELSE 
     RAISE TOO_LONG; 
    END IF; 
    END LOOP; 
    return out_stmt; 
EXCEPTION 
    WHEN TOO_LONG THEN 
     RETURN 'OVERFLOW'; 
END; 

Быстрый пример, я не знаю, есть ли какой-то тип, который не имеет ограничения целостности, потому что не всегда будет varchar(4000) прийти. но я слышал что-то об этом типе, но теперь я точно не знаю, что существует.

Когда вы будете работать с этим в слое приложения, необходимо как-то форматировать возвращаемую строку.

+0

с Oracle 10g max varchar - 4000. А также, вы не считаете, что знак «+» выиграл? T работает для конкатенации? [out_stmt: = out_stmt + 'Имя сотрудника:'] - должно было быть || – codingbiz

+0

ohh im fool, спасибо, так что T-SQL плохо влияет на меня. – Sajmon

+0

Можете также использовать обработчик исключений, если вы переполнили переменную out_stmt. – DCookie

0
CREATE TYPE some_employees_record IS RECORD 
    (emp_name VARCHAR2(4000) 
    ,dept_name VARCHAR2(4000)); 
CREATE TYPE employees_tab_type IS TABLE OF some_employees_record; 

CREATE OR REPLACE 
FUNCTION some_employees 
RETURN employees_tab_type 
PIPELINED 
IS 
    rec some_employees_record; 
BEGIN 
    FOR record_name IN (SELECT (a.first_name || ' ' || a.last_name) complete_name, 
         b.DEPARTMENT_NAME complete_name2 
        FROM employees a , departments b 
        WHERE ROWNUM < 1000 and a.DEPARTMENT_ID=b.DEPARTMENT_ID) 
    LOOP 
    rec.emp_name := record_name.complete_name; 
    rec.dept_name := record_name.complete_name2; 
    PIPE ROW (rec); 
    END LOOP; 
    RETURN; 
END; 

Вы можете вызвать вышеуказанную функцию двумя способами. В SQL:

SELECT * FROM TABLE(some_employees); 

или в PL/SQL:

DECLARE 
    rt employees_tab_type; 
BEGIN 
    rt := some_employees; 
    FOR i IN 1..rt.COUNT LOOP 
    DBMS_OUTPUT.put_line(rt(i).emp_name || ', ' || rt(i).dept_name); 
    END LOOP; 
END; 

OT: вы понимаете, что запрос возвращает эффективно случайный (недетерминированный) набор 999 записей, если количество записей превышает 999 ?

Кстати, это было сделано, например, только для целей. Если ваше единственное требование - это функция для запуска запроса, я бы не сделал этого таким образом. Я бы вернул курсор, или (еще лучше) поставил запрос в представлении.