将函数从 Oracle PL/SQL 转换为 MS SQL Server 2008

Converting function from Oracle PL/SQL to MS SQL Server 2008

我有几个类似于下面的 Oracle 函数。我对 Oracle 了解不多,尽管我已经在重写主要查询的道路上取得了进展。我想寻求一些关于如何将此功能转换为 SQL Server 2008 的帮助。

我试过使用 www.sqlines.com 的在线转换工具,并从那里的许多页面中获益...但未能成功转换此功能....

提前致谢,约翰

Oracle 来源:

function OfficeIDMainPhoneID(p_ID t_OfficeID)
return t_OfficePhoneID
is
    wPhID  t_OfficePhoneID;
    wPhID1 t_OfficePhoneID;
    cursor cr_phone
    is
    select Office_PHONE_ID,IS_PHONE_PRIMARY
    from Office_PHONE
    where Office_ID = p_ID
    order by SEQ_NUMBER;
    begin
    wPhID :=NULL;
    wPhID1:=NULL;
    for wp in cr_phone
    loop
    if wPhID is NULL
    then wPhID1:=wp.Office_PHONE_ID;
    end if;
    if wp.IS_PHONE_PRIMARY = 'Y'
    then
    wPhID:=wp.Office_PHONE_ID;
    Exit;
    end if;
    end loop;
    if wPhID is NULL
    then wPhID:=wPhID1;
    end if;
    return(wPhID);
    end OfficeIDMainPhoneID;

SQL 服务器尝试:

create function OfficeIDMainPhoneID(@p_ID t_OfficeID)
returns t_OfficePhoneID
as
begin
    declare @wPhID  t_OfficePhoneID;
    declare @wPhID1 t_OfficePhoneID;
  declare cr_phone cursor local
  for
    select Office_PHONE_ID,IS_PHONE_PRIMARY
    from Office_PHONE
    where Office_ID = @p_ID
    order by SEQ_NUMBER;

    set @wPhID =NULL;
    set @wPhID1=NULL;
    declare wp cursor for cr_phone
    open wp;
    fetch wp into;
    while @@fetch_status=0
    begin
      if @wPhID is NULL
      begin set @wPhID1=wp.Office_PHONE_ID;
      end 
      if wp.IS_PHONE_PRIMARY = 'Y'
      begin
        set @wPhID=wp.Office_PHONE_ID;
        Exit;
      end 
    fetch wp into;
    end;
    close wp;
    deallocate wp;
    if @wPhID is NULL
    begin set @wPhID=@wPhID1;
  end 
  return(@wPhID);
  end ;

回答关于函数的问题

如果您只是想修复游标使其正常工作,一个问题是两个 "fetch wp into;" 语句。你说的是 "fetch the data and put it into" 然后没有给它任何东西来放入它。声明几个变量,将数据放入其中,然后使用变量,而不是代码。游标定义中返回的每个项目都需要一个变量,因此 Office_PHONE_ID 和 IS_PHONE_PRIMARY.

各一个

此外,您正在尝试将变量(和函数)声明为 t_OfficePhoneID,我怀疑应该是 INT OR BIGINT 之类的东西(无论该列的 table 定义是什么) .

Declare @OP_ID INT, @ISPRIMARY CHAR(1) --Or whatever the column is

稍后(在两个位置),

fetch wp into (@OP_ID, @ISPRIMARY);

然后使用@OP_ID代替wp.Office_PHONE_ID,依此类推。

但是,我会在声明@wPhID 后丢弃函数中的所有代码,然后做其他事情。如果你可以通过一个简单的基于集合的请求得到你想要的,那么游标就很糟糕了。如果您按自己的方式处理 oracle 代码,它会执行以下操作: 获取标记为主要(按顺序)的第一个 phone 号码的 ID。如果它没有找到其中一个,只需按顺序获取第一个非主要 phone 号码的 ID。您可以使用以下

set @wPhID = select TOP 1 Office_PHONE_ID
from Office_PHONE
where Office_ID = @p_ID
order by CASE WHEN IS_PHONE_PRIMARY = 'Y' THEN 0 ELSE 1 END, SEQ_NUMBER;

Return @wPhID 大功告成。

我在 order by 中使用了 "CASE WHEN IS_PHONE_PRIMARY = 'Y' THEN 0 ELSE 1 END" 因为我不知道还有哪些其他值是可能的,所以这将始终有效。如果你知道唯一可能的值是 'Y' 和 'N',你可以使用类似下面的东西来代替

order by IS_PHONE_PRIMARY DESC, SEQ_NUMBER;