Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Drop Column - complicated problem
Message
 
 
To
30/11/2000 23:42:48
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00447719
Message ID:
00448987
Views:
9
Hi Trey,

For some reason, I could not make your idea to work. It returns LAERROR as laError[1,3] and shows it in laError[1,2] also. Something's strange. Perhhaps, you can find an error in the code bellow:
***********************************************************************************
procedure DeleteFields
*--------------------------------------------------------------------------
* -- RMM: 05/23/00
* --     This procedure compares the current table's fields with the fields in the
* --          datadict.
* --     If fields are found in the current table and not in the datadict, then assume
* --          we need to delete these fields ...
* --     This procedure is called before we do the modify (alter table) commands
*--------------------------------------------------------------------------
lparameters tcTableName
local lnOldSelect, lcCommandDel, lnCount, lcMessDel, lcMessDelIndx, ;
     lcOldError, llError, lcTag, lcOldMessage, llDel
lnOldSelect=select()
if !oValid.lContinue && Don't continue
     return
endif
create cursor oldTab (FldName C(128))
insert into oldTab from array laFields && Array of fields in a table
** Find fields, which should be deleted
store '' to lcCommandDel, lcMessDel, lcMessDelIndx
select * ;
     from oldTab ;
     where FldName not in ;
     (select Field_Name from DataDict where &tcTableName>0) ;
     into cursor curTemp

if _tally > 0
     select curTemp
     scan
          if !oValid.lContinue
               return
          endif
          lcCommandDel =lcCommandDel+ " DROP COLUMN " + lower(alltrim(curTemp.FldName))
          lcMessDel=lcMessDel+alltrim(curTemp.FldName)+','
     endscan
     suspend
     set message to 'Deleting fields: '+left(lcMessDel,len(lcMessDel)-1)
     =messagebox(lcCommandDel)
     lcOldError=on('error')
     on error llError = .t.
     alter table (tcTableName) &lcCommandDel
     do while llError
          =aerror(laError)
          if laError[1,1] = 1531 && cannot drop field because of index
               lcTag = laError[1,3]
               delete tag (lcTag)
               llError = .f.
               alter table (tcTableName) &lcCommandDel
          else
               exit
          endif
     enddo
     if llError
** Exited
          aerror(laError)
          =messagebox("Error: " + transform(laError[1,1])+chr(13)+;
               laError[1,2], 48)
     endif
     on error &lcOldError
     llDel=.t.
else && Tally=0 no fields to delete
     llDel=.f.
endif
* Close no longer needed tables
use in curTemp
use in oldTab
select (lnOldSelect)
return llDel
Thanks a lot in advance.

>>Great. Could you please post your test program for me to repeat? Did you try to create a one command line, then execute macro, or you delete field by field, as in your original idea. I guess, both approaches should work the same way, and I doubt, that the first will give speed benefit, because dropping fields is quite fast. Suppose, I have 5mln. records in a table and I want to drop, say, 4 fields. What is faster:
>>pseudo-code:
>>drop field1
>>drop field2, etc.
>>or lcDel='drop field 1 drop field2...'
>>&lcDel????
>>
>>Of course, for adding or changing fields, it's much better to do it once, e.g. construct the long command rather than executing field by field altering, but for dropping fields I guess, there is no speed difference. Do you know the answer on this question?
>>
>>Thanks again for your help. Your ideas are great support for me.
>

>Thank you for the kind words :)
>One command to drop all fields is the way to go. Especially with 5M records. In my test with 100K records, it took 6 seconds to drop each field individually and 2 seconds to drop both at once.
>Here's the test code I used. Setup for the test.
Create Database test
>Create Table test (ctest c(10), bogus c(10) primary key, bogus2 c(10))
>Index On ctest Tag ctest
>Index on bogus2 Tag bogus2
>Index on ctest+bogus2 Tag bogus3
>Do While Reccount()   Store Sys(2015) To m.ctest, m.bogus, m.bogus2
>  Insert Into test From Memvar
>EndDo
To run test: DropFields("test","bogus,bogus2")
** DropFields.prg
>LParameters tcTable, tcDropList
>Local llError, lcCommand
>Use (tcTable) Exclusive
>tcDropList = [,] + tcDropList
>tcDropList = Strtran(tcDropList, [,], [ drop column ])
>lcCommand = [Alter table ] + tcTable + tcDropList
>
>On Error llError = .T.
>&lcCommand
>Do While llError
>  AError(laError)
>  If laError[1,1] = 1531 && cannot drop field because of index
>    lcTag = laError[1,3]
>    ? "deleting tag ",lctag && just for messaging
>    Delete Tag (lcTag)
>    llError = .F.
>    &lcCommand
>  Else
>    Exit
>  EndIf
>EndDo
>If llError
>  ** Exited
>  AError(laError)
>  MessageBox("Error: " + Transform(laError[1,1])+Chr(13)+;
>    laError[1,2], 48)
>EndIf
>On error
btw, I've noticed in your code samples that you have the syntax coloring - do you have something you run that through before posting it, or do you take the time to do it by hand?
If it's not broken, fix it until it is.


My Blog
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform