Problema struttura db e query con più tabelle

giovedì 23 marzo 2006 - 18.25

renyp Profilo | Newbie

Ciao a tutti!
Sto imparando a usare asp,e di conseguenza anche sql. Uso Access per il momento.
Sto facendo un sito in asp - vbscript - con un db che ha attualmente 3 tabelle: Utenti, News e Annunci. Ogni utente può inserire annunci o news nuove, ed anche gestire news e annunci inseriti precedentemente. Tutto questo una volta registrato e loggato, ovviamente.
Il mio problema: effettuato il login, l'utente potrà visualizzare un elenco dei contenuti inseriti di suo pugno. Penso quindi si debba impostare il db in modo particolare: Utenti.ID dovrà essere uguale a un campo sia in News che in Annunci, in modo tale che potrò fare una query del tipo:
Select titolo, sottotitolo, corpo, data
From Annunci
Where Utenti.ID = Annunci.nomecampo

Vorrei capire come impostare il db in modo adatto e come scrivere correttamente la query. Pensavo ad un campo in Annunci e News che prenda automaticamente il valore di Utenti.ID, ma non so se è la soluzione giusta, nè come fare.
Ho cercato in molti corsi online ma non sono molto dettagliati..
Sapreste darmi qualche suggerimento? Spero di essermi spiegato bene e non aver fatto troppa confusione..
Grazie in anticipo!!

escaflowne Profilo | Junior Member

basterebbe, se non ho capito male il problema, che annunci e news siano figlie di utenti. Crea le tabelle con una relazione uno a molti fra utenti (uno) e news (molti), quindi crei la relazione uno a molti fra utenti (uno) e annunci (molti)
Questo è coerente perchè un utente può inserire molte news e annunci ma una news (ed un annuncio) può essere stato creato da un solo utente.
Questa relazione ti garantisce l'estrazione di tutto ciò (e solo quello) che l'utente ha creato, il tutto con una query tipo:

select ....
from utenti
,news
,annunci
where utenti.id = news.idUtenti
and utenti.id = annunci.idUtenti
and utenti.id = ....id dell'utente....

se non conosci a priori l'id potresti prelevarlo quando fa la login tipo
select id
from utente
where usrName = ......
and pwd = .....

poi l'id potresti portartela sempre dietro, ad esempio con una variabile di sessione (visibile solo a lui)
<% session("idUtente") = ....valore estratto dalla query %>

spero di aver capito il problema

>Ciao a tutti!
>Sto imparando a usare asp,e di conseguenza anche sql. Uso Access
>per il momento.
>Sto facendo un sito in asp - vbscript - con un db che ha attualmente
>3 tabelle: Utenti, News e Annunci. Ogni utente può inserire annunci
>o news nuove, ed anche gestire news e annunci inseriti precedentemente.
>Tutto questo una volta registrato e loggato, ovviamente.
>Il mio problema: effettuato il login, l'utente potrà visualizzare
>un elenco dei contenuti inseriti di suo pugno. Penso quindi si
>debba impostare il db in modo particolare: Utenti.ID dovrà essere
>uguale a un campo sia in News che in Annunci, in modo tale che
>potrò fare una query del tipo:
>Select titolo, sottotitolo, corpo, data
>From Annunci
>Where Utenti.ID = Annunci.nomecampo
>
>Vorrei capire come impostare il db in modo adatto e come scrivere
>correttamente la query. Pensavo ad un campo in Annunci e News
>che prenda automaticamente il valore di Utenti.ID, ma non so
>se è la soluzione giusta, nè come fare.
>Ho cercato in molti corsi online ma non sono molto dettagliati..
>Sapreste darmi qualche suggerimento? Spero di essermi spiegato
>bene e non aver fatto troppa confusione..
>Grazie in anticipo!!
>

renyp Profilo | Newbie

grazie mille per la risposta!
Adesso provo a seguire i tuoi consigli e poi ti faccio sapere se ho fatto bene..
Grazie ancora!!

escaflowne Profilo | Junior Member

>grazie mille per la risposta!
>Adesso provo a seguire i tuoi consigli e poi ti faccio sapere
>se ho fatto bene..
>Grazie ancora!!

di nulla. Chiedi pure senza problemi

renyp Profilo | Newbie

ciao!
Dunque, il problema che ti ho esposto in precedenza adesso è risolto, funziona tutto alla perfezione!

Adesso però il db fa i capricci con il login, non so perchè..
Innanzitutto non riceve più i dati di una nuova registrazione, da questo errore:

