translate from oracle to db2 - oracle

If time permits, would someone please let me know what syntax would need to be changed to accommodate this from oracle to db2? I am hoping to use the db2 command line prompt DB2 client version 10.5.3. Please let me know if you need anymore information. I changed the VARCHAR2 to VARCHAR and the NUMBER(3) to INT as well as NUMBER(10 to INT. Its much appreciated. Jean T.
DECLARE
v_count PLS_INTEGER := 0;
TYPE inv_rt IS RECORD (upc VARCHAR(20),
store INT,
inv_avail INT
);
TYPE inv_tt IS TABLE OF inv_rt;
inv_arr inv_tt;
CURSOR cur_data (in_date DATE)
IS
SELECT i.upc, i.storenumber, i.inv_avail - SUM(t.unitvolume) AS inv_avail
FROM zz_tran t,
zz_start_inv i
WHERE t.weekenddate <= in_date
AND t.upc = i.upc
AND t.storenumber = i.storenumber
GROUP BY i.upc, i.storenumber, i.inv_avail;
BEGIN
inv_arr := inv_tt();
FOR d IN (SELECT DISTINCT weekenddate
FROM zz_tran
ORDER BY weekenddate
)
LOOP
inv_arr := inv_tt();
OPEN cur_data (d.weekenddate);
FETCH cur_data BULK COLLECT INTO inv_arr;
CLOSE cur_data;
FORALL i IN inv_arr.FIRST .. inv_arr.LAST
UPDATE zz_tran
SET inv_avail = inv_arr(i).inv_avail
WHERE weekenddate = d.weekenddate
AND upc = inv_arr(i).upc
AND storenumber = inv_arr(i).store;
COMMIT;
END LOOP;
END;
/

If converting from Oracle to Db2, you can create your Db2 database in Oracle Compatibility mode. That will allow Db2 to recognize e.g. VARCHAR2 natively.
https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.5.0/com.ibm.db2.luw.apdv.porting.doc/doc/c_compat_oracle.html
You can also use the Database Conversion Workbench to assist in converting from Oracle to Db2
https://www.ibm.com/developerworks/community/groups/service/html/communityview?communityUuid=05901c97-75b2-47a1-9c32-25f748855913

Related

Convert integer to hours and minutes - getting PL/SQL numeric or value error

I am getting
ORA-06502 PL/SQL numeric or value error
when I am trying to execute this statement from Report Builder 6i and Oracle database 11g.
select to_char(to_date(lateby, 'sssss'), 'mi:ss')
from attendancelogs
where emp_no = :emp_no
and attendancedate = :dat;
late number(15);
The same statement when run under SQL*Plus is running fine without any error and fetching values the way I want.
Any help will be much appreciated.
Regards,
Mac
It might be a Reports bug, I don't know, but as a workaround you could try wrapping this into a stored procedure in the database as follows:
CREATE OR REPLACE FUNCTION sssss_to_miss ( p1 in varchar2 ) RETURN VARCHAR2 IS
BEGIN
RETURN ( to_char(to_date(p1, 'sssss'), 'mi:ss') );
END;
/
Then in the Reports Code:
select sssss_to_miss (lateby)
from attendancelogs
where emp_no = :emp_no
and attendancedate = :dat;
late number(15);
Alternatively, something like (not tested):
select to_char(to_number(lateby)/60,'00') || ':' || to_char(mod(to_number(lateby),60),'00')
from attendancelogs
where emp_no = :emp_no
and attendancedate = :dat;

Creating Oracle PL/SQL Stored procedure

I'm trying to convert the SQL Query to Oracle PL/SQL stored procedure.
Here is the query:
select * from table1 where DATE = " + s1 + " and TYPE='" + ty + "' and NAME='"+nm+"' Order by TYPE DEsc;
Here is the Stored Procedure:
CREATE PROCEDURE procedure1
(
s1 IN DATE,
ty IN CHAR DEFAULT 2,
nm IN VARCHAR2 DEFAULT 64
)
IS
d table1.DATE%TYPE;
C table1.TYPE%TYPE;
S table1.NAME%TYPE;
CURSOR tb IS select DATE,TYPE,NAME INTO d,c,s from table1;
BEGIN
FOR i IN tb
LOOP
DBMS_OUTPUT.PUT_LINE('DATE' ||i.DATE);
DBMS_OUTPUT.PUT_LINE('TYPE' ||i.TYPE);
DBMS_OUTPUT.PUT_LINE('NAME' ||i.NAME);
END LOOP;
END procedure1;
I do not see any output after Executing Stored procedure. I'm not sure if I have created the stored procedure correctly.
"I do not see any output after Executing Stored procedure"
Your "output" is DBMS_OUTPUT which is for displaying text to a screen. However, by default it writes the text to a buffer, and we need to enable the output to see the contents of the buffer.
How to do this varies depending on which client you're using. In SQL*Plus it's
SQL> set serveroutput on
In an IDE like TOAD, PLSQL Developer or Oracle SQL Developer there's a separate DBMS_OUTPUT tab: click on the tab and enable output (there's a button) - or set Preferences to always have it on.
DBMS_OUTPUT is rarely a useful means for returning data in an actual application. The normal approach is to use a Ref Cursor, which maps to JDBC and ODBC ResultSet classes. Something like this:
CREATE OR REPLACE PROCEDURE procedure1
(
s1 IN DATE,
ty IN CHAR DEFAULT 2,
nm IN VARCHAR2 DEFAULT 64,
rc out sys_refcursor
)
IS
BEGIN
open rc for
select * from table1
where d = s1
and c = ty
and s = nm;
END procedure1;
/
Incidentally, your parameters are defined with string datatypes but the defaults are numeric values. Please don't get into bad habits. Strong datatyping is a key defence against data corruption and broken code, so always use the correct data type.
try this;
CREATE PROCEDURE PROCEDURE1 (
S1 IN DATE,
TY IN CHAR DEFAULT 2,
NM IN VARCHAR2 DEFAULT 64
)
IS
BEGIN
FOR I IN (SELECT DATE, TYPE, NAME FROM TABLE1)--Easier way to use cursor
LOOP
DBMS_OUTPUT.PUT_LINE ('DATE' || I.DATE);
DBMS_OUTPUT.PUT_LINE ('TYPE' || I.TYPE);
DBMS_OUTPUT.PUT_LINE ('NAME' || I.NAME);
END LOOP;
END PROCEDURE1;
by executing this you only created the procedure and stored it in db, you need to call it and turn on system output to see the output. like this:
set serveroutput on;
begin
PROCEDURE1(null, null, null);
end;
What environment are using to compile your code? You should certainly be seeing some immediate feedback.
Note that in most environments, though, you need to do a little more than you did before.
The final ";" in your code is part of PL/SQL. It does not trigger execution of your DDL. Generally you should do this:
CREATE OR REPLACE PROCEDURE myproc
IS
BEGIN
...
END myproc;
/
And that "/" will submit your statement for execution.

