Vous êtes sur la page 1sur 14

Now, let us follow the sample code: declare f utl_file.file_type; s varchar2(200); begin f := utl_file.fopen('SAMPLEDATA','sample1.txt','R'); loop utl_file.get_line(f,s); dbms_output.

put_line(s); end loop; exception when NO_DATA_FOUND then utl_file.fclose(f); end; Since I explained much of the above program in my previous article, I dont want to go through every line. The most important issue from the above program is that I used utl_file.get_line in an infinite loop (a loop that would never finish). When does the loop terminate? It all depends on the exception. When the PL/SQL run-time successfully reads a line from the text file, it simply places that information into the variable s (which gets displayed directly onto the screen). When it is unable to read any more lines from the text file, it simply raises an exception (NO_DATA_FOUND), which gets handled in the exception section. Once an exception gets raised, the control will automatically terminate the loop abnormally.

This is the second article in a series focusing on file input/output using Oracle PL/SQL packages.
Writing to Text Files in Oracle PL/SQL - How to count the number of lines from the text file (Page 2 of 6 ) In the previous section, you learned how to display all the lines available in a text file. Now, let us see how to count the number of lines in a text file. I modified the program in the previous section to meet the new requirement. The program is as follows: declare f utl_file.file_type; s varchar2(200); c number := 0; begin f := utl_file.fopen('SAMPLEDATA','sample1.txt','R'); loop utl_file.get_line(f,s); dbms_output.put_line(s); c := c + 1; end loop; exception when NO_DATA_FOUND then utl_file.fclose(f); dbms_output.put_line('Number of lines: ' || c); end; According to the above program, I am defining a simple variable to maintain the count. That variable always gets incremented within the loop, thus maintaining the number of lines read!

You can also observe that I am handling the last part of my program only in the exception area. The exception part gets executed only when no lines are available to read. In my upcoming articles, I shall explain how to deal with these types of scenarios very professionally. Till then, I shall continue in this fashion.

This is the second article in a series focusing on file input/output using Oracle PL/SQL packages.
Writing to Text Files in Oracle PL/SQL - How to copy the information from a text file into a table using PL/SQL (Page 3 of 6 ) In the previous section, we simply counted the number of lines available in a text file. Now, let us further extend the same program by transferring the information available in the text file into an Oracle database using PL/SQL. Before going to the PL/SQL program, we need to create a simple table named sampletable as follows: create table SampleTable ( remarks varchar2(200) ) You can understand that I created a table SampleTable with only one column, remarks (max. up to 200 chars). Now, we need to insert rows into that table using PL/SQL. The PL/SQL code to achieve the desired is the following: declare f utl_file.file_type; s varchar2(200); c number := 0; begin f := utl_file.fopen('SAMPLEDATA','sample1.txt','R'); loop utl_file.get_line(f,s); insert into sampletable values (s); c := c + 1; end loop; exception when NO_DATA_FOUND then utl_file.fclose(f); dbms_output.put_line('No. of rows inserted : ' || c); end; The only extra statement I used from the above statement is the INSERT statement. You may also use the statement COMMIT either at the INSERT statement or after you close the file handle (in the exception section). I just left it without committing. But it is recommended that you commit once you finish the work. Writing to Text Files in Oracle PL/SQL - How to write into a text file from PL/SQL (Page 4 of 6 ) Until now, we have read text files using PL/SQL and copied that information into Oracle tables. Now, we shall take a look at writing to text files using PL/SQL. Let us first go through the following program. declare f utl_file.file_type;

s varchar2(200) := 'this is some info'; begin f := utl_file.fopen('SAMPLEDATA','sample2.txt','W'); utl_file.put_line(f,s); utl_file.fclose(f); end; You can observe that there is not much difference apart from the following line: utl_file.put_line(f,s); Instead of using get_line, I am now using put_line. You should also observe that I placed some string within the variable s. As we are writing to the text file, we cannot use R anymore. Instead we need to replace it with W (which stands for Write mode). If no file exists in the host operating system, PL/SQL runtime automatically creates the text file (with the same file name we specify) for us and starts writing into that. If the same file already exists in the operating system, then it erases the entire contents of that file and makes it a new one. Therefore, you should be a bit careful when using this. There exists one more mode, A. This generally stands for the Append mode. It is very similar to the W mode except that it would never remove existing information from the text file. In some cases, this is the best way to write (or add) information to the text file.

