How to seek a textfile? - pascal

I am using a textfile to store some data so that I can use it later to create reports, but the data I stored is in multiple lines ie.
1
1
2
2
Lets say if I want to read data from number 2, how would I be able assign a variable to the third and fourth line without the 1's (the numbers will not be the same in the actual data). Seek() will not work since it is a textfile and I won't be able to use writeln() if I changed the type. Is there anyway I can do this without using records?
Edit: There will be exactly 96 lines and all lines may not have the same number of digits.

Since the input file is small you could use TStringList to process it. Here's an example.
First few records of a sample text file called adrian.txt containing random numbers.
15
37
46
29
33
37
37
50
41
48
3
9
31
50
Lazarus code: The TStringList object s uses its LoadFromFile method to load the contents of the text file into itself. Now the contents of the individual records are available, indexed by their numbers. Only note that these numbers are zero-relative; ie, the first record become the 0th string in TStringList.
procedure TForm1.Button1Click(Sender: TObject);
var
s: TStringList;
begin
s := TStringList.Create;
s.LoadFromFile('adrian.txt');
Memo1.Lines.Add(s[0]);
Memo1.Lines.Add(s[1]);
Memo1.Lines.Add(s[2])
end;
Press the button and this is what you see.

Related

PL/SQL UTL_FILE package read from csv and load values into a table

If I have a CSV file like this:
How can I read this with UTL_FILE package and load the values into one table which have columns: ItemIdentifier, SoldOnWeb, SoldInTheShop?
From my point of view, as CSV files can be edited with MS Excel, I'd suggest you to rearrange the file and uniform it. The way it is now, it contains different headings and - to make it worse - they don't "match" (the same column contains itemidentifier and soldintheshop values; the same goes for the next column).
Add yet another column which would explain what the "sold..." column represents. Finally, you'd have something like this:
itemidentifier amount location
-------------- ------ -------------
1 10 soldOnWeb
2 7 soldOnWeb
3 5 soldOnweb
1 7 soldInTheShop
2 3 soldInTheShop
Doing so, it is a simple task to insert every value where it belongs.
Otherwise, can it be done in PL/SQL? Probably. Will it be difficult? Probably, as you have to "remember" what you're selecting in each row and - according to that - insert values into appropriate columns in the table.
You know how it goes ... garbage in, garbage out.

How to convert a number to a three-character string using an Oracle sequence

I need to create an Oracle 12c sequence and convert it from a number to a three-character string that has the format of 001, 002, 003 etc.
Here is an example of a sequence:
CREATE SEQUENCE supplier_seq
MINVALUE 1
MAXVALUE 999
START WITH 1
INCREMENT BY 1
CACHE 1;
Taking the above sequence, I now need to convert it to a three character string as shown above.
It is not possible using the only sequence.
But yes you can use the following function, wherever sequence is used, to convert the values of sequence to the required format.
SELECT LPAD(supplier_seq.nextval,3,0) FROM DUAL; -- 001, 002, 003
Hope, This is what you are looking for.

Oracle Apex: Aggregate show as top row

