I'm working passing ms sql server statements into hana sql statements. I have a variable (Tab) type Table and a variable string (query) defined as:
Hana Statement
CREATE TYPE "tab_table_TYPE" AS TABLE ("DocEntry" integer, "LineId" integer, "VisOrder" integer, "Object" nvarchar(20));
v_Tab tab_table_TYPE
query := 'SELECT [DocEntry],[LineId],[VisOrder] ,[Object] FROM [#INV_AFC]';
so I'm trying to convert this Ms Sql Statement into a Hana Statement :
Ms Sql Server Statement
INSERT INTO #v_Tab([DocEntry],[LineId],[VisOrder],[Object]) exec (#query)
I wish to use an internal table type variable which can hold the resultset from the query!
When I use the Sql Converter with this sentence displays this error:
--[Note:ErrorModifier] INSERT INTO statement does not support EXEC; use EXEC('insert into table '+ originalstatement)
--[Note:Stringifier] SAP HANA does not support InsertTarget
Finally the question is : How would be the correct Hana Sql Statement for this case?
The syntax of your table-type creation is correct. I guess you are trying to execute the query inside a procedure.
Inside a procedure, you have different options. If your query is only a partial result and you want to run further statements on the result set of the query, you don't need to initialize a table variable at all. Just assign a variable to a resultset:
table_variable = SELECT DocEntry, LineId, VisOrder, Object FROM INV_AFC;
// Use table_variable for further statements, for example:
SELECT count(*) INTO resultSetCount FROM :table_variable;
If your query is already the final result, you can easily define an output variable and directly assign your result set as output variable. For example:
CREATE PROCEDURE "YOURSCHEMA"."SomeProcedureName" (
in someInputVariable1 NVARCHAR(255),
in someInputVariable2 BIGINT,
out tableVariable "YOURSCHEMA".tab_table_TYPE)
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER AS
BEGIN
tableVariable = SELECT DocEntry, LineId, VisOrder, Object FROM INV_AFC;
END;
When you then call this procedure the 3rd parameter will automatically contain your result set:
call "YOURSCHEMA"."SomeProcedureName"('someString', 123, ?);
Related
I've written a stored procedure which uses a for loop to execute a query for a list of views. It generates a dynamic sql statement for each view inside the for loop and then executes it, which inserts output into a declared temporary table.
The for loop works perfectly and it runs without errors, however if I add a select statement after the END FOR; to get the final output from the temporary table I get the error below. Does anyone have any ideas please?
Error 16/07/2018 10:43:41 0:00:00.007 DB2 Database Error: ERROR [42601] [IBM][DB2/AIX64] SQL0104N An unexpected token "select *" was found following "1; END FOR; ". Expected tokens may include: "<call>". LINE NUMBER=31. SQLSTATE=42601
SQL Code:
BEGIN
DECLARE SQLTEXT varchar(500);
DECLARE GLOBAL TEMPORARY TABLE SESSION.AS_USAGE_RESULTS(
temp table columns
);
FOR v as cur1 cursor for
select distinct viewname,viewschema
from syscat.VIEWS
DO
SET SQLTEXT = 'Dynamic Insert into temp table here'
PREPARE s1 FROM SQLTEXT;
EXECUTE s1;
END FOR;
select *
from SESSION.AS_USAGE_RESULTS;
DROP TABLE SESSION.AS_USAGE_RESULTS;
END
Your mistake is that if you wish to return a result-set from session.as_usage_results, then you must declare a cursor for its select, and open that cursor then end the sproc. This is a FAQ. There are examples in the IBM Db2 Server SAMPLES directory and in the Db2 Knowledge Center.
Inside the sproc, you can either use SELECT ... INTO, or use a select within a cursor, or use a SELECT as part of a SET statement.
You should not drop the session table in the procedure in case the result-set won't be consumed before the table gets dropped. Either drop the session table elsewhere or use an alternative design.
In your example you don't need cursor cur1, so below I show a stilted artificial example of what your might mean. It is artificial because you can see that the session table is also redundant for this example, but it shows the use of the cursor for the result-set.
--#SET TERMINATOR #
create or replace procedure dynproc1
language sql
specific dynproc1
dynamic result sets 1
BEGIN
DECLARE v_sqltext varchar(2000);
DECLARE c1 cursor with return to client for s1;
DECLARE GLOBAL TEMPORARY TABLE SESSION.AS_USAGE_RESULTS ( viewname varchar(128), viewschema varchar(128) );
insert into session.as_usage_results(viewname, viewschema) select viewname, viewschema from syscat.views;
set v_sqltext = 'select * from session.as_usage_results';
prepare s1 from v_sqltext;
open c1;
END
#
I created a SQL procedure that replaces all values in a field with Xs the same length as the original values.
Update Table
Set Name = Replicate('x', Len(Name))
I am trying to alter this procedure so that I can just pass a table and field name as a parameter on execute instead of editing the stored procedure every time I want to pass a new field. Is there a way to do this?
This is what I think the execute statements should look like when I want to x out the values in another field:
Exec MyProcedure ‘Users’, ‘Email’
You can use EXEC to execute sql statements like this: EXEC (#sqlCommand). SqlCommand would be the string composed by you based on the received parameters.
Also, another option would be to run the statement using sp_executesql.
I would like to execute a stored procedure X from within the SELECT statement of stored procedure Y, so that X's value can be returned as part of Y's data.
I am trying the following syntax, but it's apparently not valid.
SELECT name, type, (EXEC X #type=type)
FROM table
As I hope you can see above, I need to pass the current row's type value to procedure X to get the proper return value.
Disclaimer: I probably just don't know what I'm doing.
The approach what you have tried is invalid. Instead of the X as the stored procedure convert it as user-defined function. like the below
Create function dbo.fnGetTypeDetail
(
#type varchar(50)
)
returns varchar(100)
As
Begin
return --do your operation;
End
And replace your query as:
SELECT name, type, dbo.fnGetTypeDetail(type) AS TypeDetail
FROM table
For sample, I created a scalar function. Based on your requirement you can create inline table valued function as per the example
You can't EXEC a stored proc inside a SELECT statement.
What you can do is INSERT..EXEC a stored proc into a temp table, and then run a SELECT statement that queries that temp table, while joining to other tables if desired.
Psuedo-example:
INSERT INTO #Tmp (Column1) EXEC X;
SELECT Name, Type, (SELECT Column1 FROM #tmp)
FROM MyTable
Is it possible to load a table from a with statement via a stored procedure in HANA? Nothing i try seems to work, and the only thing that does work when creating a procedure is just displaying the data from the with statement via a select. Below I show three examples I have tried for accessing with statement data. Currently on HANA revision 84. Please note the table create is just for purposes of the test example.
CREATE PROCEDURE test_proc
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER
AS
BEGIN
create table t1 (cal_day date);
with w1 as (
select current_date cal_day from dummy
)
--works just fine but isn't loading the data into anything
select * from w1;
--get indentifier must be declared error
select cal_day into t1 from w1;
--get incorrect syntax error
insert into t1
select cay_day from w1;
END
When you want to execute DDL statements in a SQLScript procedure you'll need to use dynamic SQL for that (EXEC).
I have a requirement where-in I need to read a table (table name provided as input parameter of the SP), store the results in a temp table and then store the count of the read table into a variable. Please advise how can this be achieved. I have been able to read the table and its count using dynamic query but am not able to put the results in a temp table/ variable. 'Select' and 'Into' clauses do not seem to be working with 'Execute Immediate'. Thanks.
It is not very clear to me exactly what is being asked, but you should be able to execute a SELECT statement in the following manner:
CREATE PROCEDURE p1(IN tablename VARCHAR) AS
BEGIN
execute immediate 'SELECT * FROM ' || :tablename;
END;
Then the following statements create a table and call the procedure to retrieve the result:
create table T (i integer);
insert into T values (123);
The following would produce a result set with one row/column with the value 123:
CALL p1('T')
Please note that with this type of functionality, you need to be very careful not to allow any user-provided input to be given directly to a procedure that uses EXECUTE IMMEDIATE to avoid the possibility of SQL injection attacks.