Microsoft JET Database Engine error '80040e14'

Errore di sintassi nell'istruzione INSERT INTO.

/Sito_Immo/iscritto.asp, line 34

la query è:

sqlIscrizione = "INSERT INTO Inserzionisti"
sqlIscrizione = sqlIscrizione & "(nome,cognome,indirizzo,citta,provincia,cap,telefono,mail,"
sqlIscrizione = sqlIscrizione & "username,password,newsletter,agenzia,fax)"
sqlIscrizione = sqlIscrizione & "VALUES('"&nome&"','"&cognome&"','"&indirizzo&"','"&citta&"',"
sqlIscrizione = sqlIscrizione & "'"&provincia&"','"&cap&"','"&telefono&"','"&mail&"','"&username&"',"
sqlIscrizione = sqlIscrizione & "'"&password&"','"&newsletter&"','"&agenzia&"','"&fax&"')"

objConn.execute (sqlIscrizione) ----------------------------------> LINEA 34

è incluso in questa pagina un file di apertura della connessione col db, il cui codice è:

<%
dim objConn, strConn
set objConn = server.createobject("Adodb.Connection")
strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Server.MapPath ("db/immodb.mdb")
objConn.open strConn
%>

Ho controllato e la posizione dei campi della query e del db corrisponde, quindi non so a cosa attribuire l'errore...
Può essere che, avendo creato le relazioni fra tabelle in un momento successivo la compilazione di questi script, vengano generati dei problemi?
Ho notato anche una cosa:.
Usando firefox il primo utente registrato, con ID = 1, non può loggarsi perchè non viene riconosciuto..con gli altri questo problema non c'è..
Usando Explorer non ci si può loggare proprio..

escaflowne Profilo | Junior Member

>ciao!
>Dunque, il problema che ti ho esposto in precedenza adesso è
>risolto, funziona tutto alla perfezione!
>
>Adesso però il db fa i capricci con il login, non so perchè..
>Innanzitutto non riceve più i dati di una nuova registrazione,
>da questo errore:
>
>Microsoft JET Database Engine error '80040e14'
>
>Errore di sintassi nell'istruzione INSERT INTO.
>
>/Sito_Immo/iscritto.asp, line 34
>
> la query è:
>
>sqlIscrizione = "INSERT INTO Inserzionisti"
> sqlIscrizione = sqlIscrizione & "(nome,cognome,indirizzo,citta,provincia,cap,telefono,mail,"
> sqlIscrizione = sqlIscrizione & "username,password,newsletter,agenzia,fax)"
> sqlIscrizione = sqlIscrizione & "VALUES('"&nome&"','"&cognome&"','"&indirizzo&"','"&citta&"',"
> sqlIscrizione = sqlIscrizione & "'"&provincia&"','"&cap&"','"&telefono&"','"&mail&"','"&username&"',"
> sqlIscrizione = sqlIscrizione & "'"&password&"','"&newsletter&"','"&agenzia&"','"&fax&"')"
>
> objConn.execute (sqlIscrizione) ---------------------------------->
>LINEA 34
>
>è incluso in questa pagina un file di apertura della connessione
>col db, il cui codice è:
>
><%
>dim objConn, strConn
>set objConn = server.createobject("Adodb.Connection")
> strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" &
>Server.MapPath ("db/immodb.mdb")
> objConn.open strConn
>%>
>
>Ho controllato e la posizione dei campi della query e del db
>corrisponde, quindi non so a cosa attribuire l'errore...
>Può essere che, avendo creato le relazioni fra tabelle in un
>momento successivo la compilazione di questi script, vengano
>generati dei problemi?

Serve qualche altra informazione quindi ti faccio qualche domanda:
- i campi del database sono tutti testo o c'è qualche number? (es cap)
- manca, per caso, qualche campo che ti sei dimenticato?
- la chiave primaria della tabella INSERZIONE è un contatore?

Cosa importante: Non è che stai, per caso, provando ad inserire un valore con un apostrofo? In questo caso sarebbe chiaro l'errore. Per risolvere puoi creare una funzioncina tipo questa:

Function Rep(val) if not isNull(val) then Rep = Replace(val,"'", "''") else Rep = val end if End Function

La metti all'inizio della pagina e l'insert la cambi in questo modo


Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

