【问题标题】:create a function from a block of code从代码块创建一个函数
【发布时间】:2012-05-31 22:11:51
【问题描述】:

如何将这段代码转换为具有相同输出的函数?

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;

【问题讨论】:

  • 您只想打印还是希望函数返回记录集以进行进一步操作?对于前者,使用@Sajmon 给出的答案,用 Put_Line 替换累积串联。对于后者,您需要创建一个表值函数。

标签: sql oracle function plsql


【解决方案1】:
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) enought。但我听说过这种类型,但现在我不知道是否存在。

当您在应用层使用它时,必须以某种方式格式化返回的字符串。

【讨论】:

  • 从 Oracle 10g 开始,最大 varchar 为 4000。而且,您不认为 '+' 符号不能用于连接吗? [out_stmt := out_stmt + 'Employee name: '] - 应该是 ||
  • 可能也需要一个异常处理程序,以防您溢出 out_stmt 变量。
【解决方案2】:
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 条记录集?

顺便说一下,这样做只是为了举例。如果您唯一的要求是运行查询的函数,我不会这样做。我会返回一个引用游标,或者(甚至更好)将查询放在视图中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    相关资源
    最近更新 更多