针对SELECT
语句的每一行执行PL/SQL函数。因此,如果您在常规的SELECT
SQL语句中调用您的函数,您将获得每条记录的值。
这里是通过连接第一和最后一个名字联系在一起的例子:
CREATE OR REPLACE FUNCTION NAME (p_FIRST_NAME IN VARCHAR2, p_LAST_NAME IN VARCHAR2)
RETURN VARCHAR2
AS
BEGIN
RETURN p_FIRST_NAME || ' ' || p_LAST_NAME;
END;
/
SELECT first_name, last_name, name(first_name, last_name) FROM HR.employees;
FIRST_NAME LAST_NAME NAME(FIRST_NAME,LAST_NAME)
---------- --------- --------------------------
Ellen Abel Ellen Abel
Sundar Ande Sundar Ande
Mozhe Atkinson Mozhe Atkinson
David Austin David Austin
正如你所看到的,用于执行PL/SQL函数每一行并连接的姓氏和名字,然后返回结果作为SELECT
声明的新列。您不需要更改该功能以使其适用于多行。
现在,您将如何在PL/SQL中使用上面用作示例的SELECT语句执行此操作。您将不得不使用游标来循环结果,或者如果您只想将所有行的结果提取到变量中,则可以使用集合类型。
使用光标( 我在我的例子证明这上面使用Cursor FOR LOOP):
BEGIN
FOR result IN (SELECT first_name, last_name, name(first_name, last_name) name FROM HR.employees) LOOP
DBMS_OUTPUT.PUT_LINE(result.first_name || ', ' || result.last_name || ', ' || result.name);
END LOOP;
END;
/
Ellen, Abel, Ellen Abel
Sundar, Ande, Sundar Ande
Mozhe, Atkinson, Mozhe Atkinson
David, Austin, David Austin
这里发生的是,我在执行同样的SELECT
语句,但现在里面光标FOR LOOP允许我循环返回的每一行。在这种情况下,我只是将结果输出到控制台中。
如果你只想保存所有的行到一个变量,你必须使用一个PL/SQL Collection:
DECLARE
-- Specify cursor with expected results
CURSOR c1 IS
SELECT first_name, last_name, name(first_name, last_name) name
FROM HR.employees;
-- Create PL/SQL type for a nested table of the rowtype of the cursor (first_name, last_name, name)
TYPE NameSet IS TABLE OF c1%ROWTYPE;
employees NameSet; -- Instantiate a variable of the nested table of records
BEGIN
-- Assign values to nested table of records:
SELECT first_name, last_name, name(first_name, last_name) name
BULK COLLECT INTO employees
FROM HR.employees;
-- Print nested table of records:
FOR i IN employees.FIRST .. employees.LAST LOOP
DBMS_OUTPUT.PUT_LINE (
employees(i).first_name || ' ' ||
employees(i).last_name || ', ' ||
employees(i).name
);
END LOOP;
END;
/
Ellen Abel, Ellen Abel
Sundar Ande, Sundar Ande
Mozhe Atkinson, Mozhe Atkinson
David Austin, David Austin
正如你可以在这里看到相同的SELECT
执行,但在这里我们使用BULK COLLECT INTO
而不仅仅是INTO
。这是因为SELECT
返回多于一行,因此我们需要告诉编译器,我们确实期望这样做,以便编译器不会抛出一个返回更多行的错误。
最后但并非最不重要的一点,考虑到在上面的示例SELECT nbrJobs(first_name, last_name) INTO nbrJobsTotal FROM employees
中使用变量名nbrJobsTotal
,我认为您真正想在此做的是总结员工在您公司中的所有不同职位的数量。你可以做到这一点,但使用内置SUM()
功能这是一个聚合函数,也就是说,它只会返回一个行没有GOUP BY
条款:
SELECT SUM(nbrJobs(first_name, last_name)) INTO nbrJobsTotal FROM employees
感谢你为这个全面的答案。毕竟这很简单! –
@Xing你甚至在说什么。我不是讽刺。 “毕竟这很简单”意味着我尝试了许多复杂的事情,完全失去了自我,而事实上我只是保持简单,gvenzl帮助我理解了他的完整答案,因此“谢谢你”。 –
没有难过的感觉!我非常确定答案只是函数的SUM(),但我认为不是给出一个单行的答案,而是增加一点关于PL/SQL函数如何工作的上下文。本着“给一个人一条鱼,他可以吃一天,教他如何钓鱼,他可以一辈子吃完”的精神。希望这个解释不仅有助于@ArthurDeschamps,而且还将帮助许多其他人找到这个问题。至于其余的问题,我很高兴这个问题已经解决,并且(希望)已经学到了一些东西。 – gvenzl