NHibernate calling Oracle stored procedure with schema prefix, how? - oracle

I have NHibernate calling stored procedure in Oracle working currently. However, how do I specify a schema prefix in the {call} syntax in the tag?
I tried
<sql-query name="my_sproc">
<return class="my_sproc_class" />
{call schema2.my_sproc (:p1)}
</sql-query>
But NHibernate run-time came back with 'schema2' not defined while 'schema2' is a definitely defined schema on my Oracle db.
thanks.

Could it be privileges ? The procedure may exist in that schema but you may not have privileges to execute it, or you may have privileges through a role that isn't enabled.
Could be parameters. If the procedure expects two parameters (or is a function) then trying to call it with one can get a "Doesn't exist" error when it really means "There isn't one I can call with just one parameter".
Final option is if you have a package in your schema with the same name as the other schema. Can happen with something generic like 'UTILS'. If you ask Oracle to execute UTILS.PROC and you have a UTILS package, then it will look in the package and throw an error if it doesn't find it, even if there is a UTILS schema with a procedure PROC.
Edited to add
In that case, I'm leaning towards a parameters issue
The example here seems to use ? as the parameter placeholder.

I could be mistaken here, but I thought that NHibernate requires all UDFs/SPROCS to be prefixed with "dbo"; does {call dbo.schema2.my_sproc (:p1)} work?

Related

Oracle - Stored Procedure with same name across multiple schema - Which would be called by default

If there is a stored procedure across different schemas (SYS, User defined Schema), which schema would be called by default if we don't mention a Schema Name.
**Schema_1**
Sample_SP
**Schema_2**
Sample_SP
**SYS**
Sample_SP
execute Sample_SP
Which schema would be executed?
It depends on how you call the procedure. If you use the simple name (meaning: not prefixed by the schema name), then Oracle will only look in the current schema. To call the procedure from any other schema, you must use the qualified name. If you call the procedure using the simple name, and a procedure by that name does not exist in your schema, you will get an error - you will not get a "default" place to look in. And, of course, if you use a qualified name to call it from a different schema, but you don't have the required privileges, you will get an error as well.
You may also create a synonym, but that can only be pointed (in the synonym definition) to one of the procedures - in one specific schema.
If you are connected as user schema_1, then its procedure would be executed.
Others might, or might not ever be executed, depending on whether their owners granted you execute privilege on their procedures and whether there are (public or private) synonyms.
But, the bottom line is: first execute your own code, then - if it doesn't exist - search for it elsewhere.
It will execute the stored procedure from connected schema.
Stored procedure from SYS will be executed if there is no user defined schema is connected as SYS is default.

calling oracle stored procedure using custom data types in perl

I have a stored procedure defined in oracle whose parameters are objects defined in oracle.
I need to invoke it through perl. I have looked but couldnt find any reference about it.
Could anyone help me out for the same ?
Thanks,
Why don't you write another Oracle procedure in which you can use your oracle-objects and call your target procedure? You could then call this new procedure by perl with standard parameters.
Bad architecture but should work...
(Sorry can't just comment)

Hiding body of stored procedure?

I defined a role and grant it with only connect to database and execute a specific stored procedure. Users have this role can see the body of procedure when execute this query;
select * from ALL_SOURCE where NAME = 'procedureName';
Procedure takes a VARCHAR2 parameter and uses it with a select query. Is that a security issue? Should i hide it somehow or escape the parameter?
Generally, it would only be a security issue if your procedure was subject to SQL injection. The fact that you talk about escaping the parameter implies that you may be doing dynamic SQL and may be vulnerable to SQL injection attacks. If that's the case, you need to fix the procedure, not hide the source.
If your stored procedure is implementing some business logic that you consider proprietary, you could potentially wrap the code so that it is obfuscated in the data dictionary. If you do that, however, make absolutely sure that you your source code in source control because there is no way to unwrap code once you've wrapped it (strictly speaking, there are various techniques that an attacker can use to recover most of the wrapped source if they really wanted to, but it's reasonably secure).

