1

我有一个返回 3 条记录的 sql

select emp_no from employees where dept_no='S3407'

结果

1089
2092
1999 

我需要在函数中使用上述 SQL,并且函数应该返回所有三个值。我想在另一个 sql 语句中使用这个函数,如下所示

select * from emp_history where emp_no in ('1089','2092','1999');

在上面的 sql 中,我想使用该函数而不是硬编码的员工编号。

实现这一目标的最佳方法是什么?

由于查询非常复杂,因为我上面提到的只是查询的一个示例,因为无法将完整的查询粘贴到此处。所以我需要使用一个函数来实现这一点。

任何帮助都是非常可观的。

问候

4

4 回答 4

1

您可以使用视图:

create view vw_MyView 
as
select  emp_no 
from    employees 
where   dept_no = 'S3407'

您可以在第二个查询中使用该视图:

select * from emp_history where emp_no in (select emp_no from vw_MyView);
于 2012-09-17T07:11:28.263 回答
1

我建议您考虑 Andomar 的建议,原因如下: 1. 视图允许提供足够级别的封装 2. CBO 几乎可以完美地与视图配合使用,因此您的查询将根据记录数量或多或少地可预测地工作。

一旦用函数替换视图,您将面临 CBO 无法估计函数的基数的情况,因此您必须提交完整扫描或实施某种包以计算函数的基数。

所以 +`1 到 Andomar

当然,您可以使用流水线函数并将查询重写为

 select * from emp_history where emp_no in (select * from table(your pipelined function))

但正如我之前解释的那样,这不是最好的方法

您可以在链接http://www.oracle-base.com/articles/misc/pipelined-table-functions.php中找到关于流水线函数的完美文章(我认为)

于 2012-09-17T07:17:57.247 回答
0

您可以在不使用函数的情况下创建子查询。

SELECT *
FROM   emp_history
WHERE  emp_no IN 
        (
            SELECT emp_no
            FROM employees
            WHERE dept_no = 'S3407'
        );
于 2012-09-17T07:05:52.010 回答
0

您可以尝试使用以下方法。

CREATE FUNCTION GetEmpNos 
(   
    @dept_no varchar(10)
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT emp_no from employees Where dept_no = @dept_no
)
GO

并像下面这样使用这个功能。

select * from emp_history where emp_no in (select * from dbo.GetEmpNos('S3407'));

对于 oracle 10g,尝试使用以下代码。

CREATE TYPE my_emp_type_coll IS TABLE OF my_emp_type; 
/ 

CREATE OR REPLACE FUNCTION get_emp_no (p_dept_no IN VARCHAR(10))  
RETURN my_emp_type_coll PIPELINED IS 
BEGIN 
  FOR emp IN (SELECT * FROM employees WHERE dept_no=p_dept_no) LOOP 
  PIPE ROW(my_emp_type(emp.emp_no)); 
  END LOOP; 
  RETURN; 
END; 
/ 

SELECT * FROM emp_history WHERE emp_no IN (SELECT * FROM TABLE(get_emp_no('S3407'))); 
于 2012-09-17T07:36:51.360 回答