Using NEWUID() function in HANA database - sql

I'm trying to use NEWUID() function to generate unique digits, but can't execute code because of probable errors in syntax.
How can I correct this one?
Thanks.
CREATE PROCEDURE GENERATINGN (
IN
p_docentryt NVARCHAR(50)
)
LANGUAGE SQLSCRIPT
AS
BEGIN
SELECT cast("ItemCode" || '-' || NEWUID() as nvarchar(50)) AS "UNIQUEIDENTIFIER"
FROM "OITM"
WHERE "T0"."DocEntry" = p_docentryt;
END;
It should be generate digits like this:
IT1225-513613161514161

The code looks ok to me. Wat error message do you have? Can you tell a bit more about the HANA version you are using?
I executed the following similar SQL code and it worked:
CREATE PROCEDURE GENERATINGN (IN p_docentryt NVARCHAR(50))
LANGUAGE SQLSCRIPT
AS
BEGIN
SELECT cast("ItemCode" || '-' || NEWUID() as nvarchar(50)) AS "UNIQUEIDENTIFIER"
FROM (
SELECT 'my-ItemCode' as "ItemCode" FROM DUMMY
);
END;

Related

HANA + Is it possible to create a local temp table with dynamic name (name including current time)?

As we do in SQL, is it possible to pass variable on create statement as a table name in HANA?
I'm trying the below code but its throwing an error
CREATE PROCEDURE temp_table()
AS
table_name nvarchar(255);
BEGIN
table_name := '#TMP_TABLE'+ CURRENT_TIMESTAMP;
CREATE LOCAL TEMPORARY COLUMN TABLE :table_name(
SCENARIO varchar(64) NULL,
SCENARIO_CY varchar(64) NULL,
MONTH_NO numeric(4, 0) NULL
);
DROP TABLE :table_name;
END;
Please help me to find out a solution.
What you are looking for is Dynamic SQL. You will need to pass your SQL statement as a string to function EXEC or EXECUTE IMMEDIATE. The timestamp dependent name can be assembled by string concatenation.
In your code above your are using '+' to do string concatenation:
table_name := '#TMP_TABLE'+ CURRENT_TIMESTAMP;
IMHO this does not work on HANA. You should use a double pipe '||' instead:
table_name := '#TMP_TABLE' || CURRENT_TIMESTAMP;

Redshift dollar quoting inside a procedure