Import text file to SQL Server in Delphi

Hi I need to write a feature in my app that allows the user to import data from a text/csv file into an MS SQL database. I want to allow the user to choose the different parameters like file location, file type, data seperation type and which fields they want to import the data to. e.g I have a Contact Table with - id, firstname, surname, mob_number, addr1, addr2 etc. but they might only want to import data into the 2 name fields. I have been told to look at using DTS, is this the right way to go about it??? if so, how do i create / run @ the DTS @ runtime from within the delphi app?? Can i map the fields from within a DTS?? Any help or advice would be grateful. p.s. im using delphi 5

Thanks

Importing text files Author Nigel Rivett


This process will import text files that arrive in a directory into a table.

It will process every file in the directory with the correct filemask and move the file to an archive directory on completion. It can be used in conjunction with an ftpget SP to import files from a ftp server (see ftp). /* Create the directories c:\Transfer\Archive\ Create these text files in c:\transfer\ bcp1.txt aaammm0120030101 bbbnnn0220030102 cccooo0320030103 bcp2.txt abcxyz5320030104 defhhh1020030105 cdezzz1120030106 fsajku9920030107 Create the table create table BCPData ( fld1 varchar(20) , fld2 varchar(20) , fld3 int , fld4 datetime ) Now run the import exec ImportFiles 'c:\Transfer\' , 'c:\Transfer\Archive\' , 'bcp*.txt', 'MergeBCPData' You can now move the files back from the archive directory to the transfer directory and import again. If this SP call is scheduled then it will import and archive any files that arrive in the transfer directory with the corect file mask. Enhancements The import should be logged to a table in ImportFiles The filename should have the datetime appended to it when archived if you wish to be able to import files with the same name The MergeData SP should log the number of records imported */ if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ImportFiles]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) drop procedure [dbo].[ImportFiles] GO create procedure ImportFiles @FilePath varchar(1000) = 'c:\Transfer\' , @ArchivePath varchar(1000) = 'c:\Transfer\Archive\' , @FileNameMask varchar(1000) = 'bcp*.txt' , @MergeProc varchar(128) = 'MergeBCPData' AS

set nocount on declare @ImportDate datetime select @ImportDate = getdate() declare @FileName @File declare @cmd varchar(2000) create table ##Import (s varchar(8000)) create table #Dir (s varchar(8000)) /*****************************************************************/ -- Import file /*****************************************************************/ select @cmd = 'dir /B ' + @FilePath + @FileNameMask delete #Dir insert #Dir exec master..xp_cmdshell @cmd delete #Dir where s is null or s like '%not found%' while exists (select * from #Dir) begin select @FileName = min(s) from #Dir select @File = @FilePath + @FileName select select select select select select ''')' truncate table ##Import -- import the data exec (@cmd) -- remove filename just imported delete #Dir where s = @FileName exec @MergeProc -- Archive the file select @cmd = 'move ' + @FilePath + @FileName + ' ' + @ArchivePath + @FileName exec master..xp_cmdshell @cmd end drop table ##Import drop table #Dir go @cmd @cmd @cmd @cmd @cmd @cmd = = = = = = @cmd @cmd @cmd @cmd @cmd + + + + + 'bulk insert' ' ##Import' ' from' ' ''' + replace(@File,'"','') + '''' ' with (FIELDTERMINATOR=''|''' ',ROWTERMINATOR = ''' + char(10) + varchar(1000) , varchar(1000)

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[MergeBCPData]') and OBJECTPROPERTY(id, N'IsProcedure') = 1) drop procedure [dbo].[MergeBCPData] GO create procedure MergeBCPData AS set nocount on -- insert data to production table insert BCPData ( fld1 , fld2 , fld3 , fld4 ) select fld1 = substring(s,1,3) , fld2 = substring(s,4,3) , fld3 = convert(int,substring(s,7,2)) , fld4 = convert(datetime,substring(s,9,8)) from ##Import go

