DECLARE #timeRange as varchar(max)
SET #timeRange= '00:30-01:00**00:20-01:00'
DECLARE #tblTime TABLE(RowNum int identity(1,1),TimeRange ntext)
INSERT INTO #tblTime SELECT rtrim(ltrim(items)) from split(#timeRange,'**')
select *from #tblTime
The above procedure is returning three rows with the middle being null
And
DECLARE #timeRange as varchar(max)
SET #timeRange= '00:30-01:00*00:20-01:00'
DECLARE #tblTime TABLE(RowNum int identity(1,1),TimeRange ntext)
INSERT INTO #tblTime SELECT rtrim(ltrim(items)) from split(#timeRange,'*')
select *from #tblTime
The above code is returning two rows exactly what I wanted.
I'd like to know why the split() function affects my result.
I have concatenated string with ** first then split, the result is different from the string concatenated with *.
EDITED: the split function is from SageFrame
Ignoring the \*\* which I assume should be **...
I guess (we don't know what the split function looks like) that the delimiter parameter is char(1) (or varchar(1)). This means that ** is truncated to *, so you get 3 rows.
Related
I'm writing a simple stored procedure for my Hana database, its behavior is to update a table and return the updated element. Here the code:
CREATE OR REPLACE PROCEDURE "UpdateTbl" (in _id integer, in formula text) AS
BEGIN
UPDATE "MyTable" SET "formula" = formula, WHERE "id" = _id;
SELECT "id", "formula" FROM "MyTable" WHERE "id" = _id;
END;
The problem i'm facing is that I cannot specify a TEXT input parameter in stored procedures.
A possible workaround could be to use NVARCHAR instead.
In this way, I can correctly create the stored procedure, but when I run it with 'dummy' value in the NVARCHAR field, i got this error
Error: (dberror) [7]: feature not supported: "Database"."UpdateTbl": ... : Unregistered function name: "to_text
It seems that it cannot convert NVARCHAR in TEXT.
So, there is a way to force the conversion of this kind of parameter in TEXT?
If not, there is a way I'm not considering to pass TEXT parameter as input (other data types, for instance)?
Thnaks in advance
this simple example works as expected when using NVARCHAR or NCLOB as procedure parameter type
DROP TABLE t1;
CREATE TABLE t1 (i int, t text fast preprocess off);
INSERT INTO t1 values(3,'');
INSERT INTO t1 values(4,'');
CREATE OR REPLACE PROCEDURE p1 (in i int, in t nclob) AS
BEGIN
UPDATE t1 SET t = :t WHERE i = :i;
--SELECT i,t FROM t1 where i = :i;
END;
CALL p1(3,'bob went to london');
CALL p1(4,'nancy moved to berlin');
SELECT * FROM t1 WHERE CONTAINS(*,'go',linguistic);
please provide your column properties
I am trying to write a stored procedure in AWS Redshift SQL and one of my parameters needs the possibility to have an integer list (will be using 'IN(0,100,200,...)' inside there WHERE clause). How would I write the input parameter in the header of the procedure so that this is possible (if at all?)
I've tried passing them in as a VARCHAR "integer list" type thing but wasn't sure then how to parse that back into ints.
Update: I found a way to parse the string and loop through it using the SPLIT_PART function and store all of those into a table. Then just use a SELECT * FROM table with the IN() call
What I ended up doing was as follows. I took in the integers that I was expecting as a comma-separated string. I then ran the following on it.
CREATE OR REPLACE PROCEDURE test_string_to_int(VARCHAR)
AS $$
DECLARE
split_me ALIAS FOR $1;
loop_var INT;
BEGIN
DROP TABLE IF EXISTS int_list;
CREATE TEMPORARY TABLE int_list (
integer_to_store INT
);
FOR loop_var IN 1..(REGEXP_COUNT(split_me,',') + 1) LOOP
INSERT INTO int_list VALUES (CAST(SPLIT_PART(split_me,',',loop_var) AS INT));
END LOOP;
END;
$$ LANGUAGE plpgsql;
So I would call the procedure with something like:
CALL test_string_to_int('1,2,3');
and could do a select statement on it to see all the values stored into the table. Then in my queries the need this parameter I ran:
.........................
WHERE num_items IN(SELECT integer_to_store FROM int_list);
Is there a way to create postgres stored function (using plpgsql to be able to set input parameters) that returns a custom data set?
I've tried to do something like this according to official manual:
CREATE FUNCTION extended_sales(p_itemno int)
RETURNS TABLE(quantity int, total numeric) AS $$
BEGIN
RETURN QUERY SELECT quantity, quantity * price FROM sales
WHERE itemno = p_itemno;
END;
$$ LANGUAGE plpgsql;
but result is an array with only one column which contains type (quantity, total), but I need to get two column array with 'quantity' column and 'total' column.
At a guess you're running:
SELECT extended_sales(1);
This will return a composite type column. If you want it expanded, you must instead run:
SELECT * FROM extended_sales(1);
Also, as #a_horse_with_no_name notes, a PL/pgSQL function is completely unnecessary here. Presumably this is a simplified example?
In future please include:
Your PostgreSQL version; and
The exact SQL you ran and the exact output you got
I have a DB2 stored procedures to get n number of sequence values and then combine them into a single comma delimited string and return it. The concat function in the stored procedure is not working as expected.
CREATE PROCEDURE REFWTX.GET_SEQ_VALUES (in numb integer, OUT SEQVALUES VARCHAR(10000))
LANGUAGE SQL
SPECIFIC GET_SEQ_VALUES
BEGIN
DECLARE SEQ_VAL Integer;
DECLARE CUR_COUNT INTEGER;
SET CUR_COUNT=1;
WHILE (CUR_COUNT <= numb) DO
SELECT NEXTVAL FOR REFWTX.ACK_999_INTR_CTRL_NO_SEQ INTO SEQ_VAL FROM SYSIBM.SYSDUMMY1;
set SEQVALUES = SEQVALUES|| ',' || CHAR(SEQ_VAL);
SET CUR_COUNT=CUR_COUNT+1;
END WHILE;
return;
END
The portion of the procedure:
set SEQVALUES = SEQVALUES|| ',' || CHAR(SEQ_VAL);
is not working as expected. How do I concatenate strings in stored procedures?
You haven't told us how it is "not working as expected". Example inputs and output would be useful.
My guess would be that since you never initialize SEQVALUES, it is set to NULL and concatenating anything with NULL gives you NULL.
Also, instead of
SELECT NEXTVAL FOR REFWTX.ACK_999_INTR_CTRL_NO_SEQ INTO SEQ_VAL FROM SYSIBM.SYSDUMMY1;
why not use
VALUES NEXTVAL FOR REFWTX.ACK_999_INTR_CTRL_NO_SEQ INTO SEQ_VAL;
I have a need to run a recursive CTE within a stored proc, but I can't get it past this:
SQL0104N An unexpected token "with" was found following "SET count=count+1;
". Expected tokens may include: "". LINE NUMBER=26.
My google-fu showed a couple of similar topics, but none with resolution.
The query functions as expected outside of the stored proc, so I'm hoping that there's some syntactic sugar I'm missing that'll let this work. Similarly, the proc compiles and works without the query.
Here's a contrived example:
--setup
create table tree (id integer, name varchar(50), parent_id integer);
insert into tree values (1, 'Alice', null);
insert into tree values (2, 'Bob', 1);
insert into tree values (3, 'Charlie', 2);
-
- the proc
create or replace procedure testme() RESULT SETS 1 LANGUAGE SQL
BEGIN
DECLARE SQLSTATE CHAR(5);
DECLARE SQLCODE integer default 0;
DECLARE count INTEGER;
DECLARE sum INTEGER;
DECLARE total INTEGER;
DECLARE id INTEGER;
DECLARE curs CURSOR WITH RETURN FOR
select count,sum from sysibm.sysdummy1;
DECLARE hiercurs CURSOR FOR
select id from tree order by id;
SET bomQuery='';
PREPARE stmt FROM bomQuery;
SET count = 0;
SET sum = 0;
set total = 0;
OPEN hiercurs;
FETCH hiercurs INTO id;
WHILE (SQLCODE <> 100) DO
SET count=count+1;
with org (level,id,name,parent_id) as
(select 1 as level,root.id,root.name,root.parent_id from tree root where root.id=id
union all
select level+1,employee.id,employee.name,employee.parent_ id from org boss, tree employee
where level < 5 and employee.parent_id=boss.id)
select count(1) into sum from org;
SET total=total+sum;
FETCH hiercurs INTO id;
END WHILE;
CLOSE hiercurs;
OPEN curs;
END
the cte in db2 doesn't seem to recognize the scalar result of the query, and so it won't let the select into work (not a problem on Oracle or SQLServer)...solution is to open a cursor and FETCH INTO (instead of SELECT INTO) instead.
In addition to rjb's suggestion of enclosing the CTE query inside a cursor, you can also stuff the CTE into a user-defined function or a view, and then code a straight select against that object into your stored procedure.