ovviamente se queste variabili le valorizzi con la request, la rep la metti li (in poche parole la insert la lasci come ce l'hai già ma ogni variabile diventa:
nome= rep(request("nome"))
cognome = rep(request("cognome"))

ecc

Prova intanto così e scusami se sono stato troppo contorto

>Ho notato anche una cosa:.
>Usando firefox il primo utente registrato, con ID = 1, non può
>loggarsi perchè non viene riconosciuto..con gli altri questo
>problema non c'è..
>Usando Explorer non ci si può loggare proprio..

ecco, questo è proprio strano

renyp Profilo | Newbie

Allora...

--------------------------------------------------------------------------------------
Serve qualche altra informazione quindi ti faccio qualche domanda:
- i campi del database sono tutti testo o c'è qualche number? (es cap)
- manca, per caso, qualche campo che ti sei dimenticato?
- la chiave primaria della tabella INSERZIONE è un contatore?
--------------------------------------------------------------------------------------

1) non sono tutti testo. 5 sono testo, alcuni memo, uno NO\SI ed alcuni numerici, tra cui cap..
tra l'altro ho notato che alcuni valori - i primi, c'è anche qualche numerico - li stampa, da un certo punto in poi - se non sbaglio proprio da cap in poi - non più

2)non manca nessun campo, anche perchè prima funzionava

3)la chiave primaria non l'avevo messa, forse di default ha preso l'ID contatore

-----------------------------------------------------------------------------------------------------------------------
Cosa importante: Non è che stai, per caso, provando ad inserire un valore con un apostrofo?
-----------------------------------------------------------------------------------------------------------------------

No, sono semplici user e password..

escaflowne Profilo | Junior Member


>1) non sono tutti testo. 5 sono testo, alcuni memo, uno NO\SI
>ed alcuni numerici, tra cui cap..
>tra l'altro ho notato che alcuni valori - i primi, c'è anche
>qualche numerico - li stampa, da un certo punto in poi - se non
>sbaglio proprio da cap in poi - non più
>
I campi numerici non li puoi inserire inserire con gli apostrofi:
Facciamo finta che CAP sia numerico, la query sarà:

sqlIscrizione = "INSERT INTO Inserzionisti" sqlIscrizione = sqlIscrizione & "(nome,cognome,indirizzo,citta,provincia,cap,telefono,mail," sqlIscrizione = sqlIscrizione & "username,password,newsletter,agenzia,fax)" sqlIscrizione = sqlIscrizione & "VALUES('"&nome&"','"&cognome&"','"&indirizzo&"','"&citta&"'," sqlIscrizione = sqlIscrizione & "'"&provincia&"',"&cap&",'"&telefono&"','"&mail&"','"&username&"'," sqlIscrizione = sqlIscrizione & "'"&password&"','"&newsletter&"','"&agenzia&"','"&fax&"')"

Cioè SENZA apici prima e dopo il cap ( '"&provincia & "'," &cap & ",'" & telefono ..... ecc......

Chiaro?


>2)non manca nessun campo, anche perchè prima funzionava
>
>3)la chiave primaria non l'avevo messa, forse di default ha preso
>l'ID contatore
>
>-----------------------------------------------------------------------------------------------------------------------
>Cosa importante: Non è che stai, per caso, provando ad inserire
>un valore con un apostrofo?
>-----------------------------------------------------------------------------------------------------------------------
>
>No, sono semplici user e password..

Comunque usala la funzione che ti ho postato (la rep()) perchè capiterà (perchè sicuramente capiterà) che l'utente Gianni D'Angelo si iscriverà e l'apostrofo ti farà taaaanto casino

renyp Profilo | Newbie

Ho fatto la query così:


sqlIscrizione = "INSERT INTO Inserzionisti"
sqlIscrizione = sqlIscrizione & " ( nome,cognome,indirizzo,citta,provincia,cap,telefono,mail,"
sqlIscrizione = sqlIscrizione & "[username],[password],newsletter,agenzia,fax)"
sqlIscrizione = sqlIscrizione & "VALUES('"&nome&"','"&cognome&"','"&indirizzo&"','"&citta&"',"
sqlIscrizione = sqlIscrizione & "'"&provincia&"',"&cap&",'"&telefono&"','"&mail&"','"&username&"',"
sqlIscrizione = sqlIscrizione & "'"&password&"','"&newsletter&"','"&agenzia&"','"&fax&"' ) "



con firefox mi da errore di Overflow
riga 34 -----> objConn.execute (sqlIscrizione)
ma funziona il login