Author PaTRiCKDRD
Yak Posting Veteran Greece 55 Posts

Topic

Page:

of 2

Posted - 05/27/2004 : 11:36:04

Oracle has a text_io package, by which you can read and write text files. What about SQL Server guys?

Edited by - PaTRiCKDRD on 05/27/2004 11:36:54

Page47
Flowing Fount of Yak Knowledge USA 2878 Posts

Posted - 05/27/2004 : 12:46:21

No one is responding because all of us are busy exporting our data to text files and installing Oracle so we can read the files .... (Use the language of your choice to write an extendend stored procedure, or better yet, store and access your data in the database management system, not the file system.)

Jay White {0} PaTRiCKDRD


Yak Posting Veteran Greece 55 Posts Posted - 05/28/2004 : 03:35:10

My language is Visual Basic 6, but how can I write an 'extendend stored procedure' in Visual Basic and use it with SQL Server?

PaTRiCKDRD
Yak Posting Veteran Greece 55 Posts

Posted - 05/28/2004 : 04:09:56

You are right though! Oracle is the best! No comparison at all!

srinivasanr
Starting Member 15 Posts

Posted - 05/28/2004 : 05:03:50

Pat, why do you manipulate text files from SQL Server... I would recomment any programming language.. SQL is great..
Posted - 05/28/2004 : 05:15:22

PaTRiCKDRD
Yak Posting Veteran Greece 55 Posts

I do use a programming language of course to do it, but I was wondering if it is possible to be done by SQL Server...

Page47
Flowing Fount of Yak Knowledge USA 2878 Posts

Posted - 05/28/2004 : 07:45:43 quote: Originally posted by PaTRiCKDRD My language is Visual Basic 6, but how can I write an 'extendend stored procedure' in Visual Basic and use it with SQL Server?

sp_addextendedproc Jay White {0} derrickleggett


Posted - 05/28/2004 : 08:45:52

Pointy Haired Yak DBA

You are right though! Oracle is the best! No comparison at all!


USA 4184 Posts

??? Oracle is better in some instances possibly. SQL Server is a better and much more cost effective option for many companies though. With the introduction of SQL Server 2000 and the upcoming Yukon, you will continue to see MS steal a greater share of the market. Oracle has good scalability. It's a nightmare to manage in a 24/7 environment though and any Oracle DBA will verify that. MeanOldDBA derrickleggett@hotmail.com When life gives you a lemon, fire the DBA.

PaTRiCKDRD
Yak Posting Veteran Greece 55 Posts

Posted - 05/28/2004 : 09:46:01

Page47 could you give me a simple example with sp_addextendedproc? and derrickleggett what do you mean by 24/7 environment? 24 hours per day and 7 days a week? (I guess)

derrickleggett
Pointy Haired Yak DBA

Posted - 05/28/2004 : 10:45:10

No. 24 clusters and 7 node groups.


USA 4184 Posts

MeanOldDBA derrickleggett@hotmail.com When life gives you a lemon, fire the DBA.

Page47
Flowing Fount of Yak Knowledge USA 2878 Posts

Posted - 05/28/2004 : 12:04:49

I'm not going to re-type what is available already in Books Online ... Jay White {0}
Posted - 06/04/2004 : 17:03:51

gaskaj
Starting Member 1 Posts

Forget the extended stored procedure, use a COM object from within SQL. This stored proc works, enjoy. Email me if you have any questions. -Joe