Oracle equivalent of stored procedure that returns an inline table?

Example in T-SQL (SQL Server - taken from here):
CREATE PROC proc_authors
#au_lname VARCHAR(40)
AS
SELECT
au_id, au_fname, au_lname, city, state
FROM authors
WHERE au_lname = #au_lname
go
Is it possible in Oracle to create a stored procedure that returns an inline table (without declaring a type - like the above)? If not, what would be the closest alternative? i.e. declare inline type, then use it. The idea is to minimize number of DB permissions that are granted.
Please include sample code as part of your answer.
Reasoning behind using stored procedure vs function - we have legacy software that can only execute stored procedures, or raw queries. It appears that only stored procedures in there have support for parameterized execution, which is what we are after.
try this with ref cursor
PROCEDURE proc_get_tada(ip_user IN VARCHAR2,
op_error_code OUT NUMBER,
op_cursor OUT SYS_REFCURSOR,) AS
BEGIN
OPEN op_cursor FOR
SELECT * FROM your_table yt where yt.user = ip_user;
EXCEPTION
WHEN OTHERS THEN
op_error_code := -1;
END proc_get_tada;
you will get collection of all data from you table you can iterate in java or calling program.
Maybe you are searching for something like this:
create table author
(
au_id number,
au_name varchar2(100)
);
insert into author (au_id, au_name) values(1, 'ME');
create or replace function getAuthor(auName varchar2)
return author%rowtype
is
retval author%rowtype;
begin
select * into retval from author where au_name=auName;
return retval;
end;
declare
auth author%rowtype;
begin
auth := getAuthor('ME');
dbms_output.put_line(auth.au_id);
end;

