I tried substring method but it is not working and giving me this error.
create or replace procedure
dsa ()
returns varchar
language javascript
$$
var b="{asdfasdf}"
var c=b.substring(1);
return c;
$$;
call dsa();
SQL compilation error: syntax error line 5 at position 0 unexpected '$$ var b="{asdfasdf}" var c=b.substring(1); return c; $$'.
You're missing the keyword AS in your stored procedure definition. You also need to define two parameters on the overloaded JavaScript function for substring. Finally, are you sure you want to use a stored procedure for this instead of a UDF or just SQL?
create or replace procedure
dsa ()
returns varchar
language javascript
as
$$
var b="{asdfasdf}"
var c=b.substring(0,1);
return c;
$$;
call dsa();
I'm constructing a snowflake stored procedure and I'm facing difficulty in using the passed argument in the snowflake procedure.
create or replace procedure dumper(n float)
returns float
language javascript
execute as caller
as
$$
var text = "select file_name from table(information_schema.COPY_HISTORY(TABLE_NAME=> 'records', start_time=> dateadd(hours, ?, current_timestamp())));";
var statement = snowflake.createStatement({sqlText: text, binds: [n]});
var result = statement.execute();
return statement.getRowCount();
$$
;
attempting to call the above procedure
call dumper(-2);
result in the following error
JavaScript execution error: Uncaught ReferenceError: n is not defined in DUMPER at ' var statement = snowflake.createStatement({sqlText: text, binds: [n]});' position 70 stackstrace: DUMPER line: 4
I tried using the interpolation one discussed over here but that too had no success.
Any clue on how to work with passed argument.
You have to capitalize "N" in your JavaScript code:
var statement = snowflake.createStatement({sqlText: text, binds: [N]});
Variables passed into Snowflake stored procedures behave like other object names until they're inside the JavaScript. If they're not double quoted, then Snowflake implicitly capitalizes them. Remember to uppercase all parameters passed into SPs and UDFs in Snowflake. Variables defined inside the SP or UDF using JavaScript follow the normal rules for the language.
Since the regular rules apply to Snowflake identifiers as they do to variables passed into procedures and functions, you can double quote parameters if you want to use lower or mixed case variable names:
create or replace function echo_string("n" string)
returns string
language javascript
as
$$
return n; // This works because "n" is double quoted in the signature
$$;
select echo_string('Hello world.');
I am using pgv10. The function that I need seems this wrong function:
CREATE FUNCTION array_coalesce(ANYARRAY) RETURNS ANYARRAY AS $f$
SELECT CASE WHEN $1 IS NULL THEN array[]::ANYARRAY ELSE $1 END;
$f$ language SQL IMMUTABLE;
Curiosity
... I started to simplify a complex problem, and arrives in the test select coalesce(null::text[], array[]::text[]) that not worked... So it was a good question, how to implement it? But sorry, I do something workng, COALESCE(array,array) is working fine (phew!).
So, "coalesce problem" is merely illustrative/didatic. What I really want to understand here is: How to use ANYARRAY?
PS: other curiosity, the string concat(), || and other concatenation operators in PostgreSQL do some "coalescing",
select concat(NULL::text, 'Hello', NULL::text); -- 'Hello'
select null::text[] || array[]::text[]; -- []
select array[]::text[] || null::text[]; -- []
How to use anyarray?
It's an interesting issue, in the context of the usage described in the question. The only way I know is to use an argument as a variable. It's possible in plpgsql (not in plain sql) function:
create or replace function array_coalesce(anyarray)
returns anyarray as $f$
begin
if $1 is null then
select '{}' into $1;
end if;
return $1;
end
$f$ language plpgsql immutable;
select array_coalesce(null::int[]);
array_coalesce
----------------
{}
(1 row)
By the way, you can simply use coalesce() for arrays:
select coalesce(null::text[], '{}'::text[]);
coalesce
----------
{}
(1 row)
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.
I'm using PostgreSQL 9.1.3 and the following functions:
CREATE OR REPLACE FUNCTION cad(INOUT args text[], OUT retval int4) AS $cad$
BEGIN
retval := 0;
RAISE NOTICE 'cad: %', args;
END;
$cad$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION dodo(in_args text[]) RETURNS text[] AS $dodo$
DECLARE
_res text[];
_rv int4;
BEGIN
_res := in_args;
EXECUTE 'SELECT cad($1)' USING _res INTO _res, _rv;
RETURN _res;
END;
$dodo$ LANGUAGE plpgsql;
When I call cad directly, I get expected output:
psql$ select cad(ARRAY['Quiz']);
NOTICE: cad: {Quiz}
-[ RECORD 1 ]---
cad | ({Quiz},0)
Time: 0,319 ms
My expected result for the dodo(ARRAY['Quiz']) call is the input array without changes. But instead I receive the following error:
psql$ select dodo(ARRAY['Quiz']);
NOTICE: cad: {Quiz}CONTEXT: SQL statement "SELECT cad($1)"
PL/pgSQL function "dodo" line 8 at EXECUTE statement
ERROR: array value must start with "{" or dimension information
CONTEXT: PL/pgSQL function "dodo" line 8 at EXECUTE statement
What is wrong here?
P.S.: I have to use EXECUTE as function to call will vary, code simplified for the purpose of question.
You want something like:
EXECUTE 'SELECT * FROM cad($1)' USING _res INTO _res, _rv;
The return type isn't two columns of text[],int it's a record of (text[],int) which needs unwrapping.