CREATE PROCEDURE dbo.uspWriteToFile @FilePath as VARCHAR(255), @DataToWrite as TEXT -- @DataToWrite as VARCHAR(8000) AS SET NOCOUNT ON DECLARE @RetCode int , @FileSystem int , @FileHandle int EXECUTE @RetCode = sp_OACreate 'Scripting.FileSystemObject' , @FileSystem OUTPUT IF (@@ERROR|@RetCode > 0 Or @FileSystem < 0) RAISERROR ('could not create FileSystemObject',16,1) EXECUTE @RetCode = sp_OAMethod @FileSystem , 'OpenTextFile' , @FileHandle OUTPUT , @FilePath, 2, 1 IF (@@ERROR|@RetCode > 0 Or @FileHandle < 0) RAISERROR ('Could not open File.',16,1) EXECUTE @RetCode = sp_OAMethod @FileHandle , 'Write' , NULL , @DataToWrite IF (@@ERROR|@RetCode > 0) RAISERROR ('Could not write to file ',16,1) EXECUTE @RetCode = sp_OAMethod @FileHandle , 'Close' , NULL IF (@@ERROR|@RetCode > 0) RAISERROR ('Could not close file',16,1) EXEC sp_OADestroy @FileSystem RETURN( @FileHandle ) ErrorHandler: EXEC sp_OADestroy @FileSystem RAISERROR ('could not create FileSystemObject',16,1) RETURN(-1) GO

Magelis
Starting Member 1 Posts

Posted - 04/21/2005 : 03:04:22

this is very COOL gaskaj. Since this can be done using extended stored procedures via Visual C++ or delphi, i haven't thought to use COM objects as you have meant. Can you send me any links that i can learn more on this topic? Thanks in advice... Btw; oracle, sybase, db2 or MS SQL....etc. All of these RDBMSes are greater than each other depending on the environment they are used. Admin question: Why should companies use oracle or sybase, if their daily transaction number is not more than 50000? Answer: To give more pain to DBA and to love loosin $...

PaTRiCKDRD
Yak Posting Veteran

Posted - 04/21/2005 : 03:17:18

What about reading a file?


Greece 55 Posts

like this? EXECUTE @RetCode = sp_OAMethod @FileHandle , 'Read' , NULL , @DataToRead

jen
Flowing Fount of Yak Knowledge Sweden 4084 Posts

Posted - 04/21/2005 : 03:43:08 quote: Originally posted by derrickleggett No. 24 clusters and 7 node groups. MeanOldDBA derrickleggett@hotmail.com When life gives you a lemon, fire the DBA.

ROTFLOL this is indeed a nightmare to manage (i'd like to know how'd they set it up) -------------------keeping it simple... Beachsandintoes
Starting Member quote: 15 Posts Originally posted by derrickleggett You are right though! Oracle is the best! No comparison at all! ??? Oracle is better in some instances possibly. SQL Server is a better and much more cost effective option for many companies though. With the introduction of SQL Server 2000 and the upcoming Yukon, you will continue to see MS steal a greater share of the market. Oracle has good scalability. It's a nightmare to manage in a 24/7 environment though and any Oracle DBA will verify that. When life gives you a lemon, fire the DBA. Posted - 05/09/2005 : 16:43:47

Tell me, is ignorance as blissful as I hear? I'm asking you because you clearly do not know what you are talking about. Since I'm a member of

