procedure declaration error (PLS-00488) - plsql

I am trying to make a procedure return a subset of records as a single type a_ntt meeting a certain requirement for which I am trying to define a cursor a_cur, and this is the relevant code for my question:
a_t a_cur%ROWTYPE;
TYPE a_ntt IS TABLE OF a_t;
l_a a_ntt;
My database server throws PLS-00488 (invalid variable declaration object must be a type or subtype) considering variable a_t. I would like to know why. To me it seems I have provided a type to a_t, I would suggest ROWTYPE does that for me, but obviously I am not getting something.
I would like to know why this error occurs, why declaring a_t as a_cur%ROWTYPE does not prevent this.
Just to make sure, I have resolved the issue by adding %TYPE to the line, so TYPE a_ntt IS TABLE OF a_t%TYPE;, but I would like to know why this is necessary.

a_t is not a type. It is a variable whose type is a_cur%ROWTYPE. You can't use it as a type.
a_t%TYPE is a type though, so that works.
The syntax diagrams for the "collection variable declaration" is in the PL/SQL docs. You'll see that either you need a type, or a rowtype_attribute which has cursor, table or view name with %ROWTYPE attached, or a type_attribute which is essentially a variable name with %TYPE attached.

Related

In Dynamoose, how to specify schema for field that allows either String or NULL?

I'm trying to define the schema for a field that will either be a string value or NULL.
From what I can tell, this should work:
myField: [String, dynamoose.type.NULL]
However, when it encounters a null value in the table, I get the following error:
TypeMismatch: Expected example.myField to be of type string, instead found type null.
The only thing I've found that works is setting the field to dynamoose.type.ANY, which seems like it defeats the purpose of defining the field at all.

age control 2 for pl/sql

