Newsgroup: it.comp.lang.visual-basic
Titolo: Verificare se esiste tabella con ADO

Ciao a tutti,
premetto che ho cercato con google ma i metodi trovati non mi hanno
funzionato.
Ho la necessità di usare una tabella temporanea, quindi la creo, la uso e la
cancello. Voglio verificare prima di crearla se esiste già, in tal caso la
voglio cancellare prima.
Per ora ho fatto qualcosa del tipo:
sqlstr= "CREATE TABLE STAMPA ....."
ADOcmd.CommandText = sqlstr
On Error GoTo err
adocmd.execute
.... serie altre operazioni
exit sub
err:
  ADOcmd.CommandText = "DROP TABLE STAMPA;"
  ADOcmd.Execute
  Resume
End Sub
In questo modo se trova la tabella va correttamente sulla gestione, ma se
faccio l'execute mi da errore SQL, non vorrei dipendesse da Interbase,
infatti se io ad esempio a runtime faccio
ADOcmd.CommandText = "SELECT *..."
adocmd.execute
Se la sintassi è sbagliata e mi da errore sull'execute, se io A RUNTIME
modifico la query e sposto il cursore del debug in alto di una riga per
riassegnare il nuovo command text, ecco, che quando ritorno sull'execute mi
restituisce un'altra volta errore, anche se la sintassi è corretta. Non so
se è un errore di SIBProvider (interbase), oppure è una cosa normale per
ADO. Ecco l'errore che mi si genera credo sia per lo stesso motivo, in
quanto da errore su una CommandText, quindi gli riassegno la nuova, ma ormai
da errore...
Grazie a tutti :D


Non rispondo direttamente alla domanda però per risolvere il problema ti
consiglierei di evitare il continuo "CREATE" e "DROP" delle tabelle .. se ti
servono delle tab. temporanee chiamale con un nome tipo "temp_" .... che
senso ha continuare a crearle e distruggerle ? mica fai un piacere al DB
(soprattutto per un DB server come interbase) ... anzi.
L'unico caso che mi viene in mente è la possibilità che esistano più utente
e che per ogni utente hai bisogno di una tab temporanea diversa (per gestire
la multiutenza e conflitti vari).
Per rilevare l'elenco delle tab presenti in un db puoi usare :
1-una funzione specifica del DB (tipo in SQLServer può vedere la tab
sysobject se non ricordo male)
2-sfrutti ADOX
3-esegui una query sulla tab temp e verifichi se ti restituisce o meno un
errore
altre non mi vengono in mente
Saluti

Ci sono due possibilitā:
1 - Cerchi sul manuale di InterBase se ci sono funzioni specifiche (es. 
in MySQL c'č: DROP TABLE IF EXISTS NomeTabella);
2 - Usi ADO con il metodo OpenSchema per ricevere l'elenco delle tabelle 
del DB, in modo da crearti una tua funzione personale (come feci io 
tempo fa): una funzione tipo EsisteTabella("nometabella") che mi 
restituiva un booleano.
-- 
Quando noi ignoranti eravamo di pių, tutto era pių bello (A. Celentano).
  ___   _   ___ _  _______   _______ ___
|   \ /_\ | _ \ |/ / _ ) \ / /_   _| __|
| |) / _ \|   / ' <| _ \\ V /  | | | _|
|___/_/ \_\_|_\_|\_\___/ |_|   |_| |___|

 (soprattutto per un DB server come interbase) ... anzi.
Potresti spiegarti un tantino meglio? La cosa mi interessa (perchč a 
volte sono costretto a creare/distruggere tabelle temporanee con MySQL).
Perchč č sconsigliata questa tecnica?
-- 
Quando noi ignoranti eravamo di piů, tutto era piů bello (A. Celentano).


 errore
Questa 3 credo che mi da lo stesso errore che mi da ora, vedrò ADOX :D
Grazie :D

 restituiva un booleano.
Ok, entro domani faccio sapere :D
Tnx!

 in tal caso la voglio cancellare prima.
Non conosco Interbase, ma con altri dbms server esiste la possibilità di
creare tabelle con uno scope limitato alla connessione o alla sessione,
visibili quindi da chi le ha create o da chi è connesso.
Il create-drop viene quindi gestito dal dbms stesso senza andare a usare il
disco nelle aree destinate ai dati permanenti.
Questo punto è molto importante. Creare una tabella potenzialmente
permanente, e poi cancellarla, crea una inutile frammentazione del disco.
L'uso delle tabelle temporanee (in Ram o su aree apposite del server) evita
questa cosa. E, soprattutto, evita quella cosa stilisticamente sgradevole di
cambiar nome alle tabelle in funzione dell'utente o del pc.
Ciò non toglie che se la tabella, anche temporanea, esiste già perchè
precedentemente creata dallo stesso applicativo, occorra forzare un drop.
Tutti i dbms forniscono funzioni che consentono di vedere se la tabella
esiste, attraverso Sql. Ad esempio, per Sql-Server hai "If Exists
Object_Id(nome_tabella) Drop Table nome_tabella". Sicuramente Interbase ha
una cosa analoga.
Considera anche, se la tabella che cancelli e ricrei ha la stessa struttura,
la possibilità di effettuare un Truncate anzichè un Drop-Create.
Saluti
Alberto

 Perchè è sconsigliata questa tecnica?
