Setting column headings on report export - oracle-apex

I'm using the following blog post to help me export a report. It works great however i wondered is it possible to set column heading names?
http://spendolini.blogspot.co.uk/2006/04/custom-export-to-csv.html

If all you want to do is to provide an initial row with column headers in it:
begin
-- Set the MIME type
owa_util.mime_header( 'application/octet', FALSE );
-- Set the name of the file
htp.p('Content-Disposition: attachment; filename="emp.csv"');
-- Close the HTTP Header
owa_util.http_header_close;
-- Send the initial row with headers
htp.prn('Ename,Empno,Department'||chr(13));
-- Loop through all rows in EMP
for x in (select e.ename, e.empno, d.dname
from emp e, dept d where e.deptno = d.deptno
and e.deptno like :P1_DEPTNO)
loop
-- Print out a portion of a row,
-- separated by commas and ended by a CR
htp.prn(x.ename ||','|| x.empno ||','||
x.dname || chr(13));
end loop;
-- Send an error code so that the
-- rest of the HTML does not render
--htmldb_application.g_unrecoverable_error := true;
--use stop apex_engine
apex_application.stop_apex_engine;
end;
Basically you just emit one extra row before you emit the data rows.
I commented htmldb_application in favor of apex_application.stop_apex_engine. See documentation

Related

PL/SQL Speeding up long function

I am looking to speed up the following PL/SQL function. Right now it has run for over 2 hours with no sign of completing. We aborted that one and attempting it again with a EXIT WHEN of 20 and it still shows no signs of actually completing.
We are running these through SQLDeveloper 17.3, and each of the (4) tables has about 15k rows.
The goal is to grab all of the SSN's in our database and change the first character to an illegal char and the last 2 characters to a random A-Z combination. We then have to update that SSN in every table that uses it (4).
declare
v_random varchar2(2);
v_origin_ssn varchar2(100);
v_working_start varchar2(100);
v_working_middle varchar2(100);
v_new_ssn varchar2(100);
begin
for o in (
select distinct ssn --loop all rows in tbl_customer
from program_one.tbl_customer
)
loop
if regexp_like(o.ssn, '^[A-Za-z9].*[A-Z]$') then continue; --if this is already scrambled, skip
else
select dbms_random.string('U', 2) --create random 2 cap letters
into v_random
from dual;
v_origin_ssn := o.ssn; --set origin ssn with the existing ssn
if regexp_like(o.ssn, '^[A-Za-z]') --if first char is already alpha, leave it alone, otherwise 9
then v_working_start := substr(o.ssn, 1, 1);
else v_working_start := 9;
end if;
v_working_middle := substr(o.ssn, 2, 6); --set middle ssn with the unchanged numbers
v_new_ssn := v_working_start||v_working_middle||v_random; --create new sanitized ssn
update program_one.tbl_customer --update if exists in tbl_customer
set ssn = v_new_ssn
where ssn = v_origin_ssn;
commit;
update program_one.tbl_mhc_backup --update if exists ssn tbl_mhc_backup
set ssn = v_new_ssn
where ssn = v_origin_ssn;
commit;
update program_two.tbl_waiver --update if exists ssn tbl_waiver
set ssn = v_new_ssn
where ssn = v_origin_ssn;
commit;
update program_two.tbl_pers --update if exists in tbl_pers
set ssan = v_new_ssn
where ssan = v_origin_ssn;
commit;
end if;
--dbms_output.put_line(v_origin_ssn||' : '||v_new_ssn); --output test string to verify working correctly
end loop;
end;
I'd do it without a function in plain SQL:
Create a table with old and new ssn:
CREATE TABLE tmp_ssn AS
SELECT ssn, '9'||substr(ssn,2,6)||dbms_random.string('U',2) as new_ssn
FROM (SELECT distinct ssn FROM program_one.tbl_customer);
CREATE UNIQUE INDEX ui_tmp_ssn ON tmp_ssn(ssn, new_ssn);
EXEC DBMS_STATS.GATHER_TABLE_STATS(null,'tmp_ssn');
... and then update the tables one by one:
MERGE INTO program_one.tbl_customer z USING tmp_ssn q ON (z.ssn=q.ssn)
WHEN MATCHED THEN UPDATE z.ssn = q.new_ssn;
COMMIT;
MERGE INTO program_one.tbl_mhc_backup z USING tmp_ssn q ON (z.ssn=q.ssn)
WHEN MATCHED THEN UPDATE z.ssn = q.new_ssn;
COMMIT;
etc
If that is still to slow, I'd do
RENAME tbl_customer to tbl_customer_old;
CREATE TABLE tbl_customer as
SELECT s.new_ssn as ssn, t.col1, t.col2, ... , t.coln
FROM tbl_customer_old t JOIN tmp_ssn s USING(ssn);
DROP TABLE tbl_customer_old;

How to read in table that depends on two sets previously defined

I am optimizing the choice of letters with the surfaces they require in the laser cutter to maximize the total frequency of words that they can form. I wrote this program for GLPK:
set unicodes;
param surfaces{u in unicodes};
table data IN "CSV" "surfaces.csv": unicodes <- [u], surfaces~s;
set words;
param frequency{w in words}, integer;
table data IN "CSV" "words.csv": words <- [word], frequency~frequency;
Then I want to give a table giving each word the count of each character with its unicode. The sets words and unicodes are already defined. According to page 42 of the manual, I can omit the set and the delimiter:
table name alias IN driver arg . . . arg : set <- [fld, ..., fld], par~fld, ..., par~fld;
...
set is the name of an optional simple set called control set. It can be omitted along with the
delimiter <-;
So I write this:
param spectrum{w in words, u in unicodes} >= 0;
table data IN "CSV" "spectrum.csv": words~word, unicodes~unicode, spectrum~spectrum;
I get the error:
Reading model section from lp...
lp:19: delimiter <- missing where expected
Context: ..., u in unicodes } >= 0 ; table data IN '...' '...' : words ~
If I write:
table data IN "CSV" "spectrum.csv": [words, unicodes] <- [word, unicode], spectrum~spectrum;
I get the error:
Reading model section from lp...
lp:19: syntax error in table statement
Context: ...} >= 0 ; table data IN '...' '...' : [ words , unicodes ] <-
How can I read in a table with data on two sets already defined?
Notes: the CSV files are similar to this:
surfaces.csv:
u,s
41,1
42,1.5
43,1.2
words.csv:
word,frequency
abc,10
spectrum.csv:
word,unicode,spectrum
abc,1,41
abc,2,42
abc,3,43
I found the answer with AMPL, A Mathematical Programming Language, which is a superset of GNU MathProg. I needed to define a set with the links between words and unicodes, and use that set as the control set when reading the table:
set links within {words, unicodes};
param spectrum{links} >= 0;
table data IN "CSV" "spectrum.csv": links <- [word, unicode], spectrum~spectrum;
And now I get:
...
INTEGER OPTIMAL SOLUTION FOUND
Time used: 0.0 secs
Memory used: 0.1 Mb (156430 bytes)
The "optional set" in the documentation is still misleading and I filed a bug report. For reference, the AMPL book is free to download and I used the transportation model scattered in page 47 in Section 3.2, page 173 in section 10.1, and page 179 in section 10.2.

Python - webscraping; dictionary data structure

