[英]Wrong number or types of arguments in call to '||'
We are supposed to read a text file, insert that data into a table while taking care of exceptions.我们应该读取一个文本文件,在处理异常的同时将该数据插入到表中。 This the code for my function:这是我的函数的代码:
set serveroutput ON;
CREATE OR replace FUNCTION Order_func(ldir VARCHAR2,
lfile VARCHAR2)
RETURN BOOLEAN
AS
result BOOLEAN;
f utl_file.file_type;
s VARCHAR2(200);
v_row VARCHAR2(2000);
v1 NUMBER;
v2 NUMBER;
v3 NUMBER;
v4 DATE;
v5 DATE;
v6 NUMBER;
v7 NUMBER;
v8 NUMBER;
v9 NUMBER;
customer_error EXCEPTION;
employee_error EXCEPTION;
item_error EXCEPTION;
customerids NUMBER;
employeeids NUMBER;
inventoryids NUMBER;
BEGIN
SELECT cno
INTO customerids
FROM customers;
SELECT employeeno
INTO employeeids
FROM employees;
SELECT itemno
INTO inventoryids
FROM inventory;
f := utl_file.Fopen(ldir, lfile, 'R');
LOOP
utl_file.Get_line(f, v_row);
v1 := Substr(v_row, 1, 4);
v2 := Substr(v_row, 6, 9);
v3 := Substr(v_row, 11, 12);
v4 := Substr(v_row, 15, 23);
v5 := Substr(v_row, 27, 35);
v6 := Substr(v_row, 38, 41);
v7 := Substr(v_row, 43);
v8 := Substr(v_row, 45, 48);
v9 := Substr(v_row, 50, 51);
IF v2 <> customerids THEN --checking customer id
RAISE customer_error;
ELSIF v3 <> employeeids THEN --checking employee id
RAISE employee_error;
ELSIF v6 <> inventoryids THEN --checking item1 id
RAISE item_error;
ELSIF v8 <> inventoryids THEN --checking item2 id
RAISE item_error;
ELSE
INSERT INTO transactions
(tid, orderno, cno, employeeno, received,
shipped, itemno1, quantity1, itemno2, quantity2)
VALUES (sequence_tid.NEXTVAL, v1, v2, v3, v4, v5,
v6, v7, v8, v9);
END IF;
END LOOP;
result := TRUE;
RETURN result;
EXCEPTION
WHEN customer_error THEN
dbms_output.Put_line('Customer not found in parent Customer table'); WHEN
employee_error THEN
dbms_output.Put_line('Employee not found in Employee table');
WHEN item_error THEN
dbms_output.Put_line('Item not found in inventory table'); WHEN OTHERS THEN
dbms_output.Put_line('Error code:'
|| SQLCODE
|| '. Error Message: '
|| SQLERRM);
utl_file.Fclose(f);
result := FALSE;
RETURN result;
END order_func;
This is how i've called the function (but i think it's wrong):这就是我调用函数的方式(但我认为这是错误的):
DECLARE
results boolean;
BEGIN
results := order_func('forQues','items.txt');
DBMS_OUTPUT.PUT_LINE('Result for ORDER_FUNC Function is: ' || results);
END;
And this is the error I've got:这是我遇到的错误:
DECLARE
results boolean;
BEGIN
results := order_func('forQues','items.txt');
DBMS_OUTPUT.PUT_LINE('Result for ORDER_FUNC Function is: ' || results);
END;
Error report -
ORA-06550: line 5, column 26:
PLS-00306: wrong number or types of arguments in call to '||'
ORA-06550: line 5, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
I tried to remove the results in the dbms_output and this is what happened:我试图删除 dbms_output 中的结果,这就是发生的事情:
DECLARE
results boolean;
BEGIN
results := order_func('forQues','items.txt');
DBMS_OUTPUT.PUT_LINE('Result for ORDER_FUNC Function is:');
END;
After running this i got:运行后我得到:
Error code:-1422. Error Message: ORA-01422: exact fetch returns more than requested number of rows
Result for ORDER_FUNC Function is:
PL/SQL procedure successfully completed.
Please somebody help, how to fix this?请有人帮忙,如何解决这个问题?
In addition to the errors already pointed out you function has a couple issues, at least.除了已经指出的错误之外,您的函数至少还有一些问题。 The biggest problem is, I believe, your misunderstanding of the Substring function, in particular the 3rd parameter.我相信,最大的问题是您对Substring函数的误解,尤其是第三个参数。 The 3rd parameter optionally indicated the length desired not the ending position.第三个参数可选地指示所需的长度而不是结束位置。 For example the variable v5 is defined as a date but the value is set as "v5 := Substr(v_row, 27, 35);".例如,变量 v5 被定义为日期,但值设置为“v5 := Substr(v_row, 27, 35);”。 Do you really have a date that is 35 characters long.你真的有一个 35 个字符长的日期吗? Additionally when the 3rd parameter is omitted then the resulting value extends from the 2nd parameter to the end of the string.此外,当省略第三个参数时,结果值将从第二个参数扩展到字符串的末尾。 So v7 extends from position 43 to the end of string.所以 v7 从位置 43 延伸到字符串的末尾。 V8, V9 then are numbers that are 48 and 51 digits respectively and every field overlaps the one following. V8、V9 分别是 48 位和 51 位的数字,每个字段都与后面的字段重叠。
The other big issue is the error NO_DATA_FOUND.另一个大问题是错误 NO_DATA_FOUND。 You have three places where this is likely to occur (the selects) and 1 where it will occur (utl_file.Get_line - that's how utl_file indicates end-of-file).您有三个可能发生这种情况的地方(选择)和 1 个可能发生的地方(utl_file.Get_line - 这就是 utl_file 表示文件结束的方式)。 As structured you have no way of knowing which initiated that error.按照结构,您无法知道是哪个引发了该错误。 In the following I propose a method to resolve this issue.下面我提出一种方法来解决这个问题。 I break each of those element into a theit own procedure.我将这些元素中的每一个都分解为一个自己的程序。 I leave the substring issue for you to resolve.我将子字符串问题留给您解决。
Before that a little philosophy.在此之前有点哲学。 Names and classifications are important.名称和分类很重要。 Names should describe what the represent but V1, V2 ... do not;名称应该描述代表什么,但 V1、V2 ... 没有; so instead of v5 perhaps v_shipped_dt.所以可能不是 v5,而是 v_shipped_dt。 Likewise declaring a procedure vs. function should done based on purpose of the routine.同样,应根据例程的目的来声明过程与函数。 Procedures accomplish things, fuunctions get things.程序完成事情,功能得到事情。 It seems the purpose here is to load data not return boolean.似乎这里的目的是加载数据而不是返回布尔值。 So I made it a procedure (it reports back via an out parameter).所以我把它变成了一个过程(它通过一个 out 参数报告)。 (Normally I wouldn't even do that. It runs successfully and returns nothing or if fails raising an exception. But that's perhaps stylistic.) (通常我什至不会这样做。它运行成功并且不返回任何内容,或者如果失败则引发异常。但这可能是风格。)
create or replace procedure load_order_file
( ldir varchar2
, lfile varchar2
, result out varchar2
)
as
customer_error exception;
employee_error exception;
item_error exception;
f utl_file.file_type;
v_row varchar2(2000);
v1 number;
v2 number;
v3 number;
v4 date;
v5 date;
v6 number;
v7 number;
v8 number;
v9 number;
EOF_Reached Boolean ;
-- procedure to handle all file processing
procedure load_order_buffer
is
begin
if f is null or not util_file.is_open(f)
then
f := utl_file.fopen(ldir, lfile, 'R');
EOF_Reached := False;
end if ;
utl_file.get_line(f, v_row);
exception
when no_data_found then
EOF_Reached := True;
util_file.fclose(f);
end load_order_buffer;
-- procedure to split file line into local variables
procedure parse_buffer
is
begin
v1 := substr(v_row, 1, 4);
v2 := substr(v_row, 6, 9);
v3 := substr(v_row, 11, 12);
v4 := substr(v_row, 15, 23);
v5 := substr(v_row, 27, 35);
v6 := substr(v_row, 38, 41);
v7 := substr(v_row, 43);
v8 := substr(v_row, 45, 48);
v9 := substr(v_row, 50, 51);
end parse_buffer;
-- procedures to validate customer, employee, and inventory
procedure validate_customer(cust_no_in number)
is
l_exists varchar2(1);
begin
select null
into l_exists
from customers
where cno = cust_no_in;
exception
when no_data_found then
raise customer_error;
end validate_customer;
procedure validate_employee(employee_no_in number)
is
l_exists varchar2(1);
begin
select null
into l_exists
from employees
where employeeno = employee_no_in;
exception
when no_data_found then
raise employee_error;
end validate_employee;
procedure validate_inventory(inventory_no_in number)
is
l_exists varchar2(1);
begin
select null
into l_exists
from inventory
where itemno = inventory_no_in;
exception
when no_data_found then
raise item_error;
end validate_inventory;
-- Main
begin
-- set up initial assumptions;
result := 'Failed';
EOF_Reached := False;
loop
load_order_buffer;
exit when EOF_Reached;
parse_buffer;
validate_customer(v2);
validate_employee(v3);
validate_inventory(v6);
validate_inventory(v8);
-- everything valid create transaction
insert into transactions
(tid, orderno, cno, employeeno, received,
shipped, itemno1, quantity1, itemno2, quantity2)
values (sequence_tid.nextval, v1, v2, v3, v4, v5,
v6, v7, v8, v9);
end loop;
result := 'Success';
exception
when customer_error then
dbms_output.put_line('Customer not found in parent Customer table');
when employee_error then
dbms_output.put_line('Employee not found in Employee table');
when item_error then
dbms_output.put_line('Item not found in inventory table');
when others then
dbms_output.put_line('Error code:'
|| sqlcode
|| '. Error Message: '
|| sqlerrm);
end load_order_file ;
/
Here is a test driver这是一个测试驱动程序
declare
result varchar2(8);
begin
load_order_file('forQues','items.txt');
dbms_output.put_line('Load Order file terminated with ' || result);
if result <> 'Success'
then
rollback;
end if ;
end ;
Since you provided neither table DDL nor sample data this is not tested .由于您既未提供表 DDL 也未提供示例数据,因此未进行测试。 Good Luck.祝你好运。
Error ORA-01422: exact fetch returns more than requested number of rows
happens when your query returns multiple rows but you have an INTO
clause which only expects 1 row to be returned.错误ORA-01422: exact fetch returns more than requested number of rows
当您的查询返回多行但您有一个只期望返回 1 行的INTO
子句时,会发生ORA-01422: exact fetch returns more than requested number of rows
。
For example, your three queries:例如,您的三个查询:
select cno into customerids from customers;
select employeeno into employeeids from employees;
select itemno into inventoryids from inventory;
Error PLS-00306: wrong number or types of arguments in call to '||'
错误PLS-00306: wrong number or types of arguments in call to '||'
is thrown because you are trying to concatenate a string with a boolean at被抛出是因为您试图将一个字符串与一个布尔值连接起来
DBMS_OUTPUT.PUT_LINE('Result for ORDER_FUNC Function is: ' || results);
which is not allowed.这是不允许的。
Possible fixes for ORA-01422
error: Put your SELECT
in a FOR
loop like: ORA-01422
错误的可能修复:将您的SELECT
放入FOR
循环中,例如:
FOR c IN (
SELECT
cno
INTO customerids
FROM
customers
) LOOP
--do stuff, access column value like c.cno
END LOOP;
Possible fixes for PLS-00306
error: Change the concatenation to PLS-00306
错误的可能修复:将串联更改为
DBMS_OUTPUT.PUT_LINE('Result for ORDER_FUNC Function is: ' || case when results then 'true' else 'false' end);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.