i am trying to find out at what age an employee started working.
if he started under 16 he should report this 'Error when entering the date of birth' mistake. so my trigger is created but my trigger is not working
I get ever this error: ORA-01422: Exact retrieval returns more than the requested number of lines
i can't find the problem
Here is the code:
SET SERVEROUTPUT ON
ACCEPT Birthday PROMPT ' Pleas give you Date of birth: '
CREATE OR REPLACE TRIGGER T_Controll
before INSERT ON meine_Firma -- Table
FOR EACH ROW
DECLARE
V_Berufstart meine_Firma.Hiredate%TYPE; --Job begin
V_Geburtsdatum DATE; -- Date of birth
V_Alter number:=0; -- AGE
SELECT HIREDATE INTO V_Berufstart FROM meine_Firma;
BEGIN
V_Geburtsdatum:=('&Birthday');
V_Alter:= Round(MONTHS_BETWEEN(V_Berufstart,V_Geburtsdatum)-2)/12;
IF 16 > V_Alter THEN
RAISE_APPLICATION_ERROR(-20201,'Error when entering the date of birth');
END IF;
END;
/
SET SERVEROUTPUT OFF
If he under 16 then he may not work
sorry my english is not good (=
You have a much bigger issue in this script than the error you are getting. Even after correcting as #ShaunPeterson suggested it will still fail
, it WILL NOT generate an error it will just not run as you expect. The issue is you failed to understand substitution variables - the use of &name (Specifically here &Birthday.) I'll actually use &Birthday in the following but the discussion applies to ANY/ALL substitution variables.
people fail to understand why they can't use the "&" substitution
variables in their PL/SQL procedures and functions to prompt for input
at run time. This article will hopefully help clarify in your mind
what the differences are so that you can understand where and when to
use these.
Substitution Variables The clue here is in the name... "substitution". It relates to values being substituted into the code
before it is submitted to the database. These substitutions are
carried out by the interface being used
The effect of this substitution is the the line containing the substitution variable is physically rewritten by the interface replacing %Birthday. In this case if you don't enter a value or the date 2000-05-19 the statement before and after substitution is
BEFORE: V_Geburtsdatum:=('&Birthday');
AFTER: V_Geburtsdatum:=(''); OR V_Geburtsdatum:=('2000-05-19');
Either way the after is what the compiler sees; it does NOT see %Birthday at all. Moreover when run the trigger will not prompt for a value. As far as the compiler is concerned it is a hard coded value that will never change. Beyond that a trigger, or any other PLSQL script (stored or anonymous) never prompts for values, they are actually incapable of doing so as it is not part of the language. Any prompt is via your interface software not plsql.
I'm going to suggest a way to avoid the trigger altogether. Getting on soap box: Triggers are BAD, they have some usefulness for assigning auto incrementing keys (before 12c),logging, very limited auditing, etc. However, for business rules they should be the option of last resort. Ok Get off soap box.
The first thing is to make the columns meine_Firma.Hiredate and meine_Firma.Geburtsdatum NOT null (if not already). If either are NULL you cannot calculate anything with them, the result would be NULL.
Second create a new column age_at_hire (or whatever) as a virtual column then put a check constraint on it. And voila trigger no longer needed. See fiddle for demo.
So the proposed change (YES you will probably have to clean up the bad data first):
alter table meine_Firma modify
( hiredate not null
, Geburtsdatum not null
) ;
alter table meine_Firma add
( age_at_hire integer generated always as (trunc(months_between(hiredate,Geburtsdatum))) virtual
, constraint check_age_at_hire check (age_at_hire >= 16*12)
);
Anyway, I hope you get an understanding of substitution variables for the future. And learn to avoid triggers. Good luck.
The reason you are getting that specific error is that the below select will select ALL rows from meine_Firma as there is no where clause
SELECT HIREDATE INTO V_Berufstart FROM meine_Firma;
However because you are in a trigger you do not need to select anything you use the :NEW bind variable. So you can just use
V_Berufstart := :NEW.HIREDATE;
If this was an update trigger there would be both a :NEW and :OLD bind variable declared so that you can access the OLD and NEW values. As this is an Insert trigger the :OLD will just be null as there is no old values.

PeopleCode reflection for variables

Does PeopleCode have something similar to reflection in C# whereby I can access a variable with the variable name stored in a string? I am aware of the # operator but I think it only applies to fields and records (correct me if I am wrong. I tried and couldn't get it to work.)
Basically, I need to access a Component variable by name with the name itself being variable.
You can do it by # :
Local string &sValue1 = "var1";
getting the value :
winmessage(#(&sValue1));

bind parameter inside a lexical parameter oracle reports builder

Is there a way to use a bind parameter inside a lexical parameter query something like this?:
select col from tbl where col = :bind_param
note: the code above is an input in a lexical parameter
When saying a "lexical query", do you mean a "lexical parameter"?
If I understood you correctly, then yes - you can do that, by setting it in the After Parameter Form trigger. (BTW, that's where I set my lexical parameters' values, always).
Open Reports Online Help System and search for "lexical". It is very well described. I believe that this is what you are asking:
A lexical reference cannot be used to create additional bind variables
after the After Form trigger fires. For example, suppose you have a
query like the following (note that the WHERE clause is replaced by a
lexical reference):
SELECT ENAME, SAL FROM EMP
&where_clause
If the value of the where_clause parameter contains a reference to a
bind variable, you must specify the value in the After Form trigger or
earlier (*LF). You would get an error if you supplied the following value
for the parameter in the Before Report trigger:
WHERE SAL = :new_bind
If you supplied this same value in the After Form trigger, the report
would run.
(*LF) Now, that's somewhat contradictory - "or earlier" actually is the Before Report trigger, so ... take it with caution. As I've said (and I'll repeat it): I set lexical parameters' values in the After Parameter Form. Worked always (for me).

L2Entities, stored procedure and mapping

Finally checked out L2E framework and ran into problems almost instantly.
Yeah, i know... i should read some books before.
Situation:
entity with props -> id and name.
entity is mapped to table, which has id and name columns.
sproc, which returns ONLY id column.
Problem:
ObjectResult<MyProp> result = _container.MyStoredProcedure(uberParameter);
Calling this will cause an error
[guilty method goes here] threw exception:
System.Data.EntityCommandExecutionException: The data reader is incompatible with the specified 'DataBase.MyPropTableObject'. A member of the type, 'name', does not have a corresponding column in the data reader with the same name..
Problem #2:
Can`t "just return" that field, cause that column has XML data type, but sproc uses fancy select statements, which causes:
Msg 421, Level 16, State 1, Line 1
The xml data type cannot be selected as DISTINCT because it is not comparable.
Question:
Is it possible to exclusively turn off mapping for this entity prop only for this one sproc?
Problem 1 is due to the proc not having the columns to populate the entity. You don't really need the proc if you have mapped the table, just select the field you want from it using linq
var result = MyEntities.EntityIMapped.First(r => r.id = uberParameter).Name;
Would give you the value from the Name column of the table for the given id. You don't need to use a stored proc for this.
Problem 2 sounds like it is in the proc, I would think that distinct on an xml data column would give a lot of results, but I'm only guessing as I don't know your solution.
This is not a direct answer for your question but, hopefully it will point you in the right direction.

Resources