oracle 10g overloaded procedures in a package - oracle

I'm trying to replicate the code found in:
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:59412348055
I did a copy and paste job. The package audit_pkg and the body compiled fine. But when I added the triggers the debug says "too many declarations for check_val" ...
Everything I've found says 10g supports overloading (or at least doesn't say otherwise).
Thoughts?

The procedure declarations in the package specification must match EXACTLY the declarations in the package body. This is where I usually encounter this error.

Is the column you're trying to use this package with a varchar2, number or date? If it's not, Oracle has to implicitly convert it to one of those three, and it won't know which one to use (and, therefore, which procedure to use). You may need to expand the package to handle more data types.

Related

Parameter list in the procedure

There is a procedure A with 2 parameters and this procedure is called in 10 stored procedures.(b,c,d....)
Now proc A is updated with 3 parameters , is there any way to update proc A parameters list in calling 10 procs in a single go.
Thanks in advance
Generally, when you publish your API (for example a package specification with several procedures and functions) and it is put into use, you have signed a contract of sorts with other developers.
You should not change the signature of those subprograms (change the terms of the contract) unless absolutely necessary.
Alternatives include:
When adding a new IN parameter, always put it at the end of the existing parameter list and provide a default value that reflects current (pre-change) behavior. All existing invocations of the subprogram remain valid.
If your are adding OUT or IN OUT parameters, consider leaving the current subprogram as is, and instead adding an overloading - same name but with the new, expanded parameter list.
This way, the existing code is not invalidated. You can then notify developers about the new subprograms (change to the contract) and they can choose to use them or not.
You can use PL/Scope, by the way, to find all usages of a particular subprogram. LiveSQL.oracle.com offers a number of PL/Scope scripts. Just search for "scope". Also, Philipp Salvisberg offers a great PL/Scope utility on Github: https://www.salvis.com/blog/2017/03/17/plscope-utils-utilities-for-plscope-in-oracle-database-12-2/
If there is only a few procedures will update 3rd statement, you'd use default value for your parameter. So you dont have to update all 10 procedures.
For ex,
CREATE OR REPLACE PROCEDURE PRC_UPD_MYPROCEDURE
(
p_ParameterOne IN NUMBER,
p_ParameterTwo IN VARCHAR2,
p_ParameterThree IN NUMBER DEFAULT NULL,
)
so when you call your procedure like (without third parameter),
PRC_UPD_MYPROCEDURE(1234,'EXAMPLE');
is valid.

How to unify pl/sql packages

I have two different packages with the same procedures (number and names), but overloaded. In the second package each procedure has one more parameter.
Specifically, in one procedure there are different declarations (cursors, etc), but EXACTLY the same code.
Now, I would like to have that code in one place, so as to maintain it in a single place. How could I do that?
you can have the overloaded procedures in the same package. But if you are asking whether you can have just one procedure rather than replicate the code, the answer is also yes, you can have one procedure with all the parameters, and then check the value of them within the procedure. You can also set a DEFAULT value for each parameter should someone call the procedure without all the require parameters (although this does assume an certain order for the parameters)

Sequences in Maple [Unable to Execute]

