我们知道,存储函数返回单个值,但我想知道如何在单个结果中显示多个结果。
我用的是northwind数据库。
这是我的函数,它只返回一个值:
CREATE OR REPLACE FUNCTION FN_PRODUCTOS_REGISTRADOS_EN_FECHAS(
FN_ORDER_DATE IN ORDERS.ORDER_DATE%TYPE)
RETURN VARCHAR2
IS
NOMBRE VARCHAR2 (500);
BEGIN
SELECT COMPANY_NAME|| ' ' ||COUNTRY|| ' ' ||PRODUCT_NAME|| ' ' ||ORDER_DATE
AS NOMBRE_DE_COMPAÑIA_PAIS_NOMBRE_PRODUCTO_FECHA_DE_ORDEN
INTO NOMBRE
FROM SUPPLIERS S
INNER JOIN PRODUCTS P ON S.SUPPLIER_ID=P.SUPPLIER_ID
INNER JOIN ORDER_DETAILS OD ON P.PRODUCT_ID=OD.PRODUCT_ID
INNER JOIN ORDERS O ON OD.ORDER_ID=O.ORDER_ID
WHERE ORDER_DATE=FN_ORDER_DATE;
RETURN NOMBRE;
END;
SELECT FN_PRODUCTOS_REGISTRADOS_EN_FECHAS(TO_DATE('07/16/1996','MM/DD/YYYY')) FROM DUAL;
查询如下:
SELECT COMPANY_NAME|| ' ' ||COUNTRY|| ' ' ||PRODUCT_NAME|| ' ' ||ORDER_DATE
AS NOMBRE_DE_COMPAÑIA_PAIS_NOMBRE_DE_PRODUCTO_FECHA_DE_ORDEN
FROM SUPPLIERS S
INNER JOIN PRODUCTS P ON S.SUPPLIER_ID=P.SUPPLIER_ID
INNER JOIN ORDER_DETAILS OD ON P.PRODUCT_ID=OD.PRODUCT_ID
INNER JOIN ORDERS O ON OD.ORDER_ID=O.ORDER_ID
WHERE ORDER_DATE=TO_DATE('07/16/1996','MM/DD/YYYY');
查询返回3行,仅使用查询返回的结果如下:
COMPANY_NAME COUNTRY PRODUCT_NAME NOMBRE_D
---------------------------------------- --------------- ---------------------------------------- --------
Heli Süßwaren GmbH & Co. KG Germany Schoggi Schokolade 16/07/96
Plutzer Lebensmittelgroßmärkte AG Germany Original Frankfurter grüne Soße 16/07/96
Aux joyeux ecclésiastiques France Chartreuse verte 16/07/96
但是使用该函数会返回错误 ORA-01422,我想知道是否可以合并之前的 3 个结果,以便在调用该函数而不是显示错误时它会在单个结果中显示 3 个结果专门使用存储函数进行查询。
我尝试了以下 usando for loop end loop:
CREATE OR REPLACE FUNCTION FN_PRODUCTOS_REGISTRADOS_EN_FECHAS(
FN_ORDER_DATE IN ORDERS.ORDER_DATE%TYPE)
RETURN VARCHAR
IS
NOMBRE VARCHAR (500);
CURSOR LISTA IS
SELECT COMPANY_NAME|| ' ' ||COUNTRY|| ' ' ||PRODUCT_NAME|| ' ' ||ORDER_DATE
AS NOMBRE_DE_COMPAÑIA_PAIS_NOMBRE_PRODUCTO_FECHA_DE_ORDEN
INTO NOMBRE
FROM SUPPLIERS S
INNER JOIN PRODUCTS P ON S.SUPPLIER_ID=P.SUPPLIER_ID
INNER JOIN ORDER_DETAILS OD ON P.PRODUCT_ID=OD.PRODUCT_ID
INNER JOIN ORDERS O ON OD.ORDER_ID=O.ORDER_ID
WHERE ORDER_DATE=FN_ORDER_DATE;
BEGIN
FOR NOMBRE IN LISTA
LOOP
RETURN NOMBRE;
END LOOP;
END;
我得到的错误如下:
LINE/COL ERROR
--------- -------------------------------------------------------------
18/5 PL/SQL: Statement ignored
18/12 PLS-00382: the type of expression is not correct
Errors: check compiler log
好吧,现在我真的迷失了试图找到这个错误的解决方案或替代解决方案。
我不完全确定我理解你的意思,据我了解:
您当前方法的问题是函数中的游标 LISTA 未正确定义。游标需要定义为返回多行和多列的查询,但在您当前的定义中,您包含了一个 INTO 子句,游标不需要它。
要解决这个问题,您可以按如下方式定义光标:
CURSOR LISTA IS
SELECT COMPANY_NAME|| ' ' ||COUNTRY|| ' ' ||PRODUCT_NAME|| ' ' ||ORDER_DATE
AS NOMBRE_DE_COMPAÑIA_PAIS_NOMBRE_PRODUCTO_FECHA_DE_ORDEN
FROM SUPPLIERS S
INNER JOIN PRODUCTS P ON S.SUPPLIER_ID=P.SUPPLIER_ID
INNER JOIN ORDER_DETAILS OD ON P.PRODUCT_ID=OD.PRODUCT_ID
INNER JOIN ORDERS O ON OD.ORDER_ID=O.ORDER_ID
WHERE ORDER_DATE=FN_ORDER_DATE;
然后,您可以使用循环将结果连接成一个字符串,并在循环结束时返回:
CREATE OR REPLACE FUNCTION FN_PRODUCTOS_REGISTRADOS_EN_FECHAS(
FN_ORDER_DATE IN ORDERS.ORDER_DATE%TYPE)
RETURN VARCHAR
IS
NOMBRE VARCHAR (500);
RESULT VARCHAR(4000);
CURSOR LISTA IS
SELECT COMPANY_NAME|| ' ' ||COUNTRY|| ' ' ||PRODUCT_NAME|| ' ' ||ORDER_DATE
AS NOMBRE_DE_COMPAÑIA_PAIS_NOMBRE_PRODUCTO_FECHA_DE_ORDEN
FROM SUPPLIERS S
INNER JOIN PRODUCTS P ON S.SUPPLIER_ID=P.SUPPLIER_ID
INNER JOIN ORDER_DETAILS OD ON P.PRODUCT_ID=OD.PRODUCT_ID
INNER JOIN ORDERS O ON OD.ORDER_ID=O.ORDER_ID
WHERE ORDER_DATE=FN_ORDER_DATE;
BEGIN
RESULT := '';
FOR NOMBRE IN LISTA LOOP
RESULT := RESULT || NOMBRE.NOMBRE_DE_COMPAÑIA_PAIS_NOMBRE_PRODUCTO_FECHA_DE_ORDEN || CHR(10);
END LOOP;
RETURN RESULT;
END;
上面的代码会将每一行的结果连接成一个由换行符分隔的字符串 (CHR(10)) 并返回它。