如何从一个函数中 return 多个 ID
How to return multiple ID’s from a function
我需要从一个基于输入的函数中 return table 的 ID。
Create or replace function f(v_input nvarchar)
Return v_table
Is
Select id bulk collect into v_table from table1 where user=v_input ;
Return v_table
End;
并且此函数将在 sql 查询中调用,例如
Select * from table2 where id in (f(abc));
这是概念。
我们如何在 oracle 中以编程方式执行此操作?如何从一个函数 return 多个记录 ID?
你需要:
BEGIN
关键字在IS
和主块的开始之间。
- 在
IS
和 BEGIN
之间 BULK COLLECT INTO
的变量声明。
- return 类型不是变量名。
- a semi-colon 终止 reutrn 语句。
NVARCHAR
应该是 NVARCHAR2
.
USER
是一个保留字,您不应该将它用作列名;如果你这样做,它必须作为带引号的标识符。
像这样:
Create or replace function f(v_input nvarchar2)
Return t_table
Is
v_table t_table;
BEGIN
Select id bulk collect into v_table from table1 where "USER"=v_input ;
Return v_table;
End;
/
那么,如果你已经创建了这些:
CREATE TYPE t_table IS TABLE OF INTEGER;
CREATE TABLE table1 (id INTEGER, "USER" NVARCHAR2(20));
INSERT INTO table1 (id, "USER")
SELECT 1, N'user1' FROM DUAL UNION ALL
SELECT 2, N'user1' FROM DUAL UNION ALL
SELECT 2, N'user2' FROM DUAL UNION ALL
SELECT 3, N'user3' FROM DUAL;
CREATE TABLE table2 (id) AS
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 5;
然后:
Select * from table2 where id MEMBER OF f('user1');
或
Select * from table2 where id IN (SELECT COLUMN_VALUE FROM TABLE(f('user1')));
输出:
ID
1
2
db<>fiddle here
在 Oracle 19c 19.7 及更高版本中,您可以使用 SQL_MACRO 概念来实现此目的,即参数化查询。
如您所见,它已合并到主查询中。
create function f_get_ids(p_user in varchar2)
return varchar2
sql_macro(table)
as
begin
return q'[select id from table1 where user_name = p_user]';
end;
/
select *
from table2
where id in (select id from f_get_ids('User 1'))
ID | DATA_
-: | :----
1 | 001
select *
from dbms_xplan.display_cursor(format => 'TYPICAL')
| PLAN_TABLE_OUTPUT |
| :---------------------------------------------------------------------------- |
| SQL_ID 9ns9x68zjtvhy, child number 0 |
| ------------------------------------- |
| select * from table2 where id in (select id from f_get_ids('User 1')) |
| |
| Plan hash value: 2946371633 |
| |
| ----------------------------------------------------------------------------- |
| | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | |
| ----------------------------------------------------------------------------- |
| | 0 | SELECT STATEMENT | | | | 6 (100)| | |
| |* 1 | HASH JOIN SEMI | | 1 | 17 | 6 (0)| 00:00:01 | |
| | 2 | TABLE ACCESS FULL| TABLE2 | 4 | 28 | 3 (0)| 00:00:01 | |
| |* 3 | TABLE ACCESS FULL| TABLE1 | 1 | 10 | 3 (0)| 00:00:01 | |
| ----------------------------------------------------------------------------- |
| |
| Predicate Information (identified by operation id): |
| --------------------------------------------------- |
| |
| 1 - access("ID"="ID") |
| 3 - filter("USER_NAME"='User 1') |
| |
db<>fiddle here
我需要从一个基于输入的函数中 return table 的 ID。
Create or replace function f(v_input nvarchar)
Return v_table
Is
Select id bulk collect into v_table from table1 where user=v_input ;
Return v_table
End;
并且此函数将在 sql 查询中调用,例如
Select * from table2 where id in (f(abc));
这是概念。
我们如何在 oracle 中以编程方式执行此操作?如何从一个函数 return 多个记录 ID?
你需要:
BEGIN
关键字在IS
和主块的开始之间。- 在
IS
和BEGIN
之间BULK COLLECT INTO
的变量声明。 - return 类型不是变量名。
- a semi-colon 终止 reutrn 语句。
NVARCHAR
应该是NVARCHAR2
.USER
是一个保留字,您不应该将它用作列名;如果你这样做,它必须作为带引号的标识符。
像这样:
Create or replace function f(v_input nvarchar2)
Return t_table
Is
v_table t_table;
BEGIN
Select id bulk collect into v_table from table1 where "USER"=v_input ;
Return v_table;
End;
/
那么,如果你已经创建了这些:
CREATE TYPE t_table IS TABLE OF INTEGER;
CREATE TABLE table1 (id INTEGER, "USER" NVARCHAR2(20));
INSERT INTO table1 (id, "USER")
SELECT 1, N'user1' FROM DUAL UNION ALL
SELECT 2, N'user1' FROM DUAL UNION ALL
SELECT 2, N'user2' FROM DUAL UNION ALL
SELECT 3, N'user3' FROM DUAL;
CREATE TABLE table2 (id) AS
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 5;
然后:
Select * from table2 where id MEMBER OF f('user1');
或
Select * from table2 where id IN (SELECT COLUMN_VALUE FROM TABLE(f('user1')));
输出:
ID 1 2
db<>fiddle here
在 Oracle 19c 19.7 及更高版本中,您可以使用 SQL_MACRO 概念来实现此目的,即参数化查询。
如您所见,它已合并到主查询中。
create function f_get_ids(p_user in varchar2) return varchar2 sql_macro(table) as begin return q'[select id from table1 where user_name = p_user]'; end; /
select * from table2 where id in (select id from f_get_ids('User 1'))
ID | DATA_ -: | :---- 1 | 001
select * from dbms_xplan.display_cursor(format => 'TYPICAL')
| PLAN_TABLE_OUTPUT | | :---------------------------------------------------------------------------- | | SQL_ID 9ns9x68zjtvhy, child number 0 | | ------------------------------------- | | select * from table2 where id in (select id from f_get_ids('User 1')) | | | | Plan hash value: 2946371633 | | | | ----------------------------------------------------------------------------- | | | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | | | ----------------------------------------------------------------------------- | | | 0 | SELECT STATEMENT | | | | 6 (100)| | | | |* 1 | HASH JOIN SEMI | | 1 | 17 | 6 (0)| 00:00:01 | | | | 2 | TABLE ACCESS FULL| TABLE2 | 4 | 28 | 3 (0)| 00:00:01 | | | |* 3 | TABLE ACCESS FULL| TABLE1 | 1 | 10 | 3 (0)| 00:00:01 | | | ----------------------------------------------------------------------------- | | | | Predicate Information (identified by operation id): | | --------------------------------------------------- | | | | 1 - access("ID"="ID") | | 3 - filter("USER_NAME"='User 1') | | |
db<>fiddle here