Reputation: 93
I have the following table
CREATE TABLE Vehicle_Location
(
id_park INTEGER CONSTRAINT nn_vehicle_location_id_park NOT NULL,
id_vehicle VARCHAR(255),
parkedtime TIMESTAMP NOT NULL,
CONSTRAINT pk_vehicle_location_id_vehicle PRIMARY KEY (id_vehicle)
);
And I'm trying to return one timestamp with the following procedure
create or replace FUNCTION GETBICYCLEPARKEDTIME(id_vehicle VARCHAR)
RETURN TIMESTAMP AS
refTime TIMESTAMP;
BEGIN
Select "PARKEDTIME" into refTime
from "VEHICLE_LOCATION"
where "ID_VEHICLE" = id_vehicle;
RETURN refTime;
END;
However I'm getting an error:
ORA-01422 : exact fetch returns more than requested number of rows
even though from my understanding I don't see how more than one row could be selected with the above procedure.
Upvotes: 1
Views: 98
Reputation: 16001
Another approach, if you really want parameters to have the same names as table columns, would be to prefix the parameter name using dot notation:
create or replace function getbicycleparkedtime(id_vehicle varchar2)
return timestamp
as
reftime timestamp;
begin
select parkedtime into reftime
from vehicle_location l
where l.id_vehicle = getbicycleparkedtime.id_vehicle;
return reftime;
end;
Here, l.id_vehicle
explicitly refers to the table column and getbicycleparkedtime.id_vehicle
refers to function parameter.
This can become quite verbose though, so it is more usual to name parameters using some convention which is different from column names. Some common naming patterns would give p_id_location
(p for "parameter"), in_id_location
(for an in
parameter), idLocation
or locationId
(assuming column names use underscores).
Double-quoting is only needed for non-standard names that would otherwise cause parsing issues because they are reserved words, or begin with numbers, contain punctuation etc, which should be rare (this may be needed for cross-platform portability, or systems like SAP where tables can have names like SAPSMP./BIC/A011DAP
). It is considered poor practice to use double-quoting when not absolutely necessary.
Use of upper/lower/mixed case is a style preference, but as a programmer I recommend that you pick one style that works best for you and stick to it.
Upvotes: 1
Reputation: 35900
There is an issue with the select
query.
It is returning more than one record with given WHERE
condition:
Select "PARKEDTIME" into refTime from "VEHICLE_LOCATION" where "ID_VEHICLE" = id_vehicle;
Try to restrict the WHERE
clause to return only one record.
You can use more conditions in the WHERE
clause or use DISTINCT
or use GROUP BY
and AGGREGATE function
.
Cheers!!
Upvotes: 0
Reputation: 146239
PL/SQL is not case-sensitive. So this line is your problem:
where "ID_VEHICLE" = id_vehicle
As identifiers "ID_VEHICLE"
and id_vehicle
are identical. (Double-quotes only make identifiers case-sensitive when the identifier is not all caps.) So the WHERE clause resolves both to the closest identifier in scope, which is the column name. Consequently your WHERE clause is equivalent to where 1 = 1
. So your query returns every row in the table.
The solution is to make the parameter distinct. That's why it's common practice to use a prefix when naming parameters:
create or replace FUNCTION GETBICYCLEPARKEDTIME(p_id_vehicle VARCHAR)
RETURN TIMESTAMP AS
refTime TIMESTAMP;
BEGIN
Select "PARKEDTIME" into refTime
from "VEHICLE_LOCATION"
where "ID_VEHICLE" = p_id_vehicle;
RETURN refTime;
END;
Upvotes: 5