2015-09-04 95 views
0

我试图从SQL Server移至Oracle数据库。我必须将存储过程从SQL Server移动到Oracle,并使用INNER JOIN从多个表执行查询。我想在这里澄清一些事情。将SQL Server存储过程转换为Oracle过程以从表中查询

SQL Server存储过程:

[dbo].[QueryAll] 
    @score1_min int = 0, 
    @score1_max int = 999, 
    @type1 varchar (1) = '%', 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT * 
    FROM FUNIJ1 uni 
    INNER JOIN CAPI99 api99 on api99.application_id = uni.application_id 
    INNER JOIN CAPI41 api41 on api41.application_id = uni.application_id 
    INNER JOIN CAPI10 api10 on api10.application_id = uni.application_id 
    WHERE 
     api10.score1 BETWEEN @score1_min AND @score1_max 
     AND uni.type1 LIKE @type1 
END 

我的Oracle过程

create or replace PROCEDURE QUERYALL 
(
    SCORE1_MIN IN NUMBER DEFAULT 0 
, SCORE1_MAX IN NUMBER DEFAULT 999 
, TYPE IN VARCHAR2 
) 
AS 
BEGIN 
    SELECT * 
    FROM FUNIJ1 uni 
    INNER JOIN CAPI99 on CAPI99.APPLICATION_ID = uni.APPLICATION_ID 
    INNER JOIN CAPI41 on CAPI41.APPLICATION_ID = uni.APPLICATION_ID 
    INNER JOIN CAPI10 on CAPI10.APPLICATION_ID = uni.APPLICATION_ID 
    WHERE 
     CAPI10.score1 BETWEEN score1_min AND score1_max 
     AND uni.type LIKE type 
END REPOQUERYALL ; 
  1. 我曾经%作为默认的查询参数在没有输入的情况下返回在SQL Server 所有值来自用户。我不确定我必须在Oracle中使用什么作为默认值才能返回所有内容。

  2. 列表项目Oracle正在使用新术语INTO关注SELECT *。我不确定是否需要在这种情况下使用INTO或光标。我不知道这里适合哪种方式以及如何使用它。

  3. 我很感激,如果有人可以将此SQL Server转移到Oracle过程。我不确定我的Oracle是否100%正确。

回答

0

下面是使用Sys_Cursor工作的代码。感谢@TS帮助引导我回答这个问题。

create or replace PROCEDURE QUERYALL 
(
o_Cursor OUT SYS_REFCURSOR 
) 
AS 
BEGIN 
O_Cursor := NULL; 

OPEN O_Cursor FOR 
    SELECT * FROM FUNIJ1 
    INNER JOIN CAPI99 on CAPI99.APPLICATION_ID = FUNIJ1 .APPLICATION_ID 
    INNER JOIN CAPI41 on CAPI41.APPLICATION_ID = FUNIJ1 .APPLICATION_ID 
    INNER JOIN CAPI10 on CAPI10.APPLICATION_ID = FUNIJ1 .APPLICATION_ID 
    WHERE 
    ---- 
    ---- 
END QUERYALL; 

当您在Java中使用此过程来显示表时,您需要将Sys_Cursor调用到Resultset中。

String sp= "{CALL QUERYALL(?)}"; // Procedure calling with Sys_Cursor 
cst = con.prepareCall(sql); 
cst.registerOutParameter(1, OracleTypes.CURSOR); 
cst.executeUpdate(); 
rs = (ResultSet) cst.getObject(1);    
while(rs.next()) { 
---- 
---- 
} 
2

以下是你需要了解Oracle存储过程是什么 - 不像在SQL Server中,你不能只是做SELECT ...任何编程块,除非这是子查询或select... into...

如果目标是从过程返回记录集,则在Oracle中,必须添加Sys_RefCursor输出参数,并使用select语句打开此参考光标。

你不是很远 - check this example。并且记住,当你做Open <cursor_name> FOR ...时,FOR后面的内容可以是动态SQL字符串或只是编译SQL。

+0

谢谢T.S.因此,当我添加'RefCursor'时,那些Oracle示例也会提及IN参数。这是强制性的吗? – SamK

+0

是的。如果你想从Oracle存储过程返回数据,你需要声明'Sys_refcursor'类型的'output'参数来返回这个数据。另一种(类似的)做法是通过声明函数'create或replace Function ... return sys_refcursor'。但它是真的一样的东西。 'Return'只是一种输出参数。所以,如果你使用存储过程,你可以返回多个ref游标。在sql server中,你可以简单地写'select * from t1;从t2选择* - 你有2个结果集。在oracle中,对于每个'select'来返回数据,你需要'sys_refcursor'参数:'Open p1 ..; Open p2' –

+0

'IN'参数只有当你需要它们传递一些东西给SP时。参考光标必须'OUT' –