I need to scrape this website (http://setkab.go.id/profil-kabinet/#) and produce an Excel file that has headers "Cabinet names" in column 1 and "Era" in column 2. That means each Cabinet name (e.g. Kabinet Presidensil, Kabinet Sjahrir I) should have its own row - alongside its respective era (e.g. Era Revolusi Fisik, Era Republik Indonesia Serikat).
This is the closest I've gotten:
import requests
from bs4 import BeautifulSoup
response = requests.get('http://setkab.go.id/profil-kabinet/#')
soup = BeautifulSoup(response.text, 'html.parser')
eras = soup.find_all('div', attrs={'class':"wpb_accordion_section group"})
setkab = {}
for element in eras:
setkab[element.a.get_text()] = {}
for element in eras:
cabname = element.find('div',attrs={'class':'wpb_wrapper'}).get_text()
setkab[element.a.get_text()]['cbnm'] = cabname
for item in setkab.keys():
print item + setkab[item]['cbnm']
import os, csv
os.chdir("/Users/mxcodes/Code")
with open("setkabfinal.csv", "w") as toWrite:
writer = csv.writer(toWrite, delimiter=",")
writer.writerow(["Era", "Cabinet name"])
for a in setkab.keys():
writer.writerow([a.encode("utf-8"), setkab[a]["cbnm"]])
However, this creates an Excel file with the headers "Era" and "Cabinet names" in column 1 and 2, respectively. It fails to put each Cabinet name in a separate row. For example, it has 'Era Revolusi Fisik' in column 1 and lists all the cabinets together in column 2.
My guess is that I need to switch the key-value pairs somehow so that each Cabinet becomes a key and its era becomes its value - because currently it's the other way around. But I've tried and failed to do so. Any help? Thank you!
From what I can see, the cabinets[a]["cbnm"] variable you use for writing is just a long Unicode so when you do writer.writerow([a.encode("utf-8"), cabinets[a]["cbnm"]]) what actually happens is that you write the era at the first column and the whole Unicode in the single cell in the next column (even if you have \n in your string it does not prevent it from being writed in a single cell (csv actually think that you want the unicode to be in ONLY one cell so it puts " before and after the cabinets[a]["cbnm"] value to be sure it will actually be in one cell)), what you should do to write every cabinet value in another row is to use the writerow method separately for each desired row.
for example this code worked fine for me:
cabinets = setkab
with open("cabinets.csv", "w") as toWrite:
writer = csv.writer(toWrite, delimiter=",")
writer.writerow(["Era", "Cabinet name"])
for a in setkab.keys():
writer.writerow([a.encode("utf-8")]) #write the era column
cabinets_list = [i for i in cabinets[a]["cbnm"].split('\n') if i != ''] #get all the values that are separated by newline chars (if they aren't empty strings)
for i in cabinets_list: writer.writerow([a.encode("utf-8"),i]) #write every value separately in the CABINET NAME row
as you can see I changed only the last 3 lines.
I hope this will help you!

source file fixed width , need only Header and Footer to the target(oracle)

I have this scenario with source as fix width flat file, and I need to read to target only the Header and Footer not the details records.
I need to trim the first column (PA22109 ) and get only PA and next 2 columns to rows as two different dates.
For Footer get only the PT(PT000000000700000030620E00000055612I00000010277I) and the rest into a column of the target.
How can I achieve this logic, inputs are appreciated.
source file :
PA22109 00153252015110905408179 2015110820151108PO ---header
DE0E9D TESTGROUPEXCH TESTINSEXCH TESTLOCEXCH ID014 LNAME014 FNAME014 14 MAIN ST ANYWHERE NJ011110000 195001012Z 01000000014 LNAME014 PATFIRST014 14 MAIN ST ANYWHERE NJ011110000 1955010110106000220 TESTGROUPEXCH 8179 TESTBENEXCH TESTCNTE53 0000000000 0000002643005 011234567890 011234567890 1234 TEST PHARMACY TEST PHARMACY LANE PHARMACYTOWN NJ09876 5555555555 11Y5 019876543210 019876543210 NJPRESCLAST PRESCFIRST 5555555551 DRLAST DRFIRST 110110000009770990300406048410 2015092720150927154401000000000000120150929 0000100000000000000000000000000
PT000000000700000030620E00000055612I00000010277I --Footer
As this a fixed file you can perform following to meet your requirement.
In your Informatica mapping, Read row in a single column.
In Expression, Mark each record for filter out if It does not start with PA OR PT (Assumption your Detail records do not start with PA or PT). Filter detail record out using Filter transformation.
Now you have only Header and Footer Records.
Now you can apply respective condition in expression for PA and PT Records.

How can I import and use labels from one Stata file to the current?

I have file aa with a variable x which is labeled with value label x_lab. I would like to use this value label on the variable x of Stata file bb:
use bb, clear
label value x x_lab
How can I import the value label x_lab?
You can use label save, which saves value labels in a do-file:
label save x_lab using label.do
use bb, clear
do label.do
See Stata help for label.
This answer technique didn't work for me as I wanted the variable labels created with e.g. label var connected "connected household", not the value labels.
Instead I used this advice: http://statalist.1588530.n2.nabble.com/st-How-to-export-variables-window-td3937733.html
*************
sysuse auto, clear
log using mylog, name(newlog) replace
foreach var of varlist _all{
di _col(3) "`var'" _col(20) "`:var label `var''"
}
log close newlog
//translate from proprietary format
translate mylog.smcl mylog.txt, replace
!start mylog.txt
*************
To fix the labels that extended over multiple lines so they just used a single one, I then replaced the \n > for the oversized labels with nothing (in regex mode in atom). I could easily save into TSV from there.
Specifically:
Clean up header and footer text in the logfile output.
On Mac: use "\n" instead of "\r\n".
On Windows: first "\r\n -> ""
then whitespace at beginning "\r\n " --> "\r\n"
then convert whitespace with 3 or more spaces in middle to tabs " +" --> "\t"
(Edit manually additional errors on tab if there are still some left)
save as mylog.tsv
open in Excel, and use table of labels as needed.