Currently I use interactive report of Oracle Apex
Column1 Column2
A1 1 2
A2 2 3
A3 3 4
A4 4 5
----------------------
10 14
After showing data, I do some calculation such as sum Column1, Column2 using aggregate function SUM of interactive report
But the result show as the last row of report so I have to scroll to see the result.
How can I show the result as the first row of report?
Column1 Column2
10 14
----------------------
A1 1 2
A2 2 3
A3 3 4
A4 4 5
This can be done using JavaScript/jQuery (of course this is only one of many ways this can be done, but it works).
The SQL statement that is used to create the report along with all the filter and search information is stored in
WWV_FLOW_WORKSHEET tables
Create a database package to generate that SQL and sum the columns that you want from that and return as XML.
Call that database package from a jQuery AJAX call then parse the XML and using jQuery add a row to the top (and bottom if you like) of the worksheet table and place the results there.
The JavaScript/jQuery function should be called from an after refresh dynamic action for the worksheet in question.
function htmldbIRTotals(worksheet,columnList) {
sessionId = $("#pInstance").val();
worksheetId = $(worksheet.triggeringElement).find(".a-IRR-table:last").attr("id");
baseReportId=parseInt("0"+$("#"+worksheetId+"_rpt_saved_reports").val());
u="'||pkg||'.getTotals?p_worksheet_id="+worksheetId+"&p_base_Report_Id="+baseReportId+"&p_session_id="+sessionId+"&p_columns="+columnList;
$.post(u,function(data) {
var xml = $.parseXML(data);
});
With sessionId, worksheetId, and baseReportId you can retrieve all the info you need
columnList is a colon separated list of the columns that you want to total
You could even get more fancy and add different agregates (i.e. AVG, MIN, MAX etc.)
Example of this at the link below.
http://apps.htmldb.com/apps/f?p=htmldb:knowledgebase:::NO:RP:P5_ID:84315
The problem is that the totals may or may not be rendered on the page depending on the page size and the number of records in the result set - so with an Interactive Report, unless you force it to always show All Records, the page might not even be able to use JS tricks to move the summary line to the top.
My preference in this sort of situation is to add a separate region to the page based on a simple SQL query. It will be shown above the interactive report. Unfortunately the columns won't be aligned, however.
I found the solution
Add sub query to calculate the sum
Union with existed result
Use highlight function to make up the new row

PL/SQL code Template

I want to convert a 9 digit number to 10 digit by appending a 0 to it.
For example In Table ABC say there is a column named B which takes a number which is at the max 10 digit long.
Now sometimes I will get a 9 digit number only.
So in that case when a 9 digit number is faced i need to fire a trigger to make it 10 digit and then insert in the table.
For that you need to create the column with character datatype so that it can hold the leading zeros.
You don't need to write any trigger for this simple operation. you can use lpad for this purpose:
eg.g
Insert into table1(number_col) values ( lpad(999999999, 10, '0'));
select * from table1;
| number_col |
|-----------------|
| 0999999999 |
To use this in trigger, create a trigger as follows (Not Tested);
create or replace trigger trg_table1
before insert or update of number_col on table1
for each row
begin
:new.number_col := lpad( :new.number_col, 10, '0' );
end;
You don't really need to make this a trigger. Adding a 0 to the front of the number is really only for humans, the computer doesn't care and that information can't be stored in the database unless you convert the column to a string format.
What you're looking for is one of three things: Either, change the way your forms display the information to add padding if the number is less 10,000,000,000 to affect the way the user sees the information (most recommended)
Or, use the lpad function to convert the number to a string with 0 padding if necessary
lpad(input,10,'0')
Note that this will require conversion back to a number to insert into the DB if it is possible for the user to edit this number. (second most recommended)
Lastly, you can always store the value in a string format and use lpad as above on insert.
I wouldn't recommend this as strings take up much more space than numbers, and the db won't search them as fast. Also, why store a number as a string purely for the user's sake, when you can change the way your data looks to the user programatically?

read first 1kb of a blob from oracle

I wish to extract just the first 1024 bytes of a stored blob and not the whole file. The reason for this is I want to just extract the metadata from a file as quickly as possible without having to select the whole blob.
I understand the following:
select dbms_lob.substr(file_blob, 16,1)
from file_upload
where file_upload_id=504;
which returns it as hex. How may I do this so it returns it in binary data without selecting the whole blob?
Thanks in advance.
DBMS_LOB.SUBSTR will, for a BLOB, return a RAW. Most environments will render that in hex.
You can use the DUMP function to view it in some other formats.
select dump(dbms_lob.substr(product_image,10,1),10),
dump(dbms_lob.substr(product_image,10,1),16),
dump(dbms_lob.substr(product_image,10,1),17)
from APEX_DEMO.DEMO_PRODUCT_INFO
where product_id = 9;
This returns the first 10 bytes of the BLOB in decimal (eg 0-255), hex and character. The latter may throw some unprintable garbage to the screen and, if the client and database character sets do not match, undergo some 'translation'.
You can use UTL_RAW.CAST_TO_VARCHAR2 which may give you what you want.
select utl_raw.cast_to_varchar2(dbms_lob.substr(product_image,10,1)) chr
from APEX_DEMO.DEMO_PRODUCT_INFO
where product_id = 9

Resources