代码之家  ›  专栏  ›  技术社区  ›  Ziad Adnan

在%type类型的函数中声明变量时,如何使用远程数据库连接?

  •  0
  • Ziad Adnan  · 技术社区  · 1 年前

    我想使用数据库链接和oracle apex通过oracle数据库19c连接到oracle数据库10g,我有这个功能:

    create or replace FUNCTION AUTHENTICATE_USER
    
      (p_username in varchar2, 
    
       p_password in varchar2)
    
    return boolean
    
    is
    
      l_user_name       sys_users.user_id%type    := upper(p_username);
    
      l_password        sys_users.user_password%type;
    
      l_hashed_password varchar2(1000);
    
      l_count           number;
    
    begin
    
    -- Returns from the AUTHENTICATE_USER function 
    
    --    0    Normal, successful authentication
    
    --    1    Unknown User Name
    
    --    2    Account Locked
    
    --    3    Account Expired
    
    --    4    Incorrect Password
    
    --    5    Password First Use
    
    --    6    Maximum Login Attempts Exceeded
    
    --    7    Unknown Internal Error
    
    --
    
    -- First, check to see if the user exists
    
        select count(*) 
    
          into l_count 
    
          from sys_users@kaash1
    
          where user_name = l_user_name;
    
          
    
         if l_count > 0 then
    
              -- Hash the password provided
    
              l_hashed_password := hash_password(l_user_name, p_password);
    
     
    
              -- Get the stored password
    
              select user_password 
    
                into l_password 
    
                from sys_users@kaash1
    
               where user_name = l_user_name;
    
      
    
              -- Compare the two, and if there is a match, return TRUE
    
              if l_hashed_password = l_password then
    
                  -- Good result. 
    
                  APEX_UTIL.SET_AUTHENTICATION_RESULT(0);
    
                  return true;
    
              else
    
                  -- The Passwords didn't match
    
                  APEX_UTIL.SET_AUTHENTICATION_RESULT(4);
    
                  return false;
    
              end if;
    
      
    
        else
    
              -- The username does not exist
    
              APEX_UTIL.SET_AUTHENTICATION_RESULT(1);
    
              return false;
    
        end if;
    
        -- If we get here then something weird happened. 
    
        APEX_UTIL.SET_AUTHENTICATION_RESULT(7);
    
        return false;
    
    exception 
    
        when others then 
    
            -- We don't know what happened so log an unknown internal error
    
            APEX_UTIL.SET_AUTHENTICATION_RESULT(7);
    
            -- And save the SQL Error Message to the Auth Status.
    
            APEX_UTIL.SET_CUSTOM_AUTH_STATUS(sqlerrm);
    
            return false;
    
            
    
    end authenticate_user;
    /
    

    现在我只运行SELECT语句及其工作

    但功能不起作用

    其中我将把远程数据库名称kaash1添加到以下变量中:

     l_user_name       sys_users.user_name%type    := upper(p_username);
        
     l_password        sys_users.user_password%type;
    

    我运行也是为了检查SQL中的函数 select语句返回值,但当运行函数时,我得到错误的无效数据类型

    第1/8行出错:ORA-00902:无效的数据类型

    select AUTHENTICATE_USER('admin','2023') FROM dual;
    

    如何解决这个错误并运行函数?

    1 回复  |  直到 1 年前
        1
  •  1
  •   Littlefoot    1 年前

    无效的数据类型 这个错误是由于SQL级别并没有布尔数据类型——您只能在PL/SQL中使用它。

    简化后,这就是您所拥有的:

    SQL> create or replace function f_Test
      2    return boolean is
      3  begin
      4    return true;
      5  end;
      6  /
    
    Function created.
    

    正如您已经注意到的,您不能在SQL级别使用它:

    SQL> select f_test from dual;
    select f_test from dual
           *
    ERROR at line 1:
    ORA-00902: invalid datatype
    

    但是,在PL/SQL中,它是有效的:

    SQL> set serveroutput on
    SQL> begin
      2    dbms_output.put_line(case when f_test then 'result is true'
      3                              else 'result is false'
      4                         end);
      5  end;
      6  /
    result is true
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    或者,如果您确实需要在SQL级别使用该函数,请修改该函数,使其返回另一个数据类型,例如。

    • NUMBER ,这样你就可以回来了 1 对于 真的 0 对于 虚假的
    • VARCHAR2 ,所以你会回来 Y 对于 真的 N 对于 虚假的
    • 或您认为合适的任何其他选项

    在声明一个通过数据库链接引用列数据类型的变量时:

    l_user_name sys_users.user_name@kaash1%type;