con explorer non funziona il login e alla registrazione non trova la pagina e da
HTTP 500 - Errore interno del server
Internet Explorer

ma gli apici devo toglierli a tutti i campi numerici, tipo telefono fax ecc...? perchè alcuni campi numerici in effetti funzionano anche con gli apici..
forse non ho capito...

escaflowne Profilo | Junior Member

>Ho fatto la query così:
>
>
>sqlIscrizione = "INSERT INTO Inserzionisti"
> sqlIscrizione = sqlIscrizione & " ( nome,cognome,indirizzo,citta,provincia,cap,telefono,mail,"
> sqlIscrizione = sqlIscrizione & "[username],[password],newsletter,agenzia,fax)"
> sqlIscrizione = sqlIscrizione & "VALUES('"&nome&"','"&cognome&"','"&indirizzo&"','"&citta&"',"
> sqlIscrizione = sqlIscrizione & "'"&provincia&"',"&cap&",'"&telefono&"','"&mail&"','"&username&"',"
> sqlIscrizione = sqlIscrizione & "'"&password&"','"&newsletter&"','"&agenzia&"','"&fax&"'
>) "
>
>
>
>con firefox mi da errore di Overflow
>riga 34 -----> objConn.execute (sqlIscrizione)
>ma funziona il login
>
>con explorer non funziona il login e alla registrazione non trova
>la pagina e da
>HTTP 500 - Errore interno del server
>Internet Explorer
>
>ma gli apici devo toglierli a tutti i campi numerici, tipo telefono
>fax ecc...? perchè alcuni campi numerici in effetti funzionano
>anche con gli apici..
>forse non ho capito...

prima di tutto un dubbio: perchè telefono, fax, cap ecc li hai fatti numerici? Secondo me non ha senso perchè, di fatto, non li userai mai come numeri (non ci fai operazioni sopra) e poi metti che debba inserire il numero di telefono 050444444, il db ti eliminerà lo zero iniziale rendendo inutile il dato conservato (se provi a comporre il numero 50444444 ti da errore no ;) ); poi si potrebbe voler inserire il numero 0544212121/2/3 (cioè tre linee telefoniche): con un campo numerico non puoi farlo

Secondo me dovresti farli diventare tutti string e tornare alla query iniziale (stando attento agli apici inseriti dagli utenti)

renyp Profilo | Newbie

Ho modificato i campi.
Firefox per login funziona, per registrazione:

Microsoft JET Database Engine error '80040e07'

Tipi di dati non corrispondenti nell'espressione criterio.

/Sito_Immo/iscritto.asp, line 34

Explorer non si logga e fa l'errore di prima perchè non trova pagina...

escaflowne Profilo | Junior Member

>Ho modificato i campi.
>Firefox per login funziona, per registrazione:
>
>Microsoft JET Database Engine error '80040e07'
>
>Tipi di dati non corrispondenti nell'espressione criterio.
>
>/Sito_Immo/iscritto.asp, line 34
>
mi sa che ti sei dimenticato qualche apice adesso :)
Ricorda che se hai messo tutte string (tranne id che deve rimanere contatore mi raccomando) devi rimettere gli apici a tutti i campi

>Explorer non si logga e fa l'errore di prima perchè non trova
>pagina...

scusa ma potresti mettere su le pagine di login e di registrazione? Probabilmente il problema riusciamo a scovarlo meglio guardando tutto il codice

renyp Profilo | Newbie

Form login

<form name="login" method="post" action="controllo.asp">
<input type="text" name="username" maxlength="8">
<input type="password" name="password" maxlength="8">
<input type="image" src="images/freccia_vai.gif" name="invia" value="invia">
</form>

script di controllo che includo nella pagina che processa i dati di login:

dim username, password, invia
username = request.form ("username")
password = request.form ("password")
invia = request.form ("invia")


if invia <> "" then
sqlControllo = "SELECT id,[username],[password], nome, cognome FROM Inserzionisti "
sqlControllo = sqlControllo & "WHERE username='"&username&"' and password='"&password&"' "

set rsControllo = objConn.execute (sqlControllo)
if rsControllo.eof <> true then
msgBenvenuto = rsControllo("nome") & " " & rsControllo("cognome")
dim idUtente
idUtente = rsControllo("id")
session("loggato") = idUtente
'session.Timeout = 10
'response.Write session("loggato") : response.end
else
response.redirect("registrazione.asp")
end if
else
if session("loggato") = "" then
response.redirect("registrazione.asp")
else
response.redirect("ERRORE")
end if
end if

