I'm joining a table to itself, in an ABAP CDS view, and would like to create a unique GUID per row. Is that possible?
Something like:
select from my_view as a
inner join my_view as b
on a.ContextKey = b.ContextKey and
a.DbKey != b.DbKey
{
key sysuuid as MAPPING_ID,
a.SomeField AS A,
b.SomeField AS B
}
I am not aware any UUID function in CDS. You need to use CDS Table Function and AMDP.
Your Table Function view.
define table function ZP_TF_TEST
with parameters #Environment.systemField: #CLIENT mandt : mandt
returns
{
mandt : mandt;
ID : uuid;
A : type_a;
B : type_b;
}
implemented by method zcl_tf_test=>get_data;
Your CDS view.
define view ZZ_TF_TEST as select from ZP_TF_TEST( mandt : $session.client )
{
key ID,
A,
B,
}
Your AMDP class .
CLASS zcl_tf_test DEFINITION PUBLIC FINAL CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb .
CLASS-METHODS get_data
FOR TABLE FUNCTION ZP_TF_TEST.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
Implement method get_data and use SELECT sysuuid FROM dummy
METHOD get_data BY DATABASE FUNCTION FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING my_table.
RETURN SELECT
a.mandt,
( SELECT sysuuid FROM dummy ) as id,
a.SomeField AS A,
b.SomeField AS B
from my_table as a inner join my_table as b
on a.ContextKey = b.ContextKey and a.DbKey != b.DbKey
where a.mandt= :mandt;
ENDMETHOD.
Related
I want to pass 'n' number of string in through UDF function but it shows error what to do
This is my code:
CREATE TEMP FUNCTION getDataOfTheseKeys(x ANY TYPE)
AS (
SELECT * FROM TABLE keys IN (x)
)
SELECT * FROM getDataOfTheseKeys("key1","key2","key3")
This is not working..
I propose you an example with an array as parameter of the udf :
CREATE TEMP FUNCTION getDataOfTheseKeys(arr ANY TYPE)
AS (
(select array_agg(id) from `project.dataset.table` where id IN UNNEST(arr))
);
SELECT
getDataOfTheseKeys(x) AS el
FROM (
SELECT ['ecaff28db267', '452094b23ee1', 'ecavf28db269'] AS x
);
In my example ecaff28db267 and 452094b23ee1 exist in the table but not ecavf28db269
The result in this case is :
Array of String =>
ecaff28db267
452094b23ee1
I have written a SQL function in PostgreSQL that accesses data from another table. On running the function, I am getting following error
relation table2 does not exist postgres
Here is the function that I am creating
CREATE OR REPLACE FUNCTION func(tbl1 table1)
RETURNS TABLE(a int, b text, c int, d text) AS $$
SELECT a, b, c, d
FROM table2
WHERE id = tbl1.user_id;
$$
language sql stable;
Working in case I change table2 to myschema.table2
What do I do? I do not want to add schema into the query. I want it to take whatever schema the function is in.
imitate 38.5.3. SQL Functions on Composite Types (https://www.postgresql.org/docs/current/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS)
db fiddle
CREATE OR REPLACE FUNCTION func(table1)
RETURNS TABLE(a int, b text, c int, d text) AS $$
SELECT a, b, c, d FROM table2 WHERE id = $1.user_id;
$$
language sql;
call it. select (func(table1.*)).* from table1;
How to replace a concrete value with a variable in Oracle SQL? I have
select 5, min(id) from my_table where id > 5 --AND ..
UNION ALL
select 6, min(id) from my_table where id > 6 --AND ..
UNION ALL
....
| 5 | 6 |
| 6 | 8 |
...
How to wrap it in a function executing pseudocode below?
for ( $i in ( select id from my_table)){
UNION ALL
select $i, min(id) from my_table where id > $i
}
Edit: To make it clear, I am looking for a general method to turn a select with hard wired values into a function that accepts variables. Note the --AND part.
Edit2:
Let me translate it in Java.
Qu estion: I have code
System.out.println(1+2+" = 1+2"+ " ");
that returns a sum of two numbers. How to replace concrete 1+2 with any a and b?
Answer:
You need to define
int getSum(int a, int b){ return a+b;}
Now you can write
for(int a : setA){
for(int b : setB){
System.out.println(" " +a+"+"+b+" = "+ getSum(a,b)+" ");
}}
This way you can iterate over all elements of setA and all elements of setB instead of providing concrete values 1 and 2.
I have exactly the same question for SQL. If I have a query that returns a result for a concrete value (Java example: 1,2; SQL example: where id > 6 ) - how to modify it so that SQL iterates over all possible values (obtained by select id from t group by id)?
It looks like you want to get the next ID for each id. That can be done simply by using the lead function:
select
t.id,
lead(t.id) over (order by t.id) as next_id
from
my_table t
If you do want to return it from a function, you would probably need a table function returning a custom table type, because the rowtype to return doesn't match your table structure, so you can't use my_table%rowtype.
The snippet below would create such a row type and matching table type, and a function that would return the same as above query. The last lines contain the same query, now using the function instead of the table:
-- Define a row type (an object).
create or replace type my_row_type as object (
id int,
next_id int
);
-- Define a table type of that row type
create type my_table_type as table of my_row_type;
-- Create a function that returns a table.
create or replace function my_function
return my_table_type
is
result my_table_type;
begin
select
-- Use the rowtype constructor to put the id and next_id into a row object
my_row_type(
t.id,
lead(t.id) over (order by t.id))
-- use bulk collect into to query all rows into the table variable 'result'
bulk collect into
result
from
my_table t;
-- Don't forget to actually return it.
return result;
end;
/
-- Query it by 'casting' the function result to a table.
select
id,
next_id
from
table(my_function);
For more info on table functions, I think this tutorial/article is a good start:
http://stevenfeuersteinonplsql.blogspot.com/2015/04/table-functions-introduction-and.html
In below create view statement I don't understand the how the phone_number is passed to a function fn_services (which considered as a table) and that function will return what kind of output a table or what?
Inside the function fn_service a variable
vServTab services_tab := services_tab ();
is returned.
I don't understand this join...
CREATE OR REPLACE FORCE VIEW (COLA,COLB)
AS
SELECT COL1,COL2
FROM v_service_view spn,
TABLE (fn_services (spn.phone_number, NULL)) serv;
Is it possible to reference/access/pass the current record within an update statement?
CREATE TABLE t1 (
id serial PRIMARY KEY,
name text
);
CREATE TABLE t2 (
id serial PRIMARY KEY,
name text,
foo text
);
CREATE FUNCTION gen_t2_foo(_a t1, _b t2) RETURNS text AS $$
SELECT _a.name || ' - ' || _b.name;
$$ LANGUAGE sql;
CREATE FUNCTION upd_t2(_min_id int, _max_id int, _a t1) RETURNS VOID AS $$
UPDATE t2 SET
foo = gen_f2_name(_a, ???) -- How to pass the current t2 record?
WHERE id >= _min_id AND id <= _max_id;
$$ LANGUAGE sql;
Just refer to the table:
create function upd_t2(_min_id int, _max_id int, _a t1)
returns void as $$
update t2
set foo = gen_t2_foo (_a, t2)
where id >= _min_id and id <= _max_id;
$$ language sql;
It looks that the second function is expected to create a value from the field name in both tables, and between a start and end indices, right? In that case, make sure that gen_t2_foo also receives an index to merge the values of a single record (in both tables). Then, you can use it as you wanted to.
By the way, why are you declaring upd_t2 as a function which returns VOID? This would be what Procedures are offered for.