【问题标题】:Converting function from Oracle PL/SQL to MS SQL Server 2008将函数从 Oracle PL/SQL 转换为 MS SQL Server 2008
【发布时间】:2017-05-19 12:58:27
【问题描述】:

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

我曾尝试使用www.sqlines.com的在线转换工具,并从那里的许多页面中受益...但没有成功转换此功能....

提前致谢,约翰

甲骨文来源:

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 Server 尝试:

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 ;

【问题讨论】:

  • 感谢 scsimon 的格式化帮助!!
  • 现在已经很晚了,我已经喝了我的啤酒,但是这个功能看起来太复杂了,因为它所做的很少——也许你根本不需要它。如果你这样做,它可以做得更短。
  • 虽然我完全同意 Erich 的观点,但我目前还不是这种语言的大师,无法重写它。慢慢地,我正在学习这两种语言,而这个非常长的大型脚本写得非常糟糕。所以我希望剥掉这个洋葱并简化代码。还是一步一个脚印吧?!

标签: oracle sql-server-2008 tsql database-migration


【解决方案1】:

回答关于函数的问题

如果您只想修复光标使其正常工作,一个问题是两个“fetch wp into;”陈述。您是在说“获取数据并将其放入”,然后没有给它任何放入的东西。声明几个变量,将数据放入其中,然后使用变量,而不是代码。对于光标定义中返回的每个项目,您需要一个变量,因此 Office_PHONE_ID 和 IS_PHONE_PRIMARY 各有一个。

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

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 代码的方式工作,它会执行以下操作: 获取第一个标记为主要的电话号码的 id(按顺序)。如果它没有找到其中一个,只需按顺序获取第一个非主要电话号码的 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;

返回@wPhID 就完成了。

我在 order by 中使用了“CASE WHEN IS_PHONE_PRIMARY = 'Y' THEN 0 ELSE 1 END”,因为我不知道其他可能的值,所以这将始终有效。如果您知道唯一可能的值是 'Y' 和 'N',则可以改用以下内容

order by IS_PHONE_PRIMARY DESC, SEQ_NUMBER;

【讨论】:

  • 非常感谢这个 DancingFool。抱歉回复晚了...我没有看到有回复,现在我知道了。我发现了一些你建议我注意和做的事情,但非常感谢你对一般情况的解释。如前所述,我不是 Oracle 人,但是在很多时候,查看从事这些工作的其他功能和查询是草率的、多余的,或者两者兼而有之。再次感谢!
猜你喜欢
  • 1970-01-01
  • 2017-06-03
  • 1970-01-01
  • 2015-12-25
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
  • 2021-06-14
  • 2014-08-24
相关资源
最近更新 更多