I have a procedure which accepts the table name and the 3 fields that need filling. This is to be called from another procedure that loops through another table deciding which sub-table to put stuff into. The important bit is a simple insert statement, e.g.
insert into table1 values
('blah','String','50');
So that 4 parameters coming in (table1, and the 3 values). How would I do this using dollar quoting? Obviously this doesnt work but gives you an idea of what I'm trying to accomplish:
create or replace procedure
insert_dc_table(p_tblname varchar,
p_name varchar,
p_datatype varchar,
p_datalen varchar)
as $$
begin
execute
'insert into '||p_tblname||'(name,datatype,datalen) values '
||'('
||p_name||', '
||p_datatype||', '
||p_datalen
||')';
end;
$$ language plpgsql;
I'd need double-dollars around some, but am unsure of exactly where $$ and quotes go in all this !*&#!
I could declare a variable to hold the execute statement and do:
declare a _output varchar(200);
a_output := $$ insert into $$||p_tblname||$$(name,datatype,datalen) values ( '$$||p_name||$$',
well, i get lost there!
Thanks in advance for help!
Redshift Stored Procedures only require dollar quoting of the procedure body. Quotes inside the the procedure body are interpreted as normal.
You may find that your SQL client does not submit the SP create correctly due to the dollar quotes. If so I recommend using psql to create the stored procedure.
Sample stored procedures are available in our "Amazon Redshift Utils" GitHub repository.
Here's a modification of your example:
-- DROP PROCEDURE insert_dc_table(VARCHAR,VARCHAR ,VARCHAR ,VARCHAR);
CREATE OR REPLACE PROCEDURE insert_dc_table(
p_tblname VARCHAR, p_name VARCHAR, p_datatype VARCHAR, p_datalen VARCHAR )
AS $$
DECLARE
rows INTEGER;
BEGIN
sql := 'INSERT INTO '||p_tblname||' (name, datatype, datalen)'
||' VALUES ('||p_name||','||p_datatype||','||p_datalen||');';
RAISE INFO 'Running SQL: %', sql;
EXECUTE sql;
GET DIAGNOSTICS rows := ROW_COUNT;
RAISE INFO 'Rows inserted = %', rows;
END
$$ LANGUAGE plpgsql;
-- CALL insert_dc_table ('test_table', 'name', 'type', 'length');

Cannot pass parameter inside stored procedure in redshift

I have written the procedure which calls the parameter in the select query, but it's not working. When I print that parameter it's working fine, but with the select query, it's not working.
I have used Aginity workbench for redshift to execute the stored procedure.
CREATE or replace PROCEDURE get_tbl_name(IN tablename varchar, IN columnname VARCHAR, IN mindate varchar) AS $$
Declare
evalmindate varchar;
BEGIN
Raise info 'tablename = %, columnname = %, mindate = %', tablename,columnname,mindate;
if mindate is null then
select min(columnname) into evalmindate from tablename;
else
evalmindate=mindate;
end if;
END;
$$ LANGUAGE plpgsql;
Calling Proc:
call get_tbl_name('test_bq', 'date',NULL);
Output:
tablename = test_bq, columnname = date, mindate = <NULL>
Error Message
42601: syntax error at or near "$2"
From the output, we can able to see the parameter inside the procedure when I print, but I can't pass the parameter to the select query, it throwing an error. Kindly help me with this.
You can't use the variable as a column or table name directly in a stored procedure query. Instead you need to compose a query string and execute that.
Also the INTO var syntax needs to come first in a plain query and last in an EXECUTE.
You have:
select min(columnname) into evalmindate from tablename;
Try this:
EXECUTE 'select min('|| columnname ||') from '|| tablename ||';' INTO evalmindate;

Pass SQL string to oracle stored procedure and get results with execute immediate

I am trying to pass in a SQL string to a stored procedure and using EXECUTE IMMEDIATE to return the results. Something like this:
CREATE PROCEDURE P360_RCT_COUNT (sqlString IN VARCHAR2)
AS
BEGIN
EXECUTE IMMEDIATE sqlString;
END;
/
I am not sure how to accomplish it. With the above, when I execute the SP using the command below, I get an error:
EXECUTE P360_RCT_COUNT 'SELECT COUNT(DISTINCT ENTITY_ID),ADDR_COUNTY FROM P360_V_RCT_COUNT GROUP BY ADDR_COUNTY';
The error is: ORA-06550: line 1, column 22:
PLS-00103: Encountered the symbol "SELECT COUNT(ENTITY_ID),ADDR_COUNTY
FROM P360_V_RCT_COUNT GROUP " when expecting one of the following:
:= . ( # % ; The symbol ":=" was substituted for "SELECT
COUNT(DISTINCT ENTITY_ID),ADDR_COUNTY FROM P360_V_RCT_COUNT GROUP " to
continue.
Basically I am building a SQL string in a system and need to pass it in to the SP and get the results back to the system. I am relatively new to stored procedures in Oracle.
The easiest way to work with a result set is sys_refcursor. This can be used quite easily with JDBC or ODBC.
Your procedure would look like this:
CREATE PROCEDURE P360_RCT_COUNT (
sqlString IN VARCHAR2
, p_result_set out sys_refcursor)
AS
BEGIN
open p_result_set for sqlString;
END;
/
Obviously the precise details of how you call it will vary according to your client. But in SQL*Plus it would be:
var rc refcursor
exec P360_RCT_COUNT( 'SELECT COUNT(DISTINCT ENTITY_ID),ADDR_COUNTY FROM P360_V_RCT_COUNT GROUP BY ADDR_COUNTY', :rc);
print rc
To return lists of values in a OUT parameter you need to decide the type(s) to use.
Say, for example, you have to return some varchar2 and some date lists, you could use something like this:
create or replace type tabOfVarchar2 is table of varchar2(100);
create or replace type tabOfDates is table of date;
create or replace procedure testProc(pString IN varchar2,
pOutVarchar1 OUT tabOfVarchar2,
pOutVarchar2 OUT tabOfVarchar2,
pOutVarchar3 OUT tabOfVarchar2,
pOutDates OUT tabOfDates
) is
begin
execute immediate pString
bulk collect into pOutVarchar1, pOutVarchar2, pOutVarchar3, pOutDates;
end;
This is way you can test this procedure:
declare
v1 tabOfVarchar2 ;
v2 tabOfVarchar2;
v3 tabOfVarchar2;
d1 tabOfDates ;
vSQL varchar2(100) := 'select ''a'', ''b'', ''c'', sysdate from dual';
begin
testProc(vSQL, v1, v2, v3, d1);
--
for i in v1.first .. v1.last loop
dbms_output.put_line(v1(i) || '/' || v2(i) || '/' || v3(i) || '/' || to_char(d1(i), 'dd/mm/yyyy'));
end loop;
end;
which gives:
a/b/c/14/04/2017
This only works with queries that give exactly a fixed number of columns, of known types.

DB2 - function to return max value from specified column

I'm new to DB2 PL/SQL and ran into some trouble, as there is not much community resources except for the official documentation which doesn't answer to all my questions.
I'm doing some data migration, and need a function that would return a max value from a specified column, from a specified table. In the last 2 hours I've come up with two approaches, but none of these works - due to my lack of knowledge of DB2 PL/SQL.
First one is preparing a query and executing it, but I can't execute a select query into a variable. Here's the code that doesn't execute:
CREATE OR REPLACE FUNCTION getMaxColValue (schemaName VARCHAR(30),
tableName VARCHAR(30), columnName VARCHAR(30))
-- function used to get max ID of a column during data migration
RETURNS INTEGER
LANGUAGE SQL
BEGIN
DECLARE query VARCHAR(1000);
DECLARE maxColValue INT;
DECLARE stmt STATEMENT;
SET query = 'select max(' || columnName || ') from ' || schemaName || '.' || tableName || '';
PREPARE stmt FROM query;
EXECUTE query INTO maxColValue;
RETURN maxColValue;
END
Error returned:
Lookup Error - DB2 Database Error: ERROR [07003] [IBM][DB2/AIX64] SQL0518N The statement named in the EXECUTE statement is not in a prepared state or is a SELECT or VALUES statement.
I've also tried something like this, returning scalar SQL value:
CREATE FUNCTION getMaxColValue_2 (schemaName VARCHAR(30), tableName VARCHAR(30), columnName VARCHAR(30))
RETURNS INT
LANGUAGE SQL
READS SQL DATA
NO EXTERNAL ACTION
DETERMINISTIC
RETURN
SELECT max(columnName)
FROM schemaName.tableName;
Error returned:
Lookup Error - DB2 Database Error: ERROR [42704] [IBM][DB2/AIX64] SQL0204N "SCHEMANAME.TABLENAME" is an undefined name.
but I guess it's harder to pass schemaname and tablename as variables here. I'll be gateful for any help. Window function is not much of an option, as I need to use this function in migration procedures and not simple select statements.
There are some syntax errors, but what's worse there are probably some logical errors due to my lack of knowledge of PL/SQL.
Cheers,
Jony
You cannot EXECUTE a SELECT statement, which is exactly what the error message is telling you.
Instead, you should declare a cursor, open it, then fetch the result into your variable:
CREATE OR REPLACE FUNCTION getMaxColValue (schemaName VARCHAR(30),
tableName VARCHAR(30), columnName VARCHAR(30))
RETURNS INTEGER
LANGUAGE SQL
not deterministic
reads sql data
begin
declare l_max int;
declare c_cur cursor for l_stmt;
prepare l_stmt from 'select max(' || columnName || ') from ' || rtrim(schemaName) ||
'.' || tableName;
open c_cur;
fetch c_cur into l_max;
close c_cur;
return l_max;
end