I'm trying to prepare stored procedure with TDS_DYN_PREPARE like
'create proc dyn1 as EXEC #RETURN_VALUE = sel_from_emp'
If I trying to use statement as is error 'Must declare variable '#RETURN_VALUE'
If parameter name replaced with ? (required for input params, but I tried on return value too) error
'The untyped variable ? is allowed only in in a WHERE clause or the SET clause of an UPDATE statement or the VALUES list of an INSERT statement'
Is it possible to use return value in such statement and if yes - how?
What you're doing here is executing a proc named sel_from_emp which apparently returns a status value (ASE procs can do that). Is this what ypu expected?
This status value is captured in variable #RETURN_VALUE -- but that variable is not declared, so you must add a statement DECLARE #RETURN_VALUE INT.
Note that capturing the proc return statis mskes sense pmly when you sre going to do domething with that value, otherwise you can you do EXEC sel_from_emp.
ALL
I have a postgresql function,so this:
CREATE OR REPLACE FUNCTION query_callouts(
INOUT io_cursor_ref refcursor,
INOUT opstatus integer,
INOUT errtext character varying)
RETURNS record AS
$BODY$
DECLARE
BEGIN
OPEN $1 FOR
SELECT tablename FROM pg_tables limit 10;
--SELECT * from call_out_numbers;
RETURN;
Exception
When Others Then
GET STACKED DIAGNOSTICS opstatus = RETURNED_SQLSTATE,
errText = MESSAGE_TEXT;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION query_callouts(refcursor, integer, character varying)
OWNER TO postgres;
I want to known ,how to use libpq in my c codes to visit the function - query_callouts and get the param io_cursor_ref and opstatus and errtext?
You can call the function just like you are executing any query:
select * from query_callouts('mycur', 0, '');
io_cursor_ref | opstatus | errtext
---------------+----------+---------
mycur | 0 |
(1 row)
opstatus and errtext would be set to the appropriate values if an exception occurs.
io_cursor_ref contains the name you have passed to the function.
Internally, a refcursor value is simply the string name of a so-called
portal containing the active query for the cursor. This name can be
passed around, assigned to other refcursor variables, and so on,
without disturbing the portal.
Note, you can use a refcursor only within a transaction.
All portals are implicitly closed at transaction end. Therefore a
refcursor value is usable to reference an open cursor only until the
end of the transaction.
You can use explicit transaction:
begin;
select * from query_callouts('mycur', 0, '');
fetch all in mycur;
-- save or show the query result
-- and finally
commit;
or use mycur inside a function.
The quotes are from the documentation.
It's just like any other query.
SELECT * FROM query_callouts('cursorname', 4, 'msg')
I suspect some if not all of your parameters should be OUT parameters not INOUT parameters, though. You don't ever use the input value of errtext at least.
I would like to take the code below and create a common function to pass in one or more expressions and to return back an error of my choosing.
Example Code:
IF #Variable1 IS NULL AND #Variable IS NULL or #Variable3 is not null
BEGIN
-- EITHER DATASET NAME OR ID MUST BE SUPPLIED.
SET #_msg = 'There was an error'
SET #_returnValue = -1
GOTO ERROR_HANDLER
END
ERROR_HANDLER:
-- CREATE THE CLOSING MESSAGE.
IF #_returnValue <> 0
RAISERROR(#_msg, 18, 2) WITH SETERROR
RETURN #_returnValue
From the above, it would be nice to say something like this below where I could reuse the proc/function and make the code less clutered.
exec ValidateMultipleConditions #Variable1 + 'IS NULL AND ' + #Variable + 'IS NULL or ' + #Variable3 + ' is not null'
Anyway, I think with dynamic SQL being passed in this way I could do something where an complete expression could be sent evaluated, validated and then the code continues or stops with an error.
I wanted to see if the community had better ways of doing this or if I'm on the right path.
Thanks.
I'm not quite sure if I get your question right. But you can easily create an procedure (if it's needed).
CREATE PROCEDURE dbo.errorout #message nvarchar(100), #sev int, #state int
AS
BEGIN
RAISERROR(#message,#sev,#state) WITH NOWAIT
END
But I won't use this at all. I would call RAISERROR() in the place where it occurs, as it will give you more accurate line numbers and procedures in the errorlog.
Below is the SQL Server's syntax to select variable as a record
DECLARE #number AS INTEGER;
SET #number = 10;
SELECT #number;
How can I do this in ORACLE?
Thanks in advance.
Regards,
Sagar Nannaware
Edited based on comment:
One way you can access the variable value assigned by a procedure is through a function again.
Example:
CREATE OR REPLACE PROCEDURE your_procedure(out_number OUT number)
IS
BEGIN
out_number:=1;
END;
function to retrieve the procedure's output
CREATE OR REPLACE FUNCTION your_function
RETURN number
AS
o_param number;
BEGIN
o_param := NULL;
your_procedure(o_param);
RETURN o_param;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
return 0; --basically how you want to handle your errors.
END your_function;
Now you can select the output of the procedure
select your_function from dual;
Useful link how to access an Oracle procedure's OUT parameter when calling it?
If you are trying to create a variable to access anywhere in your application in oracle.
You can do it by creating function and calling it from dual.
SQL>create or replace function foo return number
as
x number;
begin
x:=1;
return 1;
end;
Function created.
SQL>select foo from dual;
FOO
----------
1
Please check following link for more details
[example link] (http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1562813956388)
I am passing an array to a PL/SQL package function. I am doing this to use this array in a query inside the function which has IN clause.
My declaration of package looks like :
create or replace
PACKAGE selected_pkg IS
TYPE NUM_ARRAY IS TABLE OF NUMBER;
FUNCTION get_selected_kml(
in_layer IN NUMBER,
in_id IN NUMBER,
in_feature_ids IN selected_pkg.NUM_ARRAY,
in_lx IN NUMBER,
in_ly IN NUMBER,
in_ux IN NUMBER,
in_uy IN NUMBER
)
RETURN CLOB;
END selected_pkg;
In my PL/SQL function I am firing a query like following
select a.id, a.geom from Table_FIELD a where a.id in (select * from table (in_feature_ids)) and sdo_filter(A.GEOM,mdsys.sdo_geometry(2003,4326,NULL,mdsys.sdo_elem_info_array(1,1003,3), mdsys.sdo_ordinate_array(0,57,2.8,59)),'querytype= window') ='TRUE'
The same query runs fine if I run it from anonymous block like
CREATE TYPE num_arr1 IS TABLE OF NUMBER;
declare
myarray num_arr1 := num_arr1(23466,13396,14596);
BEGIN
FOR i IN (select a.id, a.geom from Table_FIELD a where a.id in (select * from table (myarray)) and sdo_filter(A.GEOM,mdsys.sdo_geometry(2003,4326,NULL,mdsys.sdo_elem_info_array(1,1003,3), mdsys.sdo_ordinate_array(0,57,2.8,59)),'querytype= window') ='TRUE'
loop
dbms_output.put_line(i.id);
end loop;
end;
If I try to run it by calling function as below
--Running function from passing array for IDs
declare
result CLOB;
myarray selected_pkg.num_array := selected_pkg.num_array(23466,13396,14596);
begin
result:=SELECTED_PKG.get_selected_kml(3, 19, myarray, 0.0,57.0,2.8,59);
end;
I am getting error
ORA-00904: "IN_FEATURE_IDS": invalid identifier
Could someone please help me understand the cause of it?
Thanks,
Alan
You cannot query a type declared in plsql in a sql query, as the sql engine doesn't recognise it.
Your first example works because you have declared the type numarr1 in the database, whereas the type selected_pkg.num_array is declared in a package.
Good summary here
I can't quite recreate the error you're getting; the anonymous block doesn't refer to in_feature_ids, and the package ought to only report that if it doesn't recognise it on compilation rather than at runtime - unless you're using dynamic SQL. Without being able to see the function body I'm not sure how that's happening.
But you can't use a PL/SQL-defined type in an SQL statement. At some point the table(in_feature_ids) will error; I'm getting an ORA-21700 when I tried it, which is a new one for me, I'd expect ORA-22905. Whatever the error, you have to use a type defined at schema level, not within the package, so this will work (skipping the spatial stuff for brevity):
CREATE TYPE num_array IS TABLE OF NUMBER;
/
CREATE OR REPLACE PACKAGE selected_pkg IS
FUNCTION get_selected_kml(
in_layer IN NUMBER,
in_id IN NUMBER,
in_feature_ids IN NUM_ARRAY,
in_lx IN NUMBER,
in_ly IN NUMBER,
in_ux IN NUMBER,
in_uy IN NUMBER
) RETURN CLOB;
END selected_pkg;
/
CREATE OR REPLACE PACKAGE BODY selected_pkg IS
FUNCTION get_selected_kml(
in_layer IN NUMBER,
in_id IN NUMBER,
in_feature_ids IN NUM_ARRAY,
in_lx IN NUMBER,
in_ly IN NUMBER,
in_ux IN NUMBER,
in_uy IN NUMBER
) RETURN CLOB IS
BEGIN
FOR i IN (select * from table(in_feature_ids)) LOOP
DBMS_OUTPUT.PUT_LINE(i.column_value);
END LOOP;
RETURN null;
END get_selected_kml;
END selected_pkg;
/
... and calling that also using the schema-level type:
set serveroutput on
declare
result CLOB;
myarray num_array := num_array(23466,13396,14596);
begin
result:=SELECTED_PKG.get_selected_kml(3, 19, myarray, 0.0,57.0,2.8,59);
end;
/
23466
13396
14596
PL/SQL procedure successfully completed.
Also note that you have to use exactly the same type, not just one that looks the same, as discussed in a recent question. You wouldn't be able to call your function with a variable of num_arr1 type, for example; they look the same on the surface but to Oracle they are different and incompatible.