Re: How do I store files in 8.x?
Date: Sat, 10 Mar 2001 16:34:20 GMT
Message-ID: <gIsq6.584$7d.66960_at_newshog.newsread.com>
You asked how so...see below. Everything works as shown for binary files (I used an Excel spreadsheet), but you will need some Java pieces to present the final results to your users. Don't have a sample of that for you, but may be available in books or on the Oracle tech site. Or if any other posters are willing to append one, I'd love to see it. Or to correct or improve anything below.
Van
Oracle can store different types of large objects (LOBs). For our purposes we will be storing binary files as BLOBs. If the information were strictly character data, we could store it as a CLOB. Within Oracle, BLOBs are put in a separate tablespace and not stored with the rest of the columns in a table. The table has only an internal locator value for the BLOB data. That way the database does not have to scan the BLOB data each time it reads multiple rows from the database table.
When your database designer creates a table with a LOB he needs an additional storage clause to tell Oracle where to put the LOB: storage(initial....) used for all tables, LOB or not tablespace LDGLOBALINFO used for all tables, LOB or not lob (BLOB_COLUMN_NAME) store as used for LOBs only ( tablespace LDGLOBALINFO_LOBS used for LOBs only
storage (initial 256K next 256K pctincrease 0) used for LOBs only chunk 16K pctversion 10 nocache logging ); used for LOBs only
For now we will not index our LOBs, but you can and you can use a separate LOB index tablespace if you wish.
In general LOBs are manipulated using the Oracle-supplied package DBMS_LOB. This package is similar in concept to other supplied packages we already use - DBMS_SQL, DBMS_JOB, etc. It is more difficult to select and manipulate LOBs than it is for VARCHAR2s.
When a developer inserts a row into a table, if there is no value for the
BLOB the insert looks like this:
INSERT INTO X ( KEY, BLOB_COL ) values ( 1, EMPTY_BLOB() )
Note the use of EMPTY_BLOB() to represent an empty locator value rather than
NULL. It is very important to use this syntax to prevent extra work later.
So we need to be able to take documents from a file system location(1), put them into Oracle(2), retrieve them from Oracle(3), and put them out to a file system or some other place where a user can access and use the documents(4).
(1) On the ntradevl UNIX server we set up a new directory:
ldcwlt40/oracle/oradata/tblspc/documents
and in the documents folder we placed an Excel spreadsheet, TSpaces.xls
(2) We needed to take several steps before putting a document into Oracle.
First we granted ntradevl and ldcfusion the CREATE ANY DIRECTORY privilege.
Then we modified the init.ora parameter UTL_FILE_DIR =
/oracle/oradata/tblspc/documents. In step (4) below this will prevent us
from accidentally writing something to an inappropriate location, such as
directly on top of our control files!
Next we create a BFILE locator which is a directory path and a filename.
We will use an easy-to-write alias for the directory path which, after
logging in as LDGLOBALINFO, we create like this:
CREATE DIRECTORY DOCS AS '/oracle/oradata/tblspc/documents';
We'll grant read permission on this directory to ldcfusion:
GRANT READ ON DIRECTORY DOCS to ldcfusion;
Oracle has a built-in function called BFILENAME. We can use this function
to create a locator for the external file. This locator is called a BFILE
locator and we might use it in a little anonymous block like this:
DECLARE
tspacexls BFILE;
BEGIN
tspacexls := BFILENAME('DOCS', 'TSpaces.xls');
END;
/
PL/SQL procedure successfully completed.
Well, so far so good. Now we'd like to grab a document and insert it into
an Oracle table. While you were reading, I went and created a table called
LG_DOCUMENT_ITEM_DETAIL2 using this SQL:
Create Table LDGLOBALINFO.LG_DOCUMENT_ITEM_DETAIL2 (
DOC_ITEM_KEY NUMBER(8) NOT NULL, DOC_ITEM_NAME VARCHAR2(100) NULL, DOC_ITEM_PROGRAM NUMBER(8) NULL, DOC_ITEM_EXTENSION VARCHAR2(10) NULL, DOC_ITEM_SERVER VARCHAR2(40) NULL, DOC_ITEM_PATH VARCHAR2(100) NULL, DOC_ITEM_TYPE VARCHAR2(40) NULL, DOC_ITEM_ACTUAL_DATA BLOB NULL, DOC_ITEM_POSTED_DATE DATE NULL, DOC_ITEM_LAST_MOD_DATE DATE NULL, DOC_ITEM_COMMENT VARCHAR2(200) NULL,constraint DOC_ITEM2_PK primary key (DOC_ITEM_KEY) using index tablespace LDGLOBALINFO_INDX storage (initial 32K next 32K pctincrease 0 minextents 1 maxextents 249) )
tablespace LDGLOBALINFO
storage (initial 32K next 32K pctincrease 0 minextents 1 maxextents 249) LOB (DOC_ITEM_ACTUAL_DATA) store as
( tablespace LOBSPC
storage (initial 1M next 1M pctincrease 0 minextents 1 maxextents 512) chunk 16K pctversion 20 nocache logging );
Let's grab our Excel spreadsheet and insert it into the DOC_ITEM_ACTUAL_DATA. To show this I'll use another anonymous block using some of the procedures in the Oracle-supplied DBMS_LOB package: DECLARE
source_locator BFILE;
destination_locator BLOB;
file_size INTEGER;
ignore INTEGER;
BEGIN
source_locator := BFILENAME('DOCS', 'TSpaces.xls'); file_size := DBMS_LOB.GETLENGTH(source_locator); --
DBMS_OUTPUT.PUT_LINE('Open the External File');
-- -- you must open the file before you can work with it. --
ignore := DBMS_LOB.FILEISOPEN(source_locator); IF (ignore=1) THEN
NULL;
ELSE
DBMS_LOB.FILEOPEN(source_locator, DBMS_LOB.file_readonly); END IF;
--
DBMS_OUTPUT.PUT_LINE('Spreadsheet Size: '||file_size); DBMS_OUTPUT.PUT_LINE('Inserting Empty Spreadsheet Row'); --
INSERT INTO LDGLOBALINFO.LG_DOCUMENT_ITEM_DETAIL2 (
DOC_ITEM_KEY, DOC_ITEM_NAME, DOC_ITEM_PROGRAM, DOC_ITEM_EXTENSION, DOC_ITEM_SERVER, DOC_ITEM_PATH, DOC_ITEM_TYPE, DOC_ITEM_ACTUAL_DATA, DOC_ITEM_POSTED_DATE, DOC_ITEM_LAST_MOD_DATE, DOC_ITEM_COMMENT ) VALUES ( 696, 'Test Excel Spreadsheet', 1, '.xls', 'ldcwlt40', 'dummy path', '', EMPTY_BLOB, sysdate, sysdate, 'dummy comment')RETURNING DOC_ITEM_ACTUAL_DATA INTO destination_locator; --
DBMS_OUTPUT.PUT_LINE('Loading Spreadsheet into Oracle Table'); --
DBMS_LOB.LOADFROMFILE(destination_locator, source_locator, file_size); COMMIT;
-- -- close the file when you are all done --
DBMS_OUTPUT.PUT_LINE('Close the External File'); --
DBMS_LOB.FILECLOSE(source_locator);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('OTHERS Exception ' || sqlerrm); END;
/
Which produces these results:
Open the External File
Spreadsheet Size: 194048
Inserting Empty Spreadsheet Row
Loading Spreadsheet into Oracle Table
Close the External File
PL/SQL procedure successfully completed.
(3) Now let's make sure we can manipulate the data we placed in Oracle by
running a small SQL select:
SELECT
DOC_ITEM_KEY,
DOC_ITEM_NAME,
DBMS_LOB.GETLENGTH(DOC_ITEM_ACTUAL_DATA)
FROM
LDGLOBALINFO.LG_DOCUMENT_ITEM_DETAIL2
WHERE
DOC_ITEM_PROGRAM = 1;
Which gives us
DOC_ITEM_KEY DOC_ITEM_NAME
DBMS_LOB.GETLENGTH(DOC_ITEM_ACTUAL_DATA)
------------ ------------------------- ------------------------------------- --- 696 Test Excel Spreadsheet
194048
(4) The last step is to grab the information from Oracle and make it
accessible to a user as an Excel spreadsheet. We cannot simply select the
BLOB column in SQL*Plus since Oracle does not have this capability. Once
again we'll need a short procedure.
DECLARE
destination_locator BLOB; -- pointer to the BLOB stored
- in the database
lob_buffer RAW(32767); -- where the BLOB will go when retrieved
amount BINARY_INTEGER := 32767; -- how much BLOB to grab with each pass
position INTEGER := 1; -- location of the byte in the BLOB
- where the read begins
chunksize INTEGER;
BEGIN
--
- Select the LOB -- SELECT DOC_ITEM_ACTUAL_DATA INTO destination_locator FROM LDGLOBALINFO.LG_DOCUMENT_ITEM_DETAIL2 WHERE DOC_ITEM_KEY = 696; --
- Find out the chunksize for this LOB column -- chunksize := DBMS_LOB.GETCHUNKSIZE(destination_locator); IF (chunksize < 32767) THEN Amount := (32767 / chunksize) * chunksize; END IF; --
- Read data from the LOB -- DBMS_LOB.READ (destination_locator, amount, position, lob_buffer); --
- You may want to loop through the procedure until you have the whole LOB -- END; /
- where the read begins
chunksize INTEGER;
BEGIN
--
"E. Frijters" <erik_at_e-frijters.tmfweb.nl> wrote in message news:3aa7ead2$0$9741_at_reader2...
> Hello, > > I'm building a client server application with Microsft Visual FoxPro 6.0and
> Oracle 8. > > I want to store report-files in the central Oracle database, so I can > update the reports of the different clients through the database. The only > purpose is to distribute the files, nothing more... > > I want to use BLOB or BFILE, but I don't now how to pass the informationto
> the database. (I use the latest ODBC drivers 8.05.00) > > I use Sequel Pass Through and Remote Views as programming techniques. > > Any help or examples are very appreciated! > > Greetings > > E. Frijters > erik_frijters_at_deltalloyd.nl > or > e.frijters_at_wanadoo.nl > > >Received on Sat Mar 10 2001 - 17:34:20 CET