Order by in for loop (SQL UDF) - sql

I want to aggregate some rows using a SQL UDF. I want to first select the rows ordered by their id & then concatenate them in a comma separated column. I am having error on the order by clause in my function as it is inside a for loop. Is there any way to run this without removing the order by clause? My database is DB2
CREATE FUNCTION mySchema.getDates(recId INTEGER)
RETURNS VARCHAR(1024)
LANGUAGE SQL
BEGIN ATOMIC
DECLARE STR VARCHAR(1024);
SET STR = '' ;
LOOP1 : FOR ROW AS (select replace(char(myDate,EUR),'.','/') as myDate from myTable.BookingDates where recId=recId order by rec_crt-id)
DO
IF ROW.myDate IS NOT NULL THEN
SET STR = STR || CAST ( ROW.myDate AS VARCHAR ( 20 ) ) || ', ' ;
END IF ;
END FOR;
RETURN STR ;
END
SQL State: 42601
Vendor Code: -199
Message: [SQL0199] Keyword ORDER not expected. Valid tokens: ) UNION EXCEPT. Cause . . . . . : The keyword ORDER was not expected here.

This is not going to work:
where recId=recId
DB2 will not realize that you want one of these to be the function parameter and the other the column name. It will use the same one for both, having the effect of returning all rows. You need to name your function parameter something different than the column name.
Other than that, code similar to the above works fine for me.
Are you new to writing functions? One common mistake is having your SQL editor's statement delimiter set to ;. This will make it try to break up the function into statements, rather than sending the whole thing as a single command. It will lead to lots of syntax errors such as above (Sorry if you know that already, but it took me awhile to figure that out!).

Related

Declare long string for using few times in query statement ORACLE

I want to build a query in oracle and for some materials and I want to declare these materials once and I want to use this variable in the query. The variable will be a string of strings.
It is my query but is wrong. How I can write correct query :
enter code herev_material varchar2(18000) := '2421032060SST','2421040080SST','2421050080SST';
SELECT MARA.MATERIAL,MARA.NAZWA_MATERIALU,MARA.JM,MARA.MAABC
FROM OLAP_DANE.MV_SAP_MARA MARA
Left outer join
(select something
from a
where material in v_material)c
on c.material in mara.material
WHERE MARA.MATERIAL = v_material
;
Not only query wrong, declaration of string is also wrong. You can not declare string such way.
1. For simple solution, if we can suppose that values of materials are unique from comma to comma, you can declare string like
v_material varchar2(18000) := ',2421032060SST,2421040080SST,2421050080SST,';
and when use in query
... and instr(','|| MARA.Materials ||',', v_material) > 0
2. Or way two, and it's more right in my point of view.
declare schema level table type of string
create or replace type TStrings as table of varchar2(150);
declare
v_materials TStrings := TStrings('2421032060SST','2421040080SST','2421050080SST');
and then use in query like
... select column_value from table(v_material) ...
something like this.

Syntax for insert data into table in SAP BODS

I tried this to insert data into table in SAP BODS, but it seems like it won't work :
BEGIN
sql('TEST_DB', 'INSERT INTO TEST_CODE VALUES ({$ID_NUMBER}, {$DATE}, {$NAME}))
END
Is there any missing syntax? I already search for the sql statement and followed them, but still can't work. Appreciate any help. Thanks.
SQL function needs two parameters .
1st is the DataStore Name and second being the query. I can't find any flaw in your sql function.May be values are not according to the datatypes of the columns.
Try using SQL transform instead of SQL function
,with SQL transform you can verify the syntax too.
Try the following syntax:
BEGIN
sql('TEST_DB', 'INSERT INTO TEST_CODE VALUES ( ([$ID_NUMBER]), ([$DATE]), ([$NAME]) ))
END
The correct syntax is:
BEGIN
sql('TEST_DB', 'INSERT INTO TEST_CODE VALUES ('|| $ID_NUMBER ||' , '||$DATE|| ' , '||$NAME||')');
END

How to do a conditional where clause with where in PL/SQL within Procedure

I have a pretty simple Stored Procedure that I am in trouble to do because i'm new to SQL and PL/SQL. I Have a table with a name column that is a varchar(55).
I discovered that if the user executes my procedure with an empty string as a paramter the LIKE statment brings all rows from TABLE1
SELECT *
FROM TABLE1
WHERE COLUMN LIKE VARIABLE || '%'
AND...
So I tried to change the query so if the VARIABLE is passed with a empty string it can still perform other conditions in the where statment.
SELECT *
FROM TABLE1
WHERE (VARIABLE <> '' AND COLUMN LIKE VARIABLE || '%')
AND...
But now wherever I pass as variable ('', NULL, 'anystring') I get no rows returned.
How can I build a query that validates if the variable is different of empty string and if it is it performs the LIKE statment with the variable correctly?
If I understand you correctly, it is not difficult thing to do. You can use conditional WHERE clause using CASE WHEN. So your query will support different scenarios, something like this:
SELECT *
FROM TABLE1
WHERE (CASE WHEN variable IS NULL AND column IS NULL THEN 1
WHEN variable LIKE '%' AND column LIKE variable||'%' THEN 1
ELSE 0
END) = 1
AND...
Basically, it checks if the variable = '' then it will compare the column against ''. Otherwise, it will compare it against variable||'%'.
Notice, Oracle treats empty string of the type VARCHAR as NULL (this does not apply to CHAR). So, in the first scenario we compare against NULL.
Hello Just a thought for this we can use Dynamic sql too. If you may try this approach. Hope it helps.
CREATE OR REPLACE PROCEDURE SPS_TEST_OUT(
p_input_in IN VARCHAR2
)
AS
lv_sql LONG;
lv_where VARCHAR2(100);
BEGIN
lv_where:= CASE WHEN p_input_in IS NULL OR p_input_in = '' THEN
''
ELSE
' AND COLUMN1 LIKE '''||p_input_in||'''%'
END;
lv_sql:='SELECT * FROM TABLE
WHERE 1 = 1
' ||lv_where;
dbms_output.put_line(lv_sql);
END;

MonetDB Prepare Statement in Function

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.

SQL syntax as parameters for a MySQL Routine?

I have the following MySQL routine:
DELIMITER $$
CREATE DEFINER=`root`#`%` PROCEDURE `getGroupOrders`(grp INT,
ord CHAR(20),
srt CHAR(4),
page INT,
count INT)
BEGIN
SELECT *
FROM `dbre`.`order_info`
WHERE username IN (SELECT `dbre`.`users`.`username`
FROM `dbre`.`users`
WHERE `dbre`.`users`.`id_group` = grp)
ORDER BY ord srt LIMIT page,count;
END
As you can see, I want to pass the ordering column and sorting as a parameters, however I get a syntax error is there a way to do this or do I have to make similar routines for each type of ordering?
I don't think this is possible in the way you try it.
You cannot use a variable to define the ORDER BY column an direction.
The only workaround I can think of is to create a prepared statement from a dynamically created string (where you can use the variables to specify the order by details) and then execute that prepared statement.
Here is an example of such a dynamic statement:
http://forums.mysql.com/read.php?98,393613,393642#msg-393642