【问题标题】:Exact fetch returns more than requested number of rows, PL/SQL精确提取返回超过请求的行数,PL/SQL
【发布时间】:2018-08-30 18:18:39
【问题描述】:

这是我尝试过的代码

SET SERVEROUTPUT ON;
ACCEPT input_accountNumber NUMBER PROMPT 'Enter the account number : '
ACCEPT input_branch CHAR PROMPT 'Enter the branch : '

CREATE FUNCTION activeAccounts
RETURN NUMBER    IS
  accountNumber NUMBER;
BEGIN
  FOR rec IN (SELECT account_number, branch FROM ACCOUNT_DATA WHERE status='Active') 
  LOOP
    INSERT INTO ACTIVE_ACCOUNTS VALUES (rec.account_number,rec.branch);
  END LOOP;
END;
/

DECLARE
  accountStatus VARCHAR(20);
  inputuser_accountNumber NUMBER;
  inputuser_branch VARCHAR(20);
  cf varchar(20);
BEGIN
  inputuser_accountNumber := '&input_accountNumber';
  inputuser_branch := '&input_branch';
  SELECT status INTO accountStatus FROM ACCOUNT_DATA;
  IF (accountStatus = 'Active') THEN
    cf := activeAccounts();
  ELSE
    DBMS_OUTPUT.PUT_LINE('The account is Inactive.');
  END IF;
END;
/

问题陈述是

在 PL/SQL 中为给定的需求编写一个存储函数,并在 PL/SQL 中使用相同的函数 堵塞。 户口号码。并且分支名称将被用户接受。将在中搜索相同的内容 表 acct_details。如果帐户状态处于活动状态,则显示适当的消息以及 将帐户详细信息存储在 active_acc_details 表中,否则在屏幕上显示消息 “帐户处于非活动状态”。

错误是

错误报告 - ORA-01422:精确提取返回的数量超过请求的数量 行数

ORA-06512:第 9 行

  1. 00000 - “精确提取返回的行数超过了请求的行数” *原因:exact fetch 中指定的数字小于返回的行数。 *操作:重写查询或更改请求的行数

【问题讨论】:

  • 您的 ACCOUNT_DATA 表可能不止一行。因此您不能在 varchar 类型的单个变量中选择更多值。你应该选择数组或只选择一个值
  • 你的函数不会return 任何东西,因为return 语句丢失。如果您的意图只是插入记录,您可以使用Procedures

标签: plsql


【解决方案1】:

您的代码中几乎没有可以纠正的缺陷,并且您的代码可以正常工作。首先根据您的问题陈述:

帐号并且分支名称将被用户接受。同样的意志 在表 acct_details 中进行搜索。

这意味着您的Select 查询必须有一些过滤条件来选择用户输入的唯一记录。

此外,您的代码中无需包含函数,而是更适合的过程。您需要以下内容:

--Passing the record to proc to store records to details table.
CREATE OR REPLACE PROCEDURE activeaccounts (v_acct_num number, v_brnch varchar2)
AS
BEGIN
    FOR rec IN (
        SELECT
            account_number,
            branch
        FROM
            account_data
        WHERE
            status = 'Active'
       and  acct_number =   v_acct_num
       And   branch = v_brnch)

    ) LOOP
        INSERT INTO active_accounts VALUES (
            rec.account_number,
            rec.branch
        );

    END LOOP;
END;
/

--Anonymous Block 
DECLARE
    accountstatus             VARCHAR(20);
    inputuser_accountnumber   NUMBER;
    inputuser_branch          VARCHAR(20);
    cf                        VARCHAR(20);
BEGIN
    inputuser_accountnumber := '&input_accountNumber';
    inputuser_branch        := '&input_branch';

    --As per your problem statement, your select statement must have account number and branch in where clause to pick one unique record.
    SELECT
        status
    INTO
        accountstatus
    FROM
        account_data
    Where acct_number =   inputuser_accountnumber;
    And   branch = inputuser_branch;

    IF
        ( accountstatus = 'Active' )
    THEN
       --Calling Proc to save records
       activeaccounts (inputuser_accountnumber,inputuser_branch);
    ELSE
        dbms_output.put_line('The account is Inactive.');
    END IF;

END;
/

【讨论】:

    【解决方案2】:

    一个函数意味着返回一些东西,而你需要做一些事情,而不返回任何东西,所以我会解释这个要求 作为“构建存储过程”。

    现在,假设你有你的程序,它只需要寻找一些特定的帐户分支和号码,所以它需要一些输入参数。 然后此过程应检查表中的(唯一?)行以获取帐户的状态(根据分行和帐号的值使用WHERE 条件进行选择)。 一旦知道状态,该过程只需打印一条消息或进行插入。

    使用如下表格

    create table ACCOUNT_DATA(account_number, branch, status) as (
        select 1, 'x', 'Active'   from dual union all
        select 2, 'x', 'Inactive' from dual 
    )   
    
    create table active_accounts (account_number number, branch varchar2(10))
    

    你可以像这样创建一个过程:

    create or replace procedure checkAccount(p_acc_number IN number, p_acc_branch IN varchar2) is
        v_status varchar2(10);
    begin
        -- get the status, assuming that the couple (account_number, and branch) is a key for the table 
        select status
        into v_status
        from ACCOUNT_DATA
        where account_number = p_acc_number
          and branch = p_acc_branch;
        -- check the status
        if v_status = 'Active' then
            insert into active_accounts
            values (p_acc_number, p_acc_branch);
        else
           dbms_output.put_line('The account is Inactive.');
        end if;
    end;     
    

    您的脚本可能是 (test.sql):

    SET SERVEROUTPUT ON;
    ACCEPT input_accountNumber NUMBER PROMPT 'Enter the account number : '
    ACCEPT input_branch CHAR PROMPT 'Enter the branch : '
    
    begin
        checkAccount('&input_accountNumber', '&input_branch');
    end;    
    /
    

    它是如何工作的:

    SQL> select * from active_accounts;
    
    no rows selected
    
    SQL> sta d:\temp\test.sql
    Enter the account number : 1
    Enter the branch : x
    
    PL/SQL procedure successfully completed.
    
    SQL> sta d:\temp\test.sql
    Enter the account number : 2
    Enter the branch : x
    The account is Inactive.
    
    PL/SQL procedure successfully completed.
    
    SQL> select * from active_accounts;
    
    ACCOUNT_NUMBER BRANCH
    -------------- ----------
                 1 x
    
    SQL>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-15
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      • 2017-07-25
      • 2014-02-11
      相关资源
      最近更新 更多