我有一个Oracle函数,需要转换为SQL-Server函数
这是Oracle功能:
FUNCTION check_education(in_crs_code IN VARCHAR2)
RETURN BOOLEAN IS
v_bool BOOLEAN := FALSE;
v_dummy VARCHAR2(1);
CURSOR find_education IS
SELECT 'x'
FROM KU_LIBRARY_EDUCATION_EXTLOAN
WHERE UPPER(course_code) = UPPER(in_crs_code) AND in_use = 'Y';
BEGIN
OPEN find_education;
FETCH find_education INTO v_dummy;
IF find_education%FOUND THEN
v_bool := TRUE;
ELSE
v_bool := FALSE;
END IF;
CLOSE find_education;
RETURN (v_bool);
END check_education;
这是我在SQL Server中编写的用于复制Oracle函数的内容:
CREATE FUNCTION [dbo].[check_education](@in_crs_code VARCHAR(4000))
RETURNS BIT AS
BEGIN
DECLARE @v_bool BIT = 0;
DECLARE @v_dummy VARCHAR(1);
DECLARE find_education CURSOR LOCAL FOR
SELECT 'x'
FROM [dbo].[KU_LIBRARY_EDUCATION_EXTLOAN]
WHERE UPPER(course_code) = UPPER(@in_crs_code)
AND in_use = 'Y';
OPEN find_education;
FETCH find_education INTO @v_dummy;
IF @@CURSOR_ROWS >1 BEGIN
SET @v_bool = 1;
END
ELSE BEGIN
SET @v_bool = 0;
END
CLOSE find_education;
DEALLOCATE find_education;
RETURN (@v_bool);
END;
如果光标返回“ x”,但我得到0,我希望SQL Server函数返回1。Anu的帮助将不胜感激。
答案 0 :(得分:1)
我建议使用内联表值函数而不是标量函数。为了确保这是一个内联表值函数,它必须是单个select语句。这意味着不能有循环和其他东西。幸运的是,该查询实际上不需要任何循环。一个简单的计数将返回行数。当转换为一位时,除0以外的任何其他值始终为1。
CREATE FUNCTION [dbo].[check_education]
(
@in_crs_code VARCHAR(4000)
) RETURNS table as return
SELECT CourseExists = convert(bit, count(*))
FROM [dbo].[KU_LIBRARY_EDUCATION_EXTLOAN]
WHERE UPPER(course_code) = UPPER(@in_crs_code)
AND in_use = 'Y';
答案 1 :(得分:-1)
这仅仅是EXISTS
,所以我们可以尝试
CREATE FUNCTION [dbo].[check_education](@in_crs_code VARCHAR(4000)) RETURNS BIT AS
BEGIN
RETURN EXISTS ( <query> )
END;
但是据我所知,SQL Server不接受这一点(尽管我不能说为什么不这样做-也许是因为它们缺少真正的布尔值; Oracle不接受它,因为EXISTS
是在他们的PL / SQL编程语言中没有关键字。)
因此,我们将使用IF
/ THEN
/ ELSE
:
CREATE FUNCTION [dbo].[check_education](@in_crs_code VARCHAR(4000)) RETURNS BIT AS
BEGIN
IF EXISTS
(
SELECT 'x'
FROM ku_library_education_extloan
WHERE UPPER(course_code) = UPPER(in_crs_code) AND in_use = 'Y'
)
RETURN 1
ELSE
RETURN 0
END
END;
可能会有错误,因为我从未在T-SQL中编写过存储过程,但是无论如何,您会明白的。