Passing a Table Value Parameter (TVP) to a stored procedure from Qlik - stored-procedures

In C# I've had colleagues calling a stored procedure which took a User-Defined Data Type as a parameter.
Taking from Access Stored Procedure With User Defined Data Type Using Entity Framework as an example:
-- ================================
-- Create User-defined Table Type
-- ================================
--DROP TYPE dbo.Tvp_Employee
CREATE TYPE dbo.Tvp_Employee AS TABLE
(
Name varchar(50) NULL,
Salary numeric(18,0) Null
)
GO
And then a stored procedure like this:
- =============================================
-- Author: Mitesh Gadhiya
-- Create date: 15-jul-017
-- Description: Demo for Inserting data with Custom table Type
-- =============================================
--DROP PROC Proc_insertemployee
CREATE PROCEDURE Proc_insertemployee (#tbl_Employee TVP_EMPLOYEE readonly)
AS
BEGIN
BEGIN try
-- Insert statements for procedure here
INSERT INTO tbl_employee (NAME, salary)
SELECT NAME, salary
FROM #tbl_Employee
END try
BEGIN catch
DECLARE #ErrorNumber INT
DECLARE #ErrorMessage VARCHAR(2000)
DECLARE #ErrorSeverity INT
DECLARE #ErrorState INT
SELECT #ErrorNumber = Error_number(),
#ErrorMessage = 'Error occured at time of inserting'
+ Error_message(),
#Errorseverity = Error_severity(),
#ErrorState = Error_state()
RAISERROR (#Errormessage,#ErrorSeverity,#ErrorState)
END catch
END
go
How do you call such a stored procedure from Qlik ?
In C# you can use a DataTable as a parameter, and it makes it easy to insert (a lot of) rows
Is this possible in Qlik Sense? I do not know a lot of Qlik, and I have not been able to find any examples on this?

Related

Dynamic SQL calling another stored procedure in Teradata

I've seen in the help guides that you cannot use a call statement in a teradata dynamic sql statement without output parameter.
I assume this implies I can, If the proc has an output parameter.
has anyone done this?
Scenario -
I have a table that at some point I'll expand out in terms of fields for logic on when things should run, and this table is managed elsewhere -
CREATE TABLE DB.SP_Test
(
ProcName VARCHAR(250)
,ProcRun VARCHAR(1)
);
now I added chrTest as an output however, I am still getting an error on run (no compile error)
The error :-
SQL_State SQL_Exception
T7689 Invalid dynamic SQL statement.
REPLACE PROCEDURE DB.Test_Control (OUT chrTest VARCHAR(250) )
SQL SECURITY INVOKER
LMain:
BEGIN
DECLARE sqlProcRun VARCHAR(20000);
DECLARE CONTINUE HANDLER
FOR SqlException
BEGIN
-----------------------------------------------------------------------------
DECLARE strExceptionText VARCHAR(250);
GET DIAGNOSTICS EXCEPTION 1 strExceptionText = Message_Text;
INSERT INTO DB.PROC_ERROR VALUES
(
'Test_Control'
,:SqlState
,strExceptionText
,Current_Timestamp
)
;
END;
-----------------------------------------------------------------------------
SET sqlProcRun ='';
L0:
FOR procs_run_cursor AS select_list
CURSOR FOR
SELECT Trim(ProcName) AS ProcName
FROM DB.SP_Test
DO
/*creating a lost of call statements to run*/
SET sqlProcRun = sqlProcRun ||'CALL DB.'||procs_run_cursor.ProcName|| '();';
END FOR L0;
EXECUTE IMMEDIATE sqlProcRun;
END;

HSQL problem when using TIMESTAMP value as IN parameter in stored procedure

Overview HSQL IN parameter of type TIMESTAMP doesn't work as expected for HSQL stored procedure.
Given the following DDL :
CREATE TABLE TS_STORE (
ID_COL VARCHAR(20) NOT NULL PRIMARY KEY,
TS TIMESTAMP
);
A DML statement such as :
INSERT INTO TS_STORE (ID_COL, TS) VALUES ('key1', '2020-02-19 12:17:53');
will successfully insert a row.
Then when I attempt to create a stored procedure to do the same as:
CREATE PROCEDURE TEST_PROC(IN IN_KEY VARCHAR(20), IN IN_TS TIMESTAMP)
MODIFIES SQL DATA
BEGIN ATOMIC
INSERT INTO TS_STORE(ID_COL, TS)
VALUES (IN_KEY, IN_TS);
END;
and attempt to call it as:
CALL TEST_PROC('key2', '2020-02-19 12:17:53');
Then I get an error: "incompatible data type in conversion".
This is a problem for me, since I am not allowed to change the signature of the the stored procedure to bypass the problem, since in my case HSQL is used as a mock for a production database (DB2) where the equivalent procedure works as expected.
It works if you call the procedure with a TIMESTAMP value, as opposed to the character string.
CALL TEST_PROC('key2', TIMESTAMP'2020-02-19 12:17:53');

How to get the restult table of a stored procedure into a temp table?

Enviroment:
DB2 Version 11.1,
OS - Linux
How to get the result table of stored procedure into a temp table?
The table and the result have the same table configuration (firstColumn int, secondColumn nvarchar(255))
I'm assuming your stored procedure returns an open cursor, so you want to consume that cursor, inserting its contents into a session table (declared global temporary table) on Db2-LUW.
In addition to fetch and insert statements, you need to understand the following statements:
associate result set locator ... with procedure ...
allocate ... cursor for result set ...
Here is a deliberately artificial example of a nested stored procedure, which shows fetching a result-set from a nested procedure into a session table. The purpose is to show how the syntax works, rather than to do anything useful with data (as the net effect can be equally met by a simple catalog query in this case). This example can be run at the Db2 command-line (for example at the bash shell, after you connected to a database with appropriate permissions):
update command options using s on ;
--#SET TERMINATOR #
create or replace procedure alltabs
dynamic result sets 1
language sql
specific alltabs
begin
declare v_cur cursor with return to caller for select tabschema,tabname,type from syscat.tables ;
open v_cur;
end#
declare global temporary table session.thetables(tabschema varchar(128), tabname varchar(128))
not logged with replace on commit preserve rows #
create or replace procedure populate_dgtt()
language sql
specific populate_dgtt
begin
declare v_rs result_set_locator varying;
declare v_tabschema varchar(128);
declare v_tabname varchar(128);
declare v_type char(1);
declare sqlstate char(5) default '00000';
call alltabs;
associate result set locator (v_rs) with procedure alltabs;
allocate v_rscur cursor for result set v_rs;
fetch from v_rscur into v_tabschema, v_tabname, v_type;
while ( sqlstate = '00000') do
if v_type='V' and v_tabschema='SYSSTAT'
then
insert into session.thetables(tabschema,tabname) values (v_tabschema, v_tabname);
end if;
fetch from v_rscur into v_tabschema, v_tabname, v_type;
end while;
return;
end#
call populate_dgtt()#
select rtrim(Tabschema)||'.'||rtrim(tabname) from session.thetables #

how to use dotconnect for oracle to call stored procedures with nested table as parameter

I want to pass a nested table ( OracleTable in dotconnection ? ) as a parameter to call the stored procedure in a package. The type test002_table is defined in the package. Codes of stored procedure are below:
create or replace package testPro is
type test002_table is table of test002%rowtype;
procedure testInsert(tbs test002_table);
end testPro;
create or replace package body testPro is
procedure testInsert(tbs test002_table) is
i int;
begin
delete from test002;
for i in 1..tbs.count loop
insert into test002 values tbs(i);
end loop;
end;
end;
A test written in PL\SQL runs sucessfully :
declare
tab testpro.test002_table := testpro.test002_table();
item test002%rowtype;
i integer;
begin
tab.extend();
item.id:=1;
item.name:='a';
item.lev:=5;
item.age:=55;
item.address:='das';
tab(tab.count) := item;
testPro.testInsert(tab);
commit;
end;
But I don't know how to call this procedure using dotConnect. I've tried the following way but without sucess:
OracleCommand cmd = new OracleCommand();
cmd.Connection = con; //OracleConnection con
cmd.CommandType = System.Data.CommandType.StoredProcedure;
OracleType tp = OracleType.GetObjectType("testPro.test002_table", con);
OracleTable table = new OracleTable(tp);
Dotconnect couldn't find the type.
How could I get the required object of OracleType? Or could this problem be solved in other ways? Thanks a lot.
User-defined types declared in a package cannot be used outside of this package. Please define globally the type used with the OracleTable class:
create or replace type test002_type as object(
-- list here the test002 columns
c1 number,
c2 number
);
/
create or replace type test002_table is table of test002_type;
/
JIC: ROWTYPE is a PL/SQL construct and not recognized in the SQL create type statement.

Get specific fields from sys_refcursor in stored proc?

I am running an Oracle 9i server at my office. I am working on a procedure that passes a sys_refcursor as an out parameter to another package (along with other in parameters). I was able to define a type as a record of the various columns that the called procedure returns in the cursor. I can then loop over with code like this:
LOOP
fetch o_results into v_rec;
exit when o_results%notfound;
dbms_output.put_line(v_rec.some_id);
end loop;
Is there a way to only pull one column and not have to declare an entire rowtype? I tried something like:
LOOP
fetch o_results.some_id into v_id;
exit when o_results%notfound;
dbms_output.put_line(v_id);
end loop;
But that didn't work. Any other ideas?
No, you cannot fetch a single column into a local variable other than a record if the cursor returns a result set with multiple columns. However, you do have a few alternatives.
If you declare a strongly-typed cursor rather than a weakly typed cursor, you could declare your local variable based on that cursor definition rather than declaring a new collection.
create or replace procedure cursor_proc
as
cursor emp_cur
is
select empno, ename
from emp;
l_row emp_cur%rowtype;
begin
open emp_cur;
loop
fetch emp_cur into l_row;
exit when emp_cur%notfound;
dbms_output.put_line( l_row.ename );
end loop;
close emp_cur;
end;
Alternately, if you know that the weakly typed ref cursor will always return all the columns in a particular object, you can anchor your local variable declaration to that object. You can always make this work by declaring a view that your cursor selects from. For example
create or replace view vw_emp
as
select ename, empno
from emp
create or replace procedure cursor_proc2
as
emp_cur sys_refcursor;
l_row vw_emp%rowtype;
begin
open emp_cur for select * from vw_emp;
loop
fetch emp_cur into l_row;
exit when emp_cur%notfound;
dbms_output.put_line( l_row.ename );
end loop;
close emp_cur;
end;
Finally, if you use an implicit cursor, Oracle will implicitly declare the collection type
create or replace procedure cursor_proc3
as
begin
for emp in (select ename, empno from emp)
loop
dbms_output.put_line( emp.ename );
end loop;
end;

Resources