Senza entrare nel merito di ogni DB, in generale una tab è un oggetto per la
formattazione e archiviazione dei dati. I programmi che gestiscono la loro
creazione, manutenzione ecc. non si limitano a memorizzare la struttura e i
tipi di dati ma "farciscono" di funzionalità tutti gli oggetti (tipo indici,
relazioni di integrità, piani di esecuzione ecc..) rendendoli molto più
complessi.
In pratica una tabella non è un semplice file o record, ma un oggetto molto
complesso che non è adatto alla continua creazione e distruzione, proprio
perchè richiederebbe una serie di azioni a catena certamente non prestanti
per il sistema DB.
Senza parlare poi del fatto che le tab sono oggetti fisici, quindi
memorizzati su disco e che al pari di un file crea frammentazione (come già
detto da Albe V° avanti)
Poi  non ti saprei dire se SQLS piuttosto che Oracle abbiano una gestione
talmente dinamica di tali oggetti da rendere preferibile il risparmio di
spazio su disco alla continua ri-generazione degli oggetti di tale livello.
Bisognerebbe chiedere ai vari MVP e DBMS Admin.
Saluti

Ah beh allora sto messo bene, perchè quando devo creare dei miei report 
(non uso CR e simili) creo/droppo tabelle TEMPORANEE (con MySQL 
CREATE/DROP TEMPORARY TABLE), che finiscono in ram.
Purtroppo prima di dire 'SI, IL REPORT FUNZIONA' mi tocca 
creare/droppare tabelle fisiche sul MIO pc, per poter controllare che il 
contenuto della tabella corrisponda a realtà.
Ma finchè si tratta del mio pc non credo ci siano problemi. L'importante 
è che il prodotto finale usi tabelle temporanee.
Thx per le delucidazioni.
-- 
Quando noi ignoranti eravamo di più, tutto era più bello (A. Celentano).


 Thx per le delucidazioni.
Penso che Albe abbia risposto in modo più esauriente ....
un discorso sono le tabelle temporanee supportate dal DB, un altro sono le
tabelle fisiche create e distrutte.
Access non supporta tabelle temporanee .. almeno non nel suo dialetto SQL.
Saluti

.... serie altre operazioni
Oltre al metodo "IF EXISTS" potresti provare con:
Dim rs As New ADODB.Recordset
Set rsSchema = myconnection.OpenSchema(adSchemaTables, Array(Empty,
Empty, Empty, "MyTable"))
Se rs.eof la tabella non esiste
=======================================================================
Se mi vuoi scrivere togli le maiuscole
Sveltolampo 
cteniza...@hotmail.com
=======================================================================

 Empty, Empty, "MyTable"))
Questo mettendo al posto di MyTable ad esempio "STAMPA" mi dava sempre EOF,
quindi ho fatto questo:
Vi sembra troppo "legnoso"? Non è che comunque lo deve fare tutti i giorni
questa operazione, e poi ci sta un'istante a ciclare sullo schema.
*************
Dim rstSchema As New ADODB.Recordset
Set rstSchema = ADOCn.OpenSchema(adSchemaTables)
Dim Cancella As Boolean
Cancella = False
Do Until rstSchema.EOF  'Ciclo sui nomi delle tabelle
  If UCase(rstSchema!TABLE_TYPE) = "TABLE" Then
    If rstSchema!TABLE_NAME = "STAMPA" Then
      Cancella = True
      Exit Do
    End If
  End If
  rstSchema.MoveNext
Loop
rstSchema.Close
Set rstSchema = Nothing
If Cancella = True Then
  ADOcmd.CommandText = "DROP TABLE STAMPA;"
  ADOcmd.Execute
End If
**************
Grazie a tutti ;)

 > Empty, Empty, "MyTable"))
Ho ritrovato la sintassi corretta, in pratica l'ultimo "MyTable" definisce
il tipo, quindi è o View o Table ecc.
Mentre per cercare per tabello devo:
Set rsSchema = myconnection.OpenSchema(adSchemaColumns, Array(Null, Null,
"STAMPA" , Null))
In questo modo si fa poi rsschema.eof come hai detto e si vede se esiste :D
Grazie a tutti :)