将函数从 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;
我有几个类似于下面的 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;