【问题标题】:Table valued function in OracleOracle中的表值函数
【发布时间】:2020-07-08 22:35:23
【问题描述】:

我已经使用 SQL Server 中的函数很长时间了。这些函数可以在FROM 子句中使用,并且可以指定WHERE 子句。 在 SQL Server 中,WHERE 子句用于函数本身。与 Oracle 不同,WHERE 子句在函数产生结果后应用。

如果没有WHERE 的函数返回许多结果,则区别很重要。 此外,在 SQL Server 中,如果 WHERE 应用于具有索引的列,则使用函数内部的索引。

例子:

CREATE TABLE table_test (
col1 varchar(50),
col2 varchar(50)
)

--INSERT TEST DATA
Declare @Id int
Set @Id = 1
While @Id <= 1000000
Begin 
   Insert Into table_test values ('col1' + CAST(@Id as nvarchar(10)), 'col2' + CAST(@Id as nvarchar(10)))
     Set @Id = @Id + 1
End


CREATE FUNCTION func_test() RETURNS TABLE 
AS
RETURN 
(
    SELECT * FROM table_test 
)
GO

CREATE NONCLUSTERED INDEX ixd_test ON table_test (col1) INCLUDE (col2)

SELECT * FROM func_test() WHERE col1 like 'col132%' 

Oracle中有类似的函数吗?

【问题讨论】:

  • 不确定索引部分,但您可以使用 Oracle 中的对象类型定义来获得类似的结果

标签: sql-server oracle


【解决方案1】:

创建表

CREATE TABLE table_test (
    col1 varchar(50),
    col2 varchar(50)
)

将数据填入test_table 后(使用如下所示)

Begin
for i in 1..1000000 loop
   Insert Into table_test values ('col1' || TO_CHAR(i), 'col2' || TO_CHAR(i));
end loop;
commit;
End;
/

以下内容可能会起作用。 (使用 oracle live sql 测试)

-- Create row definition
create OR REPLACE TYPE SOME_ROW_TYPE AS OBJECT
(
    COL1 varchar2(50),
    COL2 varchar2(50)
)
/
-- Create table definition
create type SOME_TABLE_TYPE as table of SOME_ROW_TYPE
/


CREATE OR REPLACE FUNCTION DoStuff RETURN SOME_TABLE_TYPE AS
-- Declarations
RET_TABLE SOME_TABLE_TYPE := SOME_TABLE_TYPE();
CURSOR DATA_FETCH IS
    SELECT
        COL1,
        COL2
    FROM TABLE_TEST;
BEGIN
FOR ITEM IN DATA_FETCH LOOP
RET_TABLE.extend;
RET_TABLE(RET_TABLE.LAST) := SOME_ROW_TYPE(
    ITEM.COL1,
    ITEM.COL2);
END LOOP;


RETURN RET_TABLE;
END;
/

创建索引

CREATE INDEX index_name ON table_test(col1)

获取方式

select * from DoStuff() WHERE col1 like 'col132%' 

【讨论】:

  • 最好让这个函数“流水线化”:orasql.org/2017/12/13/…
  • 我在列 col1 上创建了一个索引,如 Sql Server 上的示例所示。该函数首先返回所有数据,然后对其进行过滤。我希望 Oracle 上的函数能够像 Sql Server 一样使用函数内部的索引。
  • 当您查看 sql server 示例时,我相信索引是在函数范围之外创建的。很高兴犯错。函数声明的范围从CREATE FUNCTION 开始,到GO 结束。之后,您在实际表 table_test 本身上创建了一个索引
  • 更改答案以与您在 sql server 中所做的几乎匹配。看看@SayanMalakshinov 提到的使用“流水线”来提高性能
猜你喜欢
  • 1970-01-01
  • 2022-11-14
  • 2011-10-09
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
相关资源
最近更新 更多