在SQL Server中重写Oracle函数

时间:2019-06-11 16:32:41

标签: sql-server oracle

我有一个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的帮助将不胜感激。

2 个答案:

答案 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中编写过存储过程,但是无论如何,您会明白的。