我正在将一个函数从Oracle迁移到SQL Server 2008.此函数引发函数中包含的SELECT
语句无法将数据作为错误返回给客户端。我该如何解决这个问题?
原始PLSQL代码
CREATE OR REPLACE function f_birim_cevrim_katsayi (p_ID_MAMUL in number, p_ID_BIRIMDEN in number, p_ID_BIRIME in number)
return number
is
v_katsayi number;
begin
v_katsayi:=0;
if p_ID_BIRIMDEN!=p_ID_BIRIME then
for c in (
select * from CR_BIRIM_CEVRIM
where ID_MAMUL = p_ID_MAMUL
and (
(ID_BIRIM = p_ID_BIRIMDEN and ID_BIRIM2 = p_ID_BIRIME)
OR ( ID_BIRIM2 = p_ID_BIRIMDEN and ID_BIRIM = p_ID_BIRIME) )
and VALID = 1)
loop
if c.ID_BIRIM=p_ID_BIRIMDEN then
v_katsayi:=c.MT_ORAN;
else
v_katsayi:=1/c.MT_ORAN;
end if;
end loop;
else
v_katsayi:=1;
end if;
return round(v_katsayi,10);
exception
when others then
return 0;
end;
T-SQL代码:
If Exists ( SELECT name
FROM sysobjects
WHERE name = 'f_birim_cevrim_katsayi'
AND type = 'FN')
DROP FUNCTION f_birim_cevrim_katsayi
GO
CREATE FUNCTION f_birim_cevrim_katsayi
(
@p_ID_MAMUL FLOAT ,
@p_ID_BIRIMDEN FLOAT ,
@p_ID_BIRIME FLOAT
)
RETURNS float
AS
BEGIN
DECLARE @adv_error INT
DECLARE @v_katsayi FLOAT
SELECT @v_katsayi = 0
IF @p_ID_BIRIMDEN != @p_ID_BIRIME
BEGIN
DECLARE cursor_for_inline_select1 CURSOR LOCAL FOR
SELECT *
FROM CR_BIRIM_CEVRIM
WHERE ID_MAMUL = @p_ID_MAMUL
AND ((ID_BIRIM = @p_ID_BIRIMDEN
AND ID_BIRIM2 = @p_ID_BIRIME)
OR (ID_BIRIM2 = @p_ID_BIRIMDEN
AND ID_BIRIM = @p_ID_BIRIME))
AND VALID = 1
OPEN cursor_for_inline_select1
FETCH NEXT FROM cursor_for_inline_select1
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF c.ID_BIRIM = @p_ID_BIRIMDEN
BEGIN
SELECT @v_katsayi = c.MT_ORAN
END
ELSE
BEGIN
SELECT @v_katsayi = 1/c.MT_ORAN
END
END
CLOSE cursor_for_inline_select1
DEALLOCATE cursor_for_inline_select1
END
ELSE
BEGIN
SELECT @v_katsayi = 1
END
DEALLOCATE cursor_for_inline_select1
return ROUND(@v_katsayi, 10)
GOTO ExitLabel1
Exception1:
BEGIN
DEALLOCATE cursor_for_inline_select1
return 0
END
ExitLabel1:
return ROUND(@v_katsayi, 10)
END
GO
答案 0 :(得分:1)
引用本地的游标操作 声明,打开的游标, 关闭,并取消分配 功能。只有FETCH语句 使用赋值给局部变量赋值 允许INTO条款;取 将数据返回给的语句 不允许客户
这意味着这是错误的
DECLARE cursor_for_inline_select1 CURSOR LOCAL FOR
SELECT *
FROM CR_BIRIM_CEVRIM
WHERE ID_MAMUL = @p_ID_MAMUL
AND ((ID_BIRIM = @p_ID_BIRIMDEN
AND ID_BIRIM2 = @p_ID_BIRIME)
OR (ID_BIRIM2 = @p_ID_BIRIMDEN
AND ID_BIRIM = @p_ID_BIRIME))
AND VALID = 1
您没有将CURSOR输出分配给局部变量。
请描述您想要对样本数据做什么:我确定这是一个带CASE的简单SELECT
编辑:除非我的pl / sql 方式关闭
,否则你不需要CURSORCREATE FUNCTION f_birim_cevrim_katsayi (
@p_ID_MAMUL FLOAT ,
@p_ID_BIRIMDEN FLOAT ,
@p_ID_BIRIME FLOAT
)
RETURNS float
AS
BEGIN
DECLARE @v_katsayi FLOAT;
IF @p_ID_BIRIMDEN != @p_ID_BIRIME
BEGIN
SELECT
@v_katsayi = CASE
WHEN ID_BIRIM = @p_ID_BIRIMDEN THEN c.MT_ORAN
ELSE 1/c.MT_ORAN
END
FROM
CR_BIRIM_CEVRIM c
WHERE
ID_MAMUL = @p_ID_MAMUL
AND ((ID_BIRIM = @p_ID_BIRIMDEN
AND ID_BIRIM2 = @p_ID_BIRIME)
OR (ID_BIRIM2 = @p_ID_BIRIMDEN
AND ID_BIRIM = @p_ID_BIRIME))
AND VALID = 1;
END
RETURN ROUND(ISNULL(@v_katsayi, 1), 10);
END
GO
答案 1 :(得分:-1)
尝试更改这两行
SELECT @v_katsayi = 0
SELECT @v_katsayi = 1
到
SET @v_katsayi = 0
SET @v_katsayi = 1
错过了其他几个人。无论您使用SELECT来设置变量值,只需更改为SET ...
另外:更改光标以抓取字段并将其放入变量
DECLARE @theID FLOAT
DECLARE @theORAN FLOAT
DECLARE cursor_for_inline_select1 CURSOR LOCAL FOR
SELECT id_birim,MT_ORAN -- Fields name instead of *
FROM CR_BIRIM_CEVRIM
WHERE ID_MAMUL = @p_ID_MAMUL
AND ((ID_BIRIM = @p_ID_BIRIMDEN
AND ID_BIRIM2 = @p_ID_BIRIME)
OR (ID_BIRIM2 = @p_ID_BIRIMDEN
AND ID_BIRIM = @p_ID_BIRIME))
AND VALID = 1
OPEN cursor_for_inline_select1
-- Put field value into variable
FETCH NEXT FROM cursor_for_inline_select1 INTO @theID,@theORan
WHILE (@@FETCH_STATUS <> -1)
BEGIN
-- Compare variable rather than field directly
IF @theID = @p_ID_BIRIMDEN
BEGIN
SELECT @v_katsayi = @theORan
END
ELSE
BEGIN
SELECT @v_katsayi = 1/@theORan
END
END
CLOSE cursor_for_inline_select1
DEALLOCATE cursor_for_inline_select1