Call data-specific stored procedure from Oracle procedure

I have a situation where I have an Oracle procedure that is being called from at least 3 or 4 different places. I need to be able to be able to call custom-code depending on some data. The custom-code is customer-specific - so, customer A might want to do A-B-C where customer B might want to do 6-7-8 and customer C doesn't need to do anything extra. When customers D...Z come along, I don't want to have to modify my existing procedure.
I'd like to be able to enter the customer-specific procedure into a table. In this existing procedure, check that database table if a custom-code procedure exists and if so, execute it. Each of the customer-code procedures would have the same parameters.
For instance:
My application (3+ places) calls this "delete" procedure
In this delete procedure, look up the name of a child-procedure to call (if one exists at all)
If one exists, execute that delete procedure (passing the parameters in)
I know I can do this with building a string that contains the call to the stored procedure. But, I'd like to know if Oracle 10g has anything built in for doing this kind of thing?
Do each of your customers have their own database? If so the best option would be to use conditional compilation. This has the advantage of not requiring dynamic SQL. Have the main program always call the custom procedure, and use CC flags to vary the code it contains.
Otherwise, Oracle does have a Rule Engine but it is not really intended for our use.
The final solution that we went with was to store the name of a procedure in a database table. We then build the SQL call and use an EXECUTE statement.
Agree with APC's answer and just to expand on it, in this white paper if you look for "Component based installation" it describes a similar problem solved by using conditional compilation.
Your solution seems reasonable given the requirements, so I voted it up.
Another option would be to loop through the results from your table look-up and put calls to the procedures inside a big case statement. It would be more code, but it would have the advantage of making the dependency chain visible so you could more easily catch missing permissions and invalid procedures.

Oracle sql types over dblink

I have two schemas: A and B (Oracle 9). At the A there is a dblink to B. At the B there is a package, that i calls from A. Procedures in B package can returns varying count results and i think that returning a collection is a better way for this reason.
create type B.tr_rad as object (
name varchar2(64)
,code number
,vendor number
,val varchar2(255)
,num number
);
create type B.tt_rad as varray(256) of B.tr_rad;
But from A scheme I cannot use tt_rad type because using SQL-types by dblink is not supported. DBMS_SQL is not supported cursors. Create types with same OID is impossible.
I think to use temporary tables. But firstly it is not that good (after the remote function returns the value, calling side must select collection from remote table). And there are fears of a slowdown of work with temporary tables.
Maybe who knows the alternative interaction?
I've had similar problems in the past. Then I came to the conclusion that fundamentally Oracle's db links are "broken" for anything but simple SQL types (especially UDT's, CLOBS may have problems, XMLType may as well). If you can get the OID solution working then good luck to you.
The solution I resorted to was to use a Java Stored procedure, instead of the DB Link.
Characteristics of the Java Stored Procedure:
Can return a "rich set of types", just about all of the complex types (UDT's, tables/arrays/varrays) see Oracle online documentation for details. Oracle does a much better job of marshalling complex (or rich) types from java, than from a DBLink.
Stored Java can acquire the "default connection" (runs in the same session as the SQL connection to the db - no authentication issues).
Stored Java calls the PL/SQL proc on the remote DB, and the java JDBC layer does the marshaling from the remote DB.
Stored Java packages up the result and returns the results to the SQL or PL/SQL layer.
It's a bit of work, but if you have a bit of java, you should be able to "cut and paste" a solution together from the Oracle documentation and sample.
I hope this helps.
See this existing discussion
referencing oracle user defined types over dblink
An alternative interaction is to have one database with schemas A and B instead of two databases with a database link.
My solution.
On the side B i create temporary table like the collection record. At the A side i have a DBMS_SQL wrapper that calls procedure over dblink. This procedure writes result collection in the temporary table. After successful completion remote procedure i select results from remote temporary table and transform it to local collection type.
Limitations
1. the need for permanent object synchronization.
2. impossibility use A-side procedure (that call remote procedure) in SQL query.
3. the complexity of using.

Resources