I have a table scheme2.central_id__new_numbers in Greenplum.
I need select data from scheme2.central_id__new_numbers in the form of a many-to-many relationship.
Also I write the code but must have made a wrong turn somewhere (the code doesn't work):
CREATE FUNCTION my_scheme.parse_new_numbers (varchar) RETURNS SETOF varchar as
$BODY$
declare
i int;
BEGIN
FOR i IN 1..10 LOOP
select
central_id,
(select regexp_split_to_table((select new_numbers
from scheme2.central_id__new_numbers limit 1 offset i), '\s+'))
from scheme2.central_id__new_numbers limit 1 offset i
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
I'd recommend using the UNNEST() function instead, i.e. assuming new_numbers column is of int[] data type,
SELECT central_id
, UNNEST(new_numbers) AS new_numbers
FROM central_id__new_numbers;
If new_columns column is not an array data type then you need to use i.e. string_to_array() or similar before using UNNEST().
Related
I already created stored procedure in BigQuery for data querying.
The main point is send some parameter to get data in WHERE condition, then use list of data in WHERE of other table. It shown error as "Correlated subqueries that reference other tables are not supported unless they can be de-correlated, such as by transforming them into an efficient JOIN."
THIS IS MY QUERY
CALL mydatabase.stored_procedures.GetDateOutCS();
SELECT *, GetDateOutCS(ContainerHeaderID)
FROM mydatabase.instance.PRD_ContainerHeader
THIS IS MY STORED PROCEDURE
CREATE OR REPLACE PROCEDURE mydatabase.stored_procedures.GetDateOutCS()
BEGIN
CREATE TEMP FUNCTION GetDateOutCS (ContainerHeader_ID INT64)
AS
(
( SELECT GIDateFROM mydatabase.instance.RMM_ReceivedMaterialHU
WHERE HU IN
(SELECT CAST(HU AS INT64) FROM mydatabase.instance.PRD_ContainerLine
WHERE ContainerHeaderID=ContainerHeader_ID) LIMIT 1)
);
END;
I've tried to changed subquery to join table, but it's not works for me.
CREATE OR REPLACE PROCEDURE mydatabase.stored_procedures.GetDateOutCS_2()
BEGIN
CREATE TEMP FUNCTION GetDateOutCS (ContainerHID INT64)
AS
(
array( SELECT CAST(GIDate AS DATETIME)
FROM mydatabase.instance.RMM_ReceivedMaterialHU as h
INNER JOIN mydatabase.instance.PRD_ContainerLine as cl ON h.HU = CAST(cl.HU AS INT64)
WHERE cl.ContainerHeaderID=ContainerHIDAND cl.HU IS NOT NULL LIMIT 1)
);
END;
My expect solutions
How to fix this stored procedure.
This is limitation of BigQuery?
The following statement retrieve the value of sub tag msg_id from MISC column if the sub stag contain value like %PACS%.
SELECT REGEXP_SUBSTR(MISC, '(^|\s|;)msg_id = (.*?)\s*(;|$)',1,1,NULL,2) AS TRANS_REF FROM MISC_HEADER
WHERE MISC LIKE '%PACS%';
I notice the query return record with null value (without msg_id) as well. Any idea if can exclude those null records from the syntax of REGEXP_SUBSTR, without adding any where clause.
Sample data of MISC:
channel=atm ; phone=0123 ; msg_id=PACS00812 ; ustrd=U123
channel=pos; phone=9922; ustrd=U156
The second record without msg_id, so it need to be excluded.
This method does not use REGEXP so may not be suitable for you.
However, it does satisfy your requirement.
This takes your embedded list of msg_id, breaks it out to a row for each component for an ID (I've assumed you do have something uniquely identifies each record).
It then only returns the original row where one of the rows for the ID has 'PACS' in it.
WITH thedata
AS (SELECT 1 AS theid
, 'channel=atm ; phone=0123 ; msg_id=PACS00812 ; ustrd=U123'
AS msg_id
FROM DUAL
UNION ALL
SELECT 2, 'channel=pos; phone=9922; ustrd=U156' FROM DUAL)
, mylist
AS (SELECT theid, COLUMN_VALUE AS msg_component
FROM thedata
, XMLTABLE(('"' || REPLACE(msg_id, ';', '","') || '"')))
SELECT *
FROM thedata td
WHERE EXISTS
(SELECT 1
FROM mylist m
WHERE m.theid = td.theid
AND m.msg_component LIKE '%PACS%')
Thedata sub-query is simply to generate a couple of records and pretend to be your table. You could remove that and substitute your actual table name.
There are other ways to break up an embedded list including ones that use REGEXP, I just find the XMLTABLE method 'cleaner'.
i am trying to do a before insert trigger that updates one of the columns that will be inserted with a value taken from another column on the same record, however the catch is that that value is the first value of the said column after converting it to an array. when i include the function or the array i get a syntax error but the examples i have found for the proper syntax do not have the detail needed to make my code work. Here is my code:
Schema is as follows
create table events (
id int primary key,
performers varchar,
performer_id varchar
);
Function is:
create function events_set_performer() returns trigger
language plpgsql
as $$
declare
performer_ varchar := '0';
BEGIN
set NEW.performer_id = (string_to_array(NEW.performers,':'))[1];
return new;
END;
$$;
I am using Oracle APEX to build a interactive report. There is a field in my database called method which should contain either A or B. In the edit page, I want to show a list containing A and B so that users can choose from those two.
I set the type of the item to SelectList and since I need to add the other value to the list, in the List of Values area, I set the type to PL/SQL Function Body returning SQL Query and the code is as follows:
Begin
select TEST_METHOD into method from table_test
where ROWID = :P2_ROWID;
IF ('Live' = method) THEN
return select 'Screenshots' from dual;
END IF;
return select 'Live' from dual;
End;
However, I got the following error:
ORA-06550: line 5, column 10: PLS-00103: Encountered the symbol "SELECT" when expecting one of the following: ( - + ; case mod new not null continue avg count current exists max min prior sql stddev sum variance execute forall merge time timestamp interval date pipe
I am new to plsql and APEX, I know the code looks wired but I don't know what's wrong. I am also wondering if there is any other way to achieve my goal? Thanks!
I have a function like this:
CREATE OR REPLACE FUNCTION get_path_set_1(IN pathset_id_in character varying, OUT id character varying, OUT pathset_id character varying, OUT utility double precision)
RETURNS SETOF record AS
$BODY$
begin
if exists(SELECT 1 FROM "PathSet_Scaled_HITS_distinctODs" WHERE "ID" = $1) then
return query SELECT "ID", "PATHSET_ID", "UTILITY"
FROM "SinglePath_Scaled_HITS_distinctODs"
where "PATHSET_ID" = $1;
end if;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION get_path_set_1(character varying)
OWNER TO postgres;
when I call it in my program using this:
std::string testStr("43046,75502");// or std::string testStr("'43046,75502'");
soci::rowset<sim_mob::SinglePath> rs = (sql.prepare << "get_path_set_1(:pathset_id_in)",soci::use(testStr));
I get the following exception:
terminate called after throwing an instance of 'soci::postgresql_soci_error'
what(): Cannot prepare statement. ERROR: syntax error at or near "get_path_set_1"
LINE 1: get_path_set_1($1)
I will appreciate if you help me detect missing part
thank you
This does not solve the error you report. But simplify your function:
CREATE OR REPLACE FUNCTION get_path_set_1(pathset_id_in varchar)
RETURNS TABLE(id varchar, pathset_id varchar, utility double precision) AS
$func$
BEGIN
RETURN QUERY
SELECT "ID", "PATHSET_ID", "UTILITY"
FROM "SinglePath_Scaled_HITS_distinctODs"
WHERE "PATHSET_ID" = $1;
END
$func$ LANGUAGE plpgsql;
RETURNS TABLE is the modern, more elegant, equivalent form of the combination RETURNS SETOF record and OUT parameters.
IF exists ... is buying you nothing here. Run the query; if nothing is found, nothing is returned. Same result for half the cost.
From this piece of code:
soci::rowset<sim_mob::SinglePath> rs =
(sql.prepare << "get_path_set_1(:pathset_id_in)",soci::use(testStr));
it appears you're trying to prepare a query that just contains the function call without even a SELECT.
That's not valid in SQL. You want to prepare this query instead:
SELECT * FROM get_path_set_1(:pathset_id_in)
This form (select * from function(...)) is also necessary because the function returns a resultset with multiple columns, as opposed to just a scalar value.
Also as Erwin mentions, the OUT and SETOF RECORD are weird in this case, I'll second his advice on using RETURNS TABLE.