Oracle data masking

We have one requirement to mask a particular table column using a Oracle function which gives persistent masked output string.
We tried Oracle Hash Function but it does not give String type return value.
We tried Oracle Random function (dbms_random.string) but it does not give Persistent output string.
I read on internet that this is called deterministic masking. But we do not want to use Oracle Enterprise Manager; however we require a direct Oracle function.
Please suggest.
This problem is easily solved in 12c with the function STANDARD_HASH.
The solution in previous versions is only slightly more complicated. Build a simple wrapper around DBMS_CRYPTO that acts just like STANDARD_HASH:
--Imitation of the 12c function with the same name.
--Remember to drop this function when you upgrade!
create or replace function standard_hash(
p_string varchar2,
p_method varchar2 default 'SHA1'
) return varchar2 is
v_method number;
v_invalid_identifier exception;
pragma exception_init(v_invalid_identifier, -904);
begin
--Intentionally case-sensitive, just like the 12c version.
if p_method = 'SHA1' then
v_method := dbms_crypto.hash_sh1;
--These algorithms are only available in 12c and above.
$IF NOT DBMS_DB_VERSION.VER_LE_11 $THEN
elsif p_method = 'SHA256' then
v_method := dbms_crypto.hash_sh256;
elsif p_method = 'SHA384' then
v_method := dbms_crypto.hash_sh384;
elsif p_method = 'SHA512' then
v_method := dbms_crypto.hash_sh512;
$END
elsif p_method = 'MD5' then
v_method := dbms_crypto.hash_md5;
else
raise v_invalid_identifier;
end if;
return rawToHex(dbms_crypto.hash(utl_raw.cast_to_raw(p_string), v_method));
end;
/
You may need to logon with SYS and grant your user access to DBMS_CRYPTO to make the function work:
grant execute on sys.dbms_crypto to <your_schema>;
Create a public synonym, grant it to everyone, and it works exactly the same way.
create public synonym standard_hash for <schema with function>.standard_hash;
grant execute on standard_hash to public;
select standard_hash('Some text', 'MD5') from dual;
9DB5682A4D778CA2CB79580BDB67083F
select standard_hash('Some text', 'md5') from dual;
ORA-00904: : invalid identifier
Here is a simple example of using the function:
update some_table
set column1 = standard_hash(column1),
column2 = standard_hash(column2);
But updating large amounts of data can be slow. It may be faster to create a new table, drop the old one, rename the new one, etc. And the hash value may be larger than the column size, it may be necessary to alter table some_table modify column1 varchar2(40 byte);
It amazes me how many products and tools there are to do such a simple thing.
If you looking something like mask the production data to move it into non-prod for integration testing. Below the "user defined" function would be helpful to you. This function will work only 10G and above.
create or replace function scrubbing(word in varchar2)
return varchar2
as
each_var char(2);
final_val varchar2(100);
complete_data varchar2(4000);
each_word varchar2(1000);
cursor val is select substr(replace(word,' ','#'),-level,1) from dual connect by level<=length(word);
begin
open val;
--final_val:= '';
loop
fetch val into each_var;
exit when val%NOTFOUND;
--dbms_output.put_line(each_var);
final_val := trim(final_val)||trim(each_var);
--dbms_output.put_line(final_val);
select regexp_substr(final_val,'[A-Za-z]+') into each_word from dual;
select replace(translate(final_val,each_word,dbms_random.string('L',length(word))),'#',' ') into complete_data from dual;
end loop;
return complete_data;
end;
In Oracle 12C dbms_redact.add_policy is available. It can be used to get the masked value in the select query itself.
You can use dbms_crpyto package of oracle , first you need to convert varchar2 type to raw then mask the data according to the hash value.