Questo il form di registrazione:

<form name="form" method="post" action="iscritto.asp" onsubmit="return verifica();">
<fieldset>
<legend>Dati personali</legend>
<input type="text" name="nome">
<input type="text" name="cognome">
<input type="text" name="agenzia">
<input type="text" name="indirizzo">
<input type="text" name="citta">
<input type="text" name="provincia">
<input type="text" name="cap">
<input type="text" name="telefono">
<input type="text" name="fax">
</fieldset>
<fieldset>
<input type="text" name="mail">
<input type="text" name="username" maxlength="8">
<input type="password" name="password" maxlength="8">
<input type="checkbox" name="newsletter" value="si">
<input type="checkbox" name="privacy" value="si">
<input type="submit" name="Submit" value="Invia">
</fieldset>
</form>

Pagina in cui si processano i dati della registrazione:

dim nome, cognome, indirizzo, citta, provincia, cap, telefono, mail, username, password, newsletter, agenzia, fax
nome = request.form("nome")
cognome = request.form("cognome")
indirizzo = request.form("indirizzo")
citta = request.form("citta")
provincia = request.form("provincia")
cap = request.form("cap")
telefono = request.form("telefono")
mail = request.form("mail")
username = request.form("username")
password = request.form("password")
newsletter = request.form("newsletter")
agenzia = request.form("agenzia")
fax = request.form("fax")

sqlIscrizione = "INSERT INTO Inserzionisti"
sqlIscrizione = sqlIscrizione & " ( nome,cognome,indirizzo,citta,provincia,cap,telefono,mail,"
sqlIscrizione = sqlIscrizione & "[username],[password],newsletter,agenzia,fax)"
sqlIscrizione = sqlIscrizione & "VALUES('"&nome&"','"&cognome&"','"&indirizzo&"','"&citta&"',"
sqlIscrizione = sqlIscrizione & "'"&provincia&"','"&cap&"','"&telefono&"','"&mail&"','"&username&"',"
sqlIscrizione = sqlIscrizione & "'"&password&"','"&newsletter&"','"&agenzia&"','"&fax&"' ) "
'response.Write sqlIscrizione : response.end

objConn.execute (sqlIscrizione)
response.Redirect ("default.asp")

File di apertura connessione al db che includo dove serve:

dim objConn, strConn
set objConn = server.createobject("Adodb.Connection")
strConn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Server.MapPath ("db/immodb.mdb")
objConn.open strConn

La chiusura della connessione la scrivo così, sempre in fondo alla pagina dove c'è l'apertura:

objConn.close
set objConn = nothing

Spero di non aver dimenticato nulla...

P.s.: ATTENZIONE!! ho testato la query sul db e mi da questo errore..forse siamo vicini..

------------------------------------------------------------------------------------------------

numero di campi impostati a null per un errore di conversione tra tipi: 1;
numero di record non aggiunti alla tabella a causa di violazioni di chiave: 0;
a causa di violazioni di condivisione: 0;
a causa di violazioni della regola di convalida: 0.

------------------------------------------------------------------------------------------------

I campi sono adesso tutti di tipo testo, tranne un id contatore ed il campo newsletter Si\No..
Tutti i campi accettavano valore nullo, tranne user e password. Li ho modificati per far loro accettare Null ma non funziona ancora..



P.p.s.: ho risolto! Ti dico cos'era...
Nel form per il login, innanzitutto, inviavo i dati cliccando su un pulsante immagine, un
<input type="image">. Il valore di quel pulsante purtroppo non veniva passato. Così ho messo un <input type="hidden"> appena sotto, con lo stesso nome del pulsante precedente. Adesso gli passo un valore quando faccio il request.form di "invia"..

Per quel che riguarda la query, invece, è bastato modificare il tipo di campo della newsletter. Prima era Si\No, adesso è testo..non so perchè, così funge...

Ti devo ringraziare perchè sei stato gentilissimo, vorrei ricambiare ma credo che un tuo eventuale dubbio in materia sia ancora troppo per me..forse col tempo..
Ciao e grazie ancora!!!

escaflowne Profilo | Junior Member

Figurati,
sono contento che ti sia stato utile. E' lo spirito di un forum come questo.
Mi raccomando, ogni volta che hai un problema studialo per bene (stimola e si impara così) e vieni a chiedere (lo faccio anche io e spesso )

Alla prossima
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5