I have writtent some Oracle storedprocedures in these there are more then 20 input parameters and from them morethen 10 parameters are required , I want all with some value and do not want to accept null values for that , Is there anything that I can declare in the Procedure defination itself which can restrict null input parameter or Will I have to check for each value and Raise the exception if the required value is null ?
I know this is an old question, but there is another option (described here):
SUBTYPE varchar2_not_null IS VARCHAR2 NOT NULL;
You can define this type (and number_not_null, etc) either in the same package as your stored procedures, or in their own package if you want to use them in lots of places. You can then declare parameters of being these types.
If NULL gets passed as an argument, you'll get a very useful error message:
cannot pass NULL to a NOT NULL constrained formal parameter
In PL/SQL I don't know of a way around checking each one.
If you are calling the stored procedure from an external library, that library might have that functionality. This is probably not likely because frequently NULL input parameters are required.
You could make a helper PL/SQL procedure that, given a value, will raise an exception if it is null to save on redundant code. You could then write a chunk of perl/python/groovy that would slurp up your procedure declaration and crank out these calls to your null check procedure.
Related
in SQL Server I can create a procedure to receive a datatable as input instead of of primitive type, this way I can pass a list of values, like the example below.
--Create Type
CREATE TYPE dbo.NamesList
AS TABLE
(
fullName VARCHAR(50)
);
--Create Procedure
CREATE PROCEDURE dbo.DoSomethingWithNames
#List AS dbo.NamesList READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT fullName FROM #List;
END
--Example of SQL Call
--Set variable values
DECLARE #NL NamesList;
INSERT #NL VALUES ('Bill'),('Michael'),('Paul'),('William'),('Kate')
--Call procedure
Exec DoSomethingWithNames #NL
On IBM IIB I can call stored procedures with a code like this:
CREATE PROCEDURE GetFiles (IN idFile INTEGER)
LANGUAGE DATABASE
DYNAMIC RESULT SETS 1
EXTERNAL NAME "dbo.SP_S_FILE";
But I have no idea if it's possible to pass a datatable instead of primitive value and how to it. Any ideas?
Thanks
Have you looked at the PASTHRU statement? I haven't tried doing what you're asking before, but the documentation sounds promising (assuming the limitations don't prevent you from using it).
PASSTHRU can still be used to call stored procedures if:
Only input parameters can be used.
Only single result sets are supported.
If you don't meet these criteria, use the CALL statement because PASSTHRU
imposes limitations (you cannot use output parameters, for example).
I have migrated oracle database from 10g to 12c. From 12c oracle doesn't support PLSQL_V2_COMPATIBILITY parameter.
This parameter is used to :
https://www.safaribooksonline.com/library/view/oracle-database-administration/1565925165/re157.html
One of the highlighting point in above url is :
The PL/SQL compiler will allow OUT parameters to be used in expression
contexts in some cases, for example, in dot-qualified names on the
right-hand side of assignment statements. This behaviour is restricted
to fields of OUT parameters that are records, and OUT parameters
referenced in the FROM list of a SELECT statement.
Due to this change many of our packages went into error which previously using functions with record as out parameter.
CREATE OR REPLACE Package SJMUSER.nagendra AS
TYPE r_standard_url IS RECORD (
v_loginurl VARCHAR2(1000),
v_changepasswordurl VARCHAR2(1000),
v_newloginurl VARCHAR2(1000)
);
TYPE t_standardurl_tbl IS TABLE OF r_standard_url
INDEX BY BINARY_INTEGER;
t_standardurlstype t_standardurl_tbl;
FUNCTION Producestandardurls
(
tp_myuserid IN USERS.User_Id%TYPE,
v_scrntime IN VARCHAR2,
v_scrntoken IN VARCHAR2,
v_wwikey IN VARCHAR2
)
RETURN t_standardurlstype;
end nagendra;
/
Error :
PLS-00488 't_standardurlstype' must be type.
Whether this will required entire code changes ? like not using record as out parameter ? whether there is any solution for this ?
For the example you've shown, you just need to change the return type (for this function; potentially OUT parameter types for others) from:
RETURN t_standardurlstype;
to either:
RETURN t_standardurlstype%type;
or more simply:
RETURN t_standardurl_tbl;
Your are currently trying to return the variable t_standardurlstype, which is an instance of the t_standardurl_tbl type. With the PLSQL_V2_COMPATIBILITY setting it's allowing the type to be inferred from the variable, but you can't do that any more. You may not actually be using the variable anywhere else - if not you can remove its declaration, if you use the second form above.
So yes, you will need to make code changes, but only to how return and OUT parameters are declared, in both the package specification and body. You can continue to use a record as an OUT parameter, it just needs to be declared correctly.
There are other implications of that setting though. See My Oracle Support note 47354.1 for details, but summarising what that says, you also need to watch out for these changed behaviours, as PL/SQL now:
correctly enforces the read-only semantics of IN parameters and does not let index table methods modify index tables passed in as IN parameters.
does not permit OUT parameters to be used in expression contexts.
will not allow OUT parameters in the FROM clause of a SELECT list, where their value is read.
will return an error on the illegal syntax return expression which should be return type (which is what the code in your question is hitting).
does not allow the passing of an IN argument into another procedure as an OUT.
There is no quick fix or magic wand for these; if your code relies on any of the old behaviour in any of those categories then it will have to be modified to obey the 'new' syntax rules.
I have a problem with calling a stored procedure from ABAP.
I use standard ABAP class cl_sql_statement and it's methods execute_procedure and set_param. Called procedure, for example, has a single Boolean input parameter.
CREATE OR REPLACE PROCEDURE print_boolean (
p_in_flag BOOLEAN
) IS
ABAP snippet
DATA: ld_e_bool type char5,
ld_o_stat type ref to cl_sql_statement,
ld_r_data type ref to data.
***************************
ld_e_bool = 'FALSE'.
get references of ld_e_bool into ld_r_data.
ld_o_stat->set_param(DATA_REF = ld_r_data).
ld_o_stat->execute_procedure( 'print_boolean' ).
********************************************
After the call I catch an exception which says something like: 'wrong number or types of arguments'. Maybe I need another type than char5... Any help would be appreciated.
Some observation:
The JDBC drivers do not support the passing of BOOLEAN parameters to PL/SQL stored procedures( suggest wrapping the PL/SQL procedure with a second PL/SQL procedure). But i dont want to use the above option becuase there are already lot of packages/SP's are available.
The Oracle documentation is unclear on how PL/SQL boolean values are actually represented. There is also a question that discusses the use of boolean types in Oracle database fields (not really relevant here, but provides some background).
From the PL/SQL documentation:
The BOOLEAN datatype takes no parameters. Only the values TRUE, FALSE, and NULL can be assigned to a BOOLEAN variable.
You cannot insert the values TRUE and FALSE into a database column. You cannot select or fetch column values into a BOOLEAN variable. Functions called from a SQL query cannot take any BOOLEAN parameters. Neither can built-in SQL functions such as TO_CHAR; to represent BOOLEAN values in output, you must use IF-THEN or CASE constructs to translate BOOLEAN values into some other type, such as 0 or 1, 'Y' or 'N', 'true' or 'false', and so on.
In light of that, and I know you don't want to, you may need to change the type of parameter you pass into the stored procedure (e.g., use a single character or integer) and then use logic to treat that as a boolean.
In SAP doc say:
Almost all SQL statements that are valid for the addressed database system can be included between EXEC and ENDEXEC
Maybe if i try put in this section native pl/sql code i get result...
Edit: I put this code snip and it's ok.
EXEC SQL.
BEGIN
print_boolean(TRUE);
END;
ENDEXEC.
But there is one problem. This sql statement have static form only.
We have a Oracle procedure call done using iBatis. One of the IN parameters to the procedure is a VARCHAR2 datatype in procedure and is java.lang.String in Service/DAO layers.
The procedure fails whenever this input parameter is passed with NULL value. When a value is passed, then the procedure gets called without any errors.
For this procedure parameter (which is nullable) within the parametermap, we set the attribute as jdbctype="java.sql.Types.NULL" and it started working.
Is this the correct solution ?
The database connection is established using connection pool (dbcp) created in Tomcat6 server.
Ibatis for sure have problems with NULL values passed as parameters.
In our insert query we use such wrapper:
insert into table (column1) values (<isNull property="column1">NULL </isNull><isNotNull property="column1">#column1:INT# </isNotNull>)
for those still using the old version of ibatis (2.3 in my case), the above error while passing nullable parameters might be caused by not specifying jdbcType in parameterMap. there is a passage in iBatis 2.3.0 User Guide (p.27, Parameter Maps and Inline Parameters - jdbcType) pointing that out.
My form has a master block (ORDER) and a detail block (ORDER_LINE). The ORDER block has an ORDER_ID item (it's primary key) defined as follows:
The ORDER_LINE block uses the ORDER.ORDER_ID item as an argument to query its records:
The ORDERING_PACKAGE.QUERY_ORDER_LINES procedure is declared as follows:
PROCEDURE
query_order_lines
(
order_lines IN OUT ORDER_LINE_CURSOR_TYPE,
order_id NUMBER,
line_number VARCHAR2,
bin VARCHAR2,
plu VARCHAR2,
description VARCHAR2
);
When I attempt to compile my Oracle Form (Ctrl + T), I receive an error like this:
FRM-30408: Invalid value.
Reference: ORDER.ORDER_ID
Block: ORDER_LINE
Procedure: ORDERING_PACKAGE.QUERY_ORDER_LINES
Form: ORDER_FORM
FRM-30085: Unable to adjust form for output.
According to the documentation, the recommended solution is:
Cause: The value entered for the specified datatype is invalid.
Action: Correct one or more of the following:
The datatype of the argument corresponding to the given value in the procedure argument list of the specified procedure.
The value of the argument in the procedure argument list of the specified procedure.
Neither of these recommendations work:
The data type of the argument in the form (NUMBER) is identical to the data type of the procedure's parameter (NUMBER).
The value of the argument (ORDER.ORDER_ID) is also of type NUMBER (see first screen shot)
How do I resolve this error?
Ah yes, the very helpful help file in Oracle Forms. "Your parameter is wrong, change it, you donkey."
Not so much help in this case, as the error is a bit more subtle.
The value you are specifying for the argument ORDER.ORDER_ID would not be referencable in this case. You need to pre-pend it with the good ole :, to identify it as a bind variable. ":ORDER.ORDER_ID" is how it should read in the Value field for the argument.
Essentially, the value column must be an actual value that your form could reference in a PL/SQL block (in the form).
Hope this helps!