Converting Oracle stored procedure to MSSQL

I'm trying to convert some Oracle stored procedures to MSSQL I did some basic SP's but I'm having a trouble converting SP's with cursors.
here's a example :-
create or replace procedure PR_DELETE_FOLDER(indexedFolder NUMBER,indexedPath VARCHAR2,userCode VARCHAR2,folpath VARCHAR2,idpath VARCHAR2,folderid NUMBER) as
cursor c1(pfolid in NUMBER) is
SELECT folder.PARENTFOLDER, folder.FOLDERNAME, folder.FOLDERID ,sys_connect_by_path(folder.FOLDERNAME,'>>') FOLDERPATH , sys_connect_by_path(folder.FOLDERID,'>>') FOLDERIDPATH
FROM T_FOLDER folder
START WITH folder.PARENTFOLDER =pfolid
CONNECT BY PRIOR folder.FOLDERID=folder.PARENTFOLDER;
cursor c2(folid in NUMBER) is SELECT DOCUMENTID,DOCUMENTNAME from T_DOCUMENT where folder = folid;
begin
for r1 in c1(folderid) loop
update T_FOLDER set last_update=sysdate,STATUS=0 where folderid=r1.FOLDERID;
update T_FOLDER set foldercount = foldercount-1 where folderid = r1.PARENTFOLDER;
-- insert into T_FOLDER_AUDIT values(SEQ_FOLDER_AUDIT.nextval,r1.FOLDERID,'Delete a folder',userCode,sysdate,sysdate,userCode,userCode,1);
insert into t_historical_event values(SEQ_HISTORICAL_EVENT.nextval,r1.FOLDERID,null,'com.affno.adms.folder.Folder',null,'Updated',userCode,r1.FOLDERNAME,sysdate,sysdate,sysdate,userCode,userCode,1);
for r2 in c2(r1.FOLDERID) loop
update T_DOCUMENT set LAST_UPDATE = sysdate,ISUPDATEINDEXES=1,MODIFIEDBY=userCode,STATUS=0 where documentid = r2.DOCUMENTID;
update T_FOLDER set doccount=doccount-1 where folderid=r1.FOLDERID;
insert into T_DOCUMENT_AUDIT values(SEQ_DOC_AUDIT.nextval,'delete',r2.DOCUMENTID,'Original',sysdate,sysdate,userCode,userCode,1,userCode);
insert into t_historical_event values(SEQ_HISTORICAL_EVENT.nextval,r2.DOCUMENTID,null,'com.affno.adms.document.Document',null,'Deleted',userCode,r2.DOCUMENTNAME,sysdate,sysdate,sysdate,userCode,userCode,1);
end loop;
end LOOP;
end;
I'm not familiar with MSSQL cursors so I got no clue on this issue.
Thanks.
There are examples in the msdn article:
DECLARE CURSOR (Transact-SQL)
USE AdventureWorks2008R2;
GO
DECLARE vend_cursor CURSOR
FOR SELECT BusinessEntityID, Name, CreditRating FROM Purchasing.Vendor
OPEN vend_cursor
FETCH NEXT FROM vend_cursor;
You could try a made for this purpose conversion application such as http://www.convert-in.com/ora2mss.htm --> Unfortunately, at $49 it ain't cheap.

Resources