Newsgroup: it.comp.lang.perl
Titolo: Errore inserimento in tabella

Salve a tutti.
Ho un problemino con l'inserimento e estrazione di record da un db in mysql.
#CONNESSIONE
$dbh_MYSQL = DBI->connect('DBI:mysql:database=controlloscatole',
'controlloscatole', 'controlloscatole');
#INTERROGAZIONE
my $sth1 = $dbh_MYSQL->prepare("SELECT * FROM ?");
#ESECUZIONE
$filiale="001";
$sth1->execute($filiale);
while(@pippo=$sth1->fetchrow_array){
 print "Scatola $pippo[0] e pratica $pippo[1]\n";
}
Cosě facendo mi da una serie di errori del tipo:
execute failed: Errore di sintassi nella query SQL.
Viceversa se tolgo il ? dalla query e metto direttamente il nome della
tabella che voglio interrogare tutto funziona alla perfezione:
#INTERROGAZIONE
my $sth1 = $dbh_MYSQL->prepare("SELECT * FROM ` 001` ");
#ESECUZIONE
$sth1->execute();
Francamente non capisco dove sbaglio.
Qualche ideuzza?
PS: OS winXP  con server mysql sulla stessa macchina


L'errore dipende dal fatto che la query da te prodotta e'
SELECT * FROM "001"
e ben pochi DBMS supportano i nomi di tabelle variabili. MySQL non e' 
fra questi.
Puoi usare i segnaposto (?) solo per indicare valori. I nomi di tabella 
e dei campi devono essere scritti nella query.
Ciao
gmax
-- 
   ____ ____  _____ _   _
  / _  |    \(____ ( \ / )
( (_| | | | / ___ |) X (
  \___ |_|_|_\_____(_/ \_)
(_____|
Sapere, saper fare, fare, far sapere
http://gmax.oltrelinux.com

 
Pensandoci meglio, forse il tuo problema e' un sintomo di 
non-normalizzazione.
Invece di avere una tabella per ogni filiale, perche' non metti
il codice filiale in un campo della tabella?
Poi potresti fare
my $query = "SELECt * from nometabella WHERE codice_filiale = ?";
my $sth = $dbh->prepare($query);
my @filiali = qw( 001 002 003 );
for my $filiale ( @filiali )
{
     $sth->execute($filiale);
     while (my @record = $sth->fetchrow_array())
     {
          # fai qualcosa con il record


 e dei campi devono essere scritti nella query.
Caspita quindi devo fare una query per ogni  filiale?
Cioč se ho 33 filiali devo fare 33 query identiche dove cambia il numero
della filiale dopo l'INSERT?

della filiale dopo l'INSERT?
A parte quanto già detto (cioè che forse c'è qualcosa di sbagliato o non
del tutto conveniente nel progetto del database), dove sarebbe il problema
di costruire 33 (o 33000) query?
Quello che non può fare MySql può farlo facilmente perl, costruendo la
stringa di interrogazione nel modo che ti sembrerà più conveniente:
  my $filiale="001";
  my $sth1 = $dbh_MYSQL->prepare("SELECT * FROM " . $filiale);
  ....
Le prestazioni saranno inferiori a quelle che avresti se potessi preparare
una query parametrica, ma siccome non puoi usare come parametro la tabella
sono comunque il massimo che puoi avere.
Ciao.

 non-normalizzazione.
Si hai ragione ma č voluta... Mi spiego meglio (anche se forse sono un
pochino OT)
Il db originale č in access e contiene un tot di scatole e pratiche per ogni
filiale ben normalizzato.
Da questo db devo esportare in uno MySQL dove il responsabile di ogni
filiale deve poter leggerevia web le proprie scatole e non quelle delle
altre filiali.
La soluzione migliore sarebbe esportare la tabella cosě come č e farsi un
CGI di interrogazione ma.... non ho il tempo.
Quindi sto optando per fare una tabella per filiale da interrogare con
phpmyadmin (non me ne vogliate per aver scritto questa parola)...
A questo punto il problemino č di mysql perchč permette l'autenticazione
degli utenti in base l'host, il db, la tabella ed un campo della tabella ma
non su una eventuale clausola WHERE su un campo.
Per tale motivo ho pensato di dividere le scatole su tabelle differenti e
dare a ogni capo filiale il permesso solo a quella tabella...
Spero di aver spiegato bene il problema.
Qualsiasi suggerimento č ben accettato :-)


Continuo l'OT, e ti suggerisco di mettere comunque il codice filiale in 
ogni tabella, e poi di riunire le varie tabelle sparse con una tabella 
di tipo MERGE.
La tabella MERGE ti consente di vedere tutte piu' tabelle (con la stessa 
struttura) come una sola, e di interrogarle globalmente, mantenendo 
intatti i privilegi che hai dato.
Una volta ho dovuto fare un lavoro del genere, e tanto per uscire 
dall'OT eccoti una soluzione in Perl per creare la tabella merge.
Questo script presuppone che le tabelle che hanno un nome tutto numerico 
siano quelle delle filiali, e che abbiano tutte la stessa struttura.
my $tabella_merge = 'SCATOLE';  # metti il nome che vuoi
# prende la struttura della prima tabella
my $query = qq{show create table 001};
# legge la struttura
my (undef, $create) = $dbh->selectrow_array($query);
# legge i nomi delle tabelle
my @nomitabelle = sort
               grep { /^\d+$/ }
               @{
                $dbh->selectcol_arrayref(
                    "show tables from nomeDelTuoDatabase"
                )
                };
my $tabelle = join ",\n", @nomitabelle;
# mette il nome della nuova tabella
$create =~ s/001//;
$create =~ s/001/$tabella_merge/;
# aggiunge la lista delle tabelle che compongono il MERGE
$create =~ s/TYPE=MyISAM/\nTYPE=MERGE\nUNION=($tabelle)/;
print $create;
Se tutto va bene, ti produce una query per generare la tabella grande, 
che non occupa spazio su disco, ma e' solo un trucco del DBMS.
Per modificare tutte le tabelle in modo che abbiano il codice_filiale, 
puoi usare lo stesso array:
for (@nomitabelle) {
   $dbh->do("alter table $_
            add column codice_filiale unsigned int NOT NULL ");
   $dbh->do("update table $_ set codice_filiale = $_");
