I want to assign values in a table column (column type is integer) to integer array. Unfortunately I could not.
--TYPE--
CREATE OR REPLACE TYPE ABILITY_ID_ARRAY IS VARRAY(100) OF INTEGER
--DECLARE IN PROCEDURE
ABILITY_IDS ABILITY_ID_ARRAY;
--STATEMENT--
SELECT ABILITY_FK INTO ABILITY_IDS
FROM T_EDUCATION_ABILITY_REL
WHERE EDUCATION_FK = edu_id;
I received this error:
[Error] ORA-00932 (16: 12): PL/SQL: ORA-00932: inconsistent datatypes: expected UDT got NUMBER
You need to use BULK COLLECT clause to store a resultset into a collection variable.
Please study the documentation of SELECT INTO statement:
https://docs.oracle.com/database/121/LNPLS/selectinto_statement.htm#LNPLS01345
into_clause
With this clause, the SELECT INTO statement retrieves one or more columns from a single row and stores them in either one or
more scalar variables or one record variable.
bulk_collect_into_clause With this clause, the SELECT INTO statement retrieves an entire result set and stores it in one or more
collection variables.
The PL/SQL statament should look like this in your case:
SELECT ABILITY_FK BULK COLLECT INTO ABILITY_IDS
FROM T_EDUCATION_ABILITY_REL
WHERE EDUCATION_FK = edu_id;
Related
In one use case I need to write a Query which return 1 if string count is >=4 or else return 0.
Below is the JSON which contains string.
Below is the query, which is returning a single row.
Select * from [Frs_def_businessobjectlayouts] where Definition like '%Open In Parent%' AND name like
'Task.ResponsiveAnalyst'
Note - Definition is the column which contains JSON data
Could some one help me out here!!.
First, you need to query the JSON and store in a temp variable and declare the word you want to search in another variable and perform the below operation. You will get the number of times it occurred in the JSON as output.
DECLARE #string VARCHAR(MAX)="Query your JSON from the table and assign to this variable"
DECLARE #tosearch VARCHAR(MAX)='Open In Parent'
SELECT (DATALENGTH(#string)-DATALENGTH(REPLACE(#string,#tosearch,'')))/DATALENGTH(#tosearch)
AS OccurrenceCount
How do I pass multiple entries through an input parameter mapped from a Table Function in SAP HANA ?
I've written a Table Function with an Input Parameter say IN_FORMAT_CD.
I've mapped this parameter to the one created in my calculation view.
I'm able to retrieve the data when I'm passing only one value say 100.
But it gives no result when I'm passing more than one value.
Is there any workaround for the same ?
My table function :
FUNCTION "HADMIN"."RA.Test.Prathamesh::PH_DEMO" (IN IN_FORMAT_CD NVARCHAR(500))
RETURNS TABLE (NAME NVARCHAR(10), ID NVARCHAR(10), FORMAT_CD NVARCHAR(3))
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER AS
BEGIN
RETURN
SELECT NAME,ID,FORMAT_CD
FROM
HADMIN.PH_DEMO
WHERE FORMAT_CD IN (select :IN_FORMAT_CD as FORMAT_CD from dummy);
END;
What you are looking for is the APPLY_FILTER function of SAP HANA SQLScript.
The following example shows how your scenario could be coded:
create function get_vals (IN id_list varchar(400))
returns table (id bigint, val varchar(40))
as
begin
declare myfilter varchar(450) := ' ID in (' || :id_list || ')';
_tmp = select id, val from some_vals;
_tmp2 = APPLY_FILTER (:_tmp, :myfilter);
return :_tmp2;
end;
select *
from
get_vals ('1, 4, 23, 4, 23, 3');
This approach will push down the unique list of IDs to be used as a filter when reading the table data. However, this is still dynamic SQL so you lose benefits like plan sharing and risk SQL injection attacks. Read more on this e.g. here.
If possible, you want to handle selection lists in your application code.
This, in turn, would also give you the option to decide whether using IN-lists or inner joins against temporary tables is the best approach for your situation.
In case you want to go with the selection list as a string, you should at least make sure, that common SQL injection attacks are not used and that the "in-list" really only contains possible ID values and commas.
it is not possible to produce(!) many items from a single sql variable unless you split them
In your SQL subselect query will return only rows that FORMAT_CD column values are exactly same with IN_FORMAT_CD parameter.
If this parameter represents more than one value, then this parameter is a concatenated string representation of each sub items. So we can split them back.
Splitting will produce a table on the fly which can be used for selection.
Please create the user-defined HANA Split function fnsplit that source codes can be found at referenced document
Then you can alter your function as follows assuming that each value is seperated with "," from others
ALTER FUNCTION "HADMIN"."RA.Test.Prathamesh::PH_DEMO" (IN IN_FORMAT_CD NVARCHAR(500))
RETURNS TABLE (NAME NVARCHAR(10), ID NVARCHAR(10), FORMAT_CD NVARCHAR(3))
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER AS
BEGIN
RETURN
SELECT NAME,ID,FORMAT_CD
FROM
HADMIN.PH_DEMO
WHERE FORMAT_CD IN (
select str from fnsplit(:IN_FORMAT_CD,',')
);
END;
I have a table with column as_of_date that is formatted as MMDDYY10. in SAS 7.1
proc sql;
INSERT INTO mytable (as_of_date)
VALUES (12/31/2016);
run;
and I get the following error:
ERROR 22-322: Syntax error, expecting one of the following: a quoted string, a numeric constant, a datetime constant,
a missing value, ), +, ',', -, MISSING, NULL, USER.
ERROR 200-322: The symbol is not recognized and will be ignored.
Note: if I change the value to 12/31/16 it still does not work. If I put quotes around it ('12/31/2016') I get the error:
ERROR: Value 1 of VALUES clause 1 does not match the data type of the corresponding column in the object-item list (in the SELECT
clause).
If I insert it without slashes (12312016) it is inserted without errors as ********
You need to use the DDMMMYYYY format within quotes and the d modifier:
proc sql noprint;
INSERT INTO mytable (as_of_date)
VALUES ("31dec2016"d);
quit;
Another way to look at it is SAS is looking for the numeric value underneath a date format. You can check the actual value and use the following code to get the same result:
data check;
date = "31dec2016"d;
run;
proc sql noprint;
INSERT INTO mytable (as_of_date)
VALUES (20819);
quit;
I'm trying to create a function that takes the parameters for the column, the table, the limit, and offset. Basically, I want to be able to get a specified number of rows data from a specified table from a specified column.
However, I'm unable to get the following code to work - I get several errors such as:
syntax error, unexpected SELECT, expecting ':' in: "create function get_banana(lim int, off int, tbl varchar(32), col varchar(32)) r"
syntax error, unexpected RETURN in: "return"
syntax error, unexpected END in: "end"
These errors seem kind of meaningless.
My code is as follows:
CREATE FUNCTION GET_BANANA(lim int, off int, tbl varchar(32), col varchar(32))
RETURNS TABLE (clm int)
BEGIN
PREPARE SELECT col FROM tbl LIMIT ? OFFSET ?;
RETURN EXEC (lim, off);
END;
I'd appreciate any help :) Thanks!
I see at least two issues
EXEC needs the identifier that is returned by PREPARE, e.g.:
sql>prepare select * from tables;
execute prepared statement using: EXEC 2(...)
sql>exec 2();
The function parameters tbl and col are string values. You cannot use them as table/column identifiers.
Having said that, I am not even sure if PREPARE can be used inside a function.
No, PREPARE is a top-level statement modifier.
I'm using Postgresql and PHP 5.3.x with PDO to access the DB.
I have this the SQL query (stripped down version), with a placeholder for PDO to fill in:
INSERT INTO t_articles (a_article_id) VALUES (?) RETURNING a_id
I want a_article_id to be either a number, like 5, or else it should be the result of the subquery:
((SELECT max(a_article_id) FROM t_articles) + 1)
However, PDO says:
SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "(SELECT max(a_article_id) FROM t_articles) + 1"
And I've tried to set the subquery as the default value, but it is not allowed apparently:
ERROR: cannot use sub query in default expression
How can I insert the result of this sub query (or what can be done to achieve the same result)?
You'd have to use INSERT...SELECT for that:
insert into t_articles (a_article_id)
select max(a_article_id) + 1
from t_articles
returning id
Or if you don't need contiguous values for a_article_id, use a sequence for it:
Create a sequence, we'll call it article_id_sequence.
-- Get the current max(a_article_id)+1 to use instead of FIRST_VAL below
create sequence article_id_sequence
start FIRST_VAL
owned by t_articles.a_article_id;
Set the default value for t_articles.a_article_id to nextval('article_id_sequence').
alter table t_articles
alter column a_article_id
set default nextval('article_id_sequence');
Use the default value when inserting:
insert into t_articles (a_article_id)
values (default)
returning id;