I've been working on a programme to solve any maximisation LPP using the Revised Simplex Method. I have a problem with it though as I'm trying to input a sequence to solve the problem of non-basic variables.
My code is as follows:
matmax:=proc(tableau,basic)
local pivot,T,nbv,n,m,b;
T:=evalm(tableau);
n:=coldim(T); m:=rowdim(T);
b:=evalm(basic);
print(evalm(T));
nbv:={seq(i,i=2..n-1)}minus{seq(b[i],i=1..m)};
pivot:=getpiv(T,nbv);
while not pivot=FAIL do
b[pivot[1]]:=pivot[2];
T:=evalm(gauss(col(T,pivot[2]),pivot[1])&*T);
print(evalm(T));
nbv:={seq(i,i=2,..n-1)}minus{seq(b[i],i=1..m)};
pivot:=getpiv(T,nbv);
od;
[evalm(T),evalm(b)];
end;
The gauss and getpiv commands are procedures written to work in this programme, these work fine. However upon executing this procedure Maple returns with the message "Error, (in matmax) unable to execute seq" If anyone can give me any help on how to fix this problem it would be greatly appreciated.
If you have not loaded the linalg package before calling your matxmax then commands like coldim will simplify not work and not produce the integer results for n and m that are expected when using those in the bound of the seq calls. I believe that is why your seq error occurs, because n and m are not being assigned integer intermediate results like you expect.
You could try to remedy this by either loading the package before calling matmax, with with(linalg). But that is not so robust, and there are scenarios where it might not work. The with command won't work within a procedure body, so you can't put that inside the defn of proc matmax.
You could insert a line into matmax above, say, the local declaration line, like,
uses linalg;
That would make coldim and friends from the linalg package work. Unfortunately you've used the name pivot as a local variable, and that clashes with the pivot export from linalg package. So that simple fix via uses is not quite enough. You could use some name other than pivot, and that simple uses line, sure.
My own preference would be to make everything fully explicit, so that later on you or anyone else reading the code can understand it more clearly, even if it's longer. So I would use linalg[coldim] instead of coldim, and so on for the other exports uses from the linalg package within matmax.
Having said all the above, you should know that the linalg package is deprecated in modern Maple and that LinearAlgebra is the new package that offers the functionality you seem to be using. The command names are longer, but using the newer package means that you don't need all those evalm calls (or anything like it).
The problem could lie in your gauss and getpiv commands as they may not work with your procedure, could you expand on what they do?

How can I read functions and procedures body/ddl while they are in a package?

TASK:
Move all the functions and procedures in packages to the current Oracle schema. (you can imagine a case when you could need that, if not - take it like a challenge!)
QUESTION:
How can I read the functions/procedure "body" while they are in the package? I know that I can use all_source, dba_source and others to get the package body lines, but this means that I have to parse all those rows/strings - it should be an easier way. Isn't it?
If you have access to Toad, it does this very well.
Also, look at DBMS_METADATA package, specifically, the GET_DDL procedure.
Hope that helps.
Why exactly do you need this?
Are you just trying to execute the functions and procedures as if they were defined in your schema? If so, then invoker's rights may help.
Are you doing this for testing? If so, take a look at this answer: Is there a way to access private plsql procedures for testing purposes? (summary: use conditional compilation to optionally make functions and procedures public)
If you really need to break the packages down to functions and procedures you'll need to do it manually if you want to be 100% accurate.
There are many potential problems with just reading the source and trying to do it automatically. What about package variables, types, initialization, security (can every function be public?), procedures within procedures, duplicate names, wrapped source, etc.

Replacing part of an Oracle package

I need to modify one procedure from within a package. I need to touch both the declaration and the implementation. As I am maintaining patch files for each modification, I would like the changes to be minimal.
Can I update the package with just the changed procedure ( if yes, how ? ) , or do I need to supply the complete package definition and implementation?
You need to replace the whole package specification and body - you cannot operate on just part of a package.
Just to contradict everyone else . . .
Technically you could do it - you could write something that would take in your patch file, retrieve the existing package source from the database (using USER_SOURCE), apply your patch, and then recompile the package using EXECUTE IMMEDIATE.
However, I don't think it would be a very good idea - patch based fixing becomes very difficult to keep track of, especially once multiple patches and multiple databases are involved. Putting the whole file into source control is a lot better - your patch should still be clearly visible.
If the patch is to a third-party package, consider wrapping it - so that everything is a straight call through except your patch. Or put your patch into a standalone package that calls the first one. There is still a danger that a change to the original package could be incompatible with your patch.
You cannot. As far as I remember, the only way to avoid referencing objects invalidation is not to touch your package declaration, and perform only CREATE OR REPLACE PACKAGE BODY.
Since the declaration changes, you might consider putting the new procedure into a new package, to avoid touching the existing one. Packages using the new version of the procedure must be adapted anyways, to reflect the change in the declaration (unless it's a new parameter with a default value).
If you're on Oracle 11g, and you want to minimise invalidations of other objects, make sure to place the new declarations at the end of the package spec.

Resources