the 'any Oracle DBA' that you cite, I am obligated to help educate you in something called reality. In the company that I work for, I am a part of a small DBA team that manages over 1,000 Oracle instances and over 100 SQL Server installations in an 24/7 environment. The company enjoys very high uptime with it's Oracle Instances. If there is a problem with accessing Oracle then the issue is generally a storage or network failure. Even then, the passive node in the cluster takes over and the potentially impacted databases continue to run. As a matter of fact, the Oracle databases have been up since last year's scheduled generator and UPS upgrade. The SQL Server databases, however, have been a series of costly disappointments. The company expected to 'save money' on SQL Server (after all, SQL Server is cheaper, right?) but, after all of the bills were paid, SQL Server cost the company more because SQL Server features pale in comparison to Oracle and DB2. (As testimony for SQL Server's ineptness, I am writing this because the maximum length of a varchar in SQL Server is 8000?) Fortunately, Oracle has long since released a licensing model comparable to SQL Server and the company that I work for has already started saving money by converting the surviving SQL Server installations back to Oracle. Unfortunately for other companies that will be upgrading SQL Server to Yukon, SQL Server costs are about to go up with Microsoft's new SQL Server licensing model. By the way, I've been to a few Yukon presentations and I've shaken hands with Yukon developers in Redmond, CA.. They are all very nice people and I've always enjoyed speaking to them. However, my typical reaction to Yukon's new features has typically been 'Yeah, but Oracle and/or DB2 has been doing that for years.' Since you believe that Yukon will gobble up market share, you should know that the real 'threat' to market share is not MS SQL Server. The real threat to market share is/ (will be) MySQL. When life gives you a lemon, pray you have a DBA that knows what their doing.

Michael Valentine Jones


Yak DBA Kernel (pronounced Colonel) USA 6636 Posts

Posted - 05/09/2005 : 17:17:41

How did this year old topic get revived? Maybe we need a separate forum for Oracle vs. SQL Server vs. MySQL flame wars.

quote: Originally posted by Beachsandintoes ...Rant deleted...

CODO ERGO SUM Beachsandintoes


Starting Member Posted - 05/09/2005 : 19:06:47

Hi,
15 Posts

I apologize for the flame. Normally, I have a live and let live attitude. I know, I know - SQL Server DBAs should be allowed to breathe the same air as Oracle DBAs - even when SQL Server DBAs are filled with nothing but hot air. j/k! Really I'm just kidding... The frustration that I vented earlier is from watching an important project tank because of limitations in SQL Server that we do not have in DB2 and Oracle. Currently, we are converting adhoc SQL into stored procedures in order to improve Procedure Cache usage and eliminate SQL injection threats. We can do this because there are about 150,000 DML statements that can be converted into 75 stored procedures. (FYI: we didn't originally write the code, we are simply fixing it) Our plan is to write stored procedures that will write other stored procedures. We already have stored procedures that automatically generate new stored procedures in Oracle and DB2. Unfortunately, SQL Server is the proving ground for this project because the impact of adhoc SQL is far worse in SQL Server than any of the other database platforms and we keep running into issues with SQL Server. The latest issue is that NVARCHAR only supports up to a maximum of 4000. Arg! Some of our generated stored procedures can go well beyond 4000 or even 8000 characters. (FYI: varchar2 in Oracle supports over 32,000 characters) Ok, so our next attempt will be writing our generated stored procedures to a file on the database server. Heh heh, if we were doing this in Oracle we would do as the original poster noted, we would have used text_io and we would be home with our families. I hope all is well. Take care and again I apologize for the flame. - Beach

tkizer
Almighty SQL Goddess USA 31529 Posts

Posted - 05/09/2005 : 19:08:55

So why not use text or ntext data types in SQL Server to avoid the 4000/8000 nvarchar/varchar limitation?

Tara Beachsandintoes
Starting Member Posted - 05/09/2005 : 19:21:22

Thanks Tara,
15 Posts

We tried but: 1) Working with TEXT is not the same as working with nvarchar or varchar. For example, you can't simply do: set @strSQL = @strSQL + @strNewLine 2) We experimented with 'EXEC @txtSQL' and 'EXEC sp_execute @txtSQL'. Neither command was able to execute a simple as 'CREATE PROCEDURE XXXX AS ...'. Tara since you are the almighty SQL Goddess, do you know the goddess Caffiena or Stressa? LOL - I seem to be paying homage to them every day. Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel) USA 6636 Posts Posted - 05/09/2005 : 19:21:49

Instead of sending out flames, it would be a lot more productive and positive to state what you are trying to do, and ask for some help with how to do it. You seem to have made the assumption that since you could not figure out how to do it, there is no way to get it done in SQL Server. For item 1, use WRITETEXT to append data to the NTEXT column in a table. For item 2, you can execute the data in the NTEXT column from a table like this: select @txt_1 @txt_2 @txt_3 .. and from #temp_data exec (@txt_1 + @txt_2 + @txt_3 + ...and so on...) = = = so substring(ntext_data, 1, 4000), substring(ntext_data, 4001, 4000), substring(ntext_data, 8001, 4000), on...

CODO ERGO SUM


Edited by - Michael Valentine Jones on 05/09/2005 19:33:38

Vous aimerez peut-être aussi