Oracle SQL。用户定义的函数不会在 SELECT 语句中运行,但如果包装在过程中则会运行

0 sql oracle types plsql function

我在选民登记册上有一个 oracleSQL 数据库。为了检查选民之前是否投票过,我创建了一个PreviouslyVoted(election_code, electorate_code, voter_id)如下所示的函数。

create or replace FUNCTION previouslyVoted(election_code_in IN NUMBER, electorate_id_in IN NUMBER, voter_id_in IN NUMBER)
RETURN BOOLEAN IS
voter_id_temp NUMBER;
BEGIN
    SELECT COUNT(*) INTO voter_id_temp
    FROM ballot_issuance bi
    WHERE bi.electorate_id = electorate_id_in
    AND bi.election_serial_number = election_code_in
    AND bi.voter_id = voter_id_in;

RETURN voter_id_temp > 0 ;
END;
Run Code Online (Sandbox Code Playgroud)

现在我想从 PHP 服务器调用它。

我尝试运行发送以下查询:

Select previouslyVoted(" .ELECTION ."," .ELECTORATE .", $oracle_voter_id) "Result" FROM dual;
Run Code Online (Sandbox Code Playgroud)

这没有用。我收到以下错误:

ORA-00902: invalid datatype
00902. 00000 -  "invalid datatype"
*Cause:    
*Action:
Error at Line: 1 Column: 8
Run Code Online (Sandbox Code Playgroud)

我尝试去 sqldeveloper 并运行

Select previouslyVoted(20190404,1,13321) "Result" FROM dual;
Run Code Online (Sandbox Code Playgroud)

再次出现同样的错误。我尝试将表达式扩展为

SELECT
    "S4026115"."PREVIOUSLYVOTED"(20190404, 1, 13321) "Result"
FROM
    "SYS"."DUAL" "A1";
Run Code Online (Sandbox Code Playgroud)

但再次出现同样的错误。有趣的是:如果我将其包装在如下所示的过程中,它就完全可以正常工作。

create or replace PROCEDURE runprevvoted
AS
   has_voted BOOLEAN;
BEGIN
   has_voted := previouslyVoted(20190404, 1, 13321);
   IF has_voted THEN
      DBMS_OUTPUT.PUT_LINE('This voter has previously voted.');
   ELSE
      DBMS_OUTPUT.PUT_LINE('This voter has not previously voted.');
   END IF;
END;
Run Code Online (Sandbox Code Playgroud)

希望有人能帮助我了解我做错了什么!先感谢您

Koe*_*rie 5

您在问题开头调用函数“previouslyVoted”,但在包装器中引用“has_voted”。我假设它们是相同的?问题很可能是该函数返回布尔值,而 SQL 在 23c 之前没有布尔数据类型。pl/sql 确实有布尔数据类型。所以发生的情况是 pl/sql 函数成功执行,但 SQL 语句由于不知道数据类型而出错。

例子:

koen19c>set serveroutput on size 999999
koen19c>CREATE OR REPLACE FUNCTION istrue RETURN BOOLEAN
  2  AS
  3  BEGIN
  4    RETURN true;
  5  END;
  6* /

Function ISTRUE compiled

koen19c>BEGIN 
  2    IF istrue() THEN
  3      dbms_output.put_line('it is true !');
  4    END IF;
  5  END;
  6* /
it is true !


PL/SQL procedure successfully completed.

koen19c>SELECT istrue() from dual;

Error starting at line : 1 in command -
SELECT istrue() from dual
Error at Command Line : 1 Column : 8
Error report -
SQL Error: ORA-00902: invalid datatype
00902. 00000 -  "invalid datatype"
*Cause:    
*Action:
koen19c>
Run Code Online (Sandbox Code Playgroud)

解决方案,修改函数,使其返回字符串('Y'/'N'、'true'/'false')或数字(1/0)