Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2006
    Messaggi
    188

    [VB6 sp6] - Problema aggiornamento recordset

    Cari amici ho un grosso problema che mi sta togliendo la vita.
    ho un progetto nel quale vado a creare e/o aggiornare un recordset (che poi è la riga di un documento)
    Ora: per non stare tranquillo, ho voluto fare la versione ADO, in prospettiva di mettere il DB sotto sql su server farm, cambiando tutti i comandi di connessione, apertura etc. etc.
    Problema:
    In inserimento nessun problema.
    Vado a modificare e mi da il maledetto errore
    'Impossibile individuare la riga specificata per l'aggiornamento. E'
    possibile che alcuni valori siano stati modificati dopo l'ultima
    operazione di lettura'

    connessione db:
    Set dbarchivio = New Connection
    Archivio.CursorLocation = adUseClient

    Archivio.Open "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=" + Trim(percorso) + ";Jet OLEDB: Database Password=xxxxx"

    per il recordset:

    Set rsrigaordine = New ADODB.Recordset
    rsrigaordine.Open Trim(documento) + "_RIGHE", Archivio, adOpenStatic, adLockOptimistic

    rsrigaordine.AddNew

    così, l'inserimento.

    Per la modifica vario in:
    Sql = "select * from " + Trim(documento) + "_RIGHE " _
    & "where num_riga=" & nr & " and doc_id='" + Trim(codicedoc) + "' and azienda_id = " & testordine!AZIENDA_ID & " "
    Set rsrigaordine = New ADODB.Recordset
    rsrigaordine.Open Sql, Archivio, adOpenStatic, adLockOptimistic

    A questo punto, se faccio subito un update, senza 'toccare' nessun campo, non da nessun errore, altrimenti, qualsiasi sia il campo che vario, anche se lo vario con lo stesso valore, all'UPDATE mi esce l'errore.
    Da premettere che nella sezione dove lavoro con le anagrafiche (clienti, articoli) non ho questo problema e le stringhe comandi sono 'identiche'
    Potrebbe essere un problema di qualche settaggio strano della tabella?
    L'archivio è un DB Access 2002, con tabelle 'importate' da un DB SQL.

    Grazie fin d'ora a chi mi aiuterà a risolvere questo dilemma (presumo già chi saranno i miei 2 angeli custodi)

  2. #2
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    Prima di tutto, ti consiglio caldamente di abbandonare la scrittura di enunciati SQL alla 'vecchia maniera'.
    Con ADODB è raccomandato l'uso dei Command e relativi parametri per motivi di vista di chi sviluppa che sarebbe costretto (alla vecchia maniera) a fare i salti mortali per formattare le stringhe con apici, cancelletti, formati data (e chi più ne ha più ne metta...).
    Oltretutto il codice diventa estremamente più leggibile, e perciò manutenibile, al contrario della 'vecchia maniera' in cui spesso devi perdere tempo solo perchè hai scordato un'apice!

    Vedi il mio articolo in firma su ADODB e Command (include un progetto di esempio con funzioni molto utili per un database Access!).
    Una volta che metterai in pratica l'uso dei Command ti chiederai in che mondo hai vissutto fino ad ora...


    Veniamo al problema: nell'enunciato SQL hai scritto (ricorda di usare i tag CODE per il codice!!!) qunato segue (lo riscrivo formattandolo per migliorare la leggibilità:
    codice:
    Sql = "SELECT * FROM " & Trim(documento) & "_RIGHE " 
    Sql = Sql & " WHERE num_riga=" & nr 
    Sql = Sql & " AND doc_id='" & Trim(codicedoc) & "' " 
    Sql = Sql & " AND azienda_id = " & testordine!AZIENDA_ID & " "
    Onestamente non capisco perchè esegui un comando SELECT quando invece per aggiornare i dati occorre fare un UPDATE...
    Ancor di più non capisco perchè usi un recordset?
    Per aggiornare i campi via SQL basta il metodo Execute della connessione:

    codice:
    Archivio.Execute Sql
    Ma, in ogni caso, devi fare un UPDATE.


    1) Hai verificato i valore delle tue variabili prima di eseguire l'enunciato SQL?

    2) se PRIMA esegui un
    codice:
    Debug.Print Sql
    cosa leggi nella finestra Immediata di VB6?
    Riporta il testo...



  3. #3
    Utente di HTML.it
    Registrato dal
    Aug 2006
    Messaggi
    188
    Buon giorno Gibra, e grazie per l'attenzione. Mi andrò a leggere il tuo articolo così se mi farà 'crescere' te ne sarò grato... in eterno (si dice così!)

    Cominciamo dal fondo

    [QUOTE]Ma, in ogni caso, devi fare un UPDATE. 1) Hai verificato i valore delle tue variabili prima di eseguire l'enunciato SQL? 2) se PRIMA esegui un codice: Debug.Print Sql cosa leggi nella finestra Immediata di VB6? Riporta il testo...

    ecco il testo
    select * from fatt_cli_RIGHE where num_riga=10 and doc_id='2011-FVK-0000022' and azienda_id = 1

    Pensando alla tua domanda

    codice: Sql = "SELECT * FROM " & Trim(documento) & "_RIGHE " Sql = Sql & " WHERE num_riga=" & nr Sql = Sql & " AND doc_id='" & Trim(codicedoc) & "' " Sql = Sql & " AND azienda_id = " & testordine!AZIENDA_ID & " " Onestamente non capisco perchè esegui un comando SELECT quando invece per aggiornare i dati occorre fare un UPDATE... Ancor di più non capisco perchè usi un recordset? Per aggiornare i campi via SQL basta il metodo Execute della connessione:
    effettivamente la uso x... abitudine, di solito vado a modificare facendo ancora operazioni tra i campi, è un mio modo di operare. Ultimamente ho iniziato ad usare l'execute, ma non so perchè, essendo tanti campi nel record, mi trovo meglio con la sql (che uso per posizionarmi sul record) e poi modifico, anche perchè a volte, per alcuni campi, a seconda del valore che trovo devo fare o meno delle operazioni.

    A tal proposito, ti comunico che un primo controllo che ho fatto, (sia in questa routine che non funge sia in un altra che funge) è stato quello di verificare che il record letto fosse quello voluto e, ripeto se per errore ti fosse sfuggito, come sarebbe capitato a me, che se faccio l'update subito, senza aver messo o confermato un campo non ho l'errore, se invece, tipo il primo campo dove c'è l'azienda lo 'rinfresco' con lo stesso valore, (verificato anche questo in debug), e provo subito l'update mi da l'errore. L'altra routine che ti cito e non ti riporto è semplicemente l'anagrafica articoli, aggiornamento, prezzo, unità di misura, descrizione, etc., sempre presa con una sql 'parametrizzata' sull'articolo che mi serve, ma qui non mi da nessun problema. stesso DB etc. etc.

    Spero, questa volta, di averTi dato le risposte come me le hai richieste e... sono a tua disposizione se ho errato qualcosa (faccio già adesso le mie scuse )

  4. #4
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    OK, abbiamo appurato che l'enunciato SQL è corretto (almeno dal punt di vista formale)

    però resta il fatto che non hai indicato il codice che usi per aggiornare.

    e, ancor più importante, qual'è il campo impostato come chiave primaria?


  5. #5
    Utente di HTML.it
    Registrato dal
    Aug 2006
    Messaggi
    188
    So già che non è di tuo gradimento , ma... non ho un campo chiave.
    Per quanto riguarda il codice per l'aggiornamento, dopo la 'lettura', setto i vari campi con il mio vecchio (dopo aver parlato con te, STRAVECCHIO ) metodo

    rsrigaordine!campo = valore
    etc. etc.

    alla fine

    rsrigaordine.update

  6. #6
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    Originariamente inviato da benjy
    So già che non è di tuo gradimento , ma... non ho un campo chiave.
    Lo sospettavo...
    Quindi sbagli sapendo di sbagliare.
    Il problema non è che io non lo gradisco, è il database che non lo gradisce.
    Il tuo problema è tutto qui.

    Non so come fai a lavorare senza una chiave primaria, io non ci riuscirei perchè tutti gli aggiornamenti NON li faccio usando il metodo Update del recordset, ma tramite i Command con enunciati SQL del tipo:

    codice:
    UPDATE tabella Set Campo1=?, Campo2=?,
    WHERE IDChiavePrimaria = <n>
    Se non avessi/usassi la chiave primaria sarei fritto.

    Ma poi scusa, non capisco: che male ti fa averla ?


    Originariamente inviato da benjy
    Per quanto riguarda il codice per l'aggiornamento, dopo la 'lettura', setto i vari campi con il mio vecchio (dopo aver parlato con te, STRAVECCHIO ) metodo

    rsrigaordine!campo = valore
    etc. etc.

    alla fine

    rsrigaordine.update
    Sì, sì, adesso capisco.
    Non vedo alcuna soluzione al tuo problema diversa da quella di creare la chiave primaria.


  7. #7
    Utente di HTML.it
    Registrato dal
    Aug 2006
    Messaggi
    188
    Scusa la mia ormai nota 'ignoranza', ma perchè solo con questa tabella mi dà il problema ? La tabella dell'anagrafica clienti, anagrafica articoli, testate documenti, che NON hanno neanche loro la chiave primaria, non ho nessun problema. E' uno dei tanti misteri di microsoft o hai una spiegazione che forse non ho letto nei tuoi post precedenti?

  8. #8
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    Originariamente inviato da benjy
    Scusa la mia ormai nota 'ignoranza', ma perchè solo con questa tabella mi dà il problema ?
    Lo dice l'errore stesso (bisognerebbe riflettere di più sui messaggi di errore):
    Impossibile individuare la riga specificata per l'aggiornamento.
    ciò può essere colpa di cause diverse.
    Non ho molta esperienza su questo errore, dato che IO uso la PK (chiave primaria) univoca.
    Comunque la causa è di solito che esistono più record i cui campi contengono gli stessi valori, quindi il motore del database non sa quale deve essere aggiornato.

    Se tu usassi la PK, questo problema non si verificherebbe mai, perchè in modifica accedi al record riferendoti alla sua PK :

    SELECT <campi> FROM <tabella> WHERE ID=PK


    Potrebbe essere che la tua SELECT invece di caricare un solo record (come ti aspetti) ne carichi più di uno.
    Per avere la certezza di caricarne uno solo dovresti indicare nella WHERE tutti i campi con i rispettivi valori.
    Naturalmente ciò vale fino a che non esistono 2 record identici, nel qual caso ecco che appare il problema.

    Originariamente inviato da benjy
    La tabella dell'anagrafica clienti, anagrafica articoli, testate documenti, che NON hanno neanche loro la chiave primaria, non ho nessun problema.
    E' uno dei tanti misteri di microsoft o hai una spiegazione che forse non ho letto nei tuoi post precedenti?
    Nessun mistero e Microsoft non c'entra nulla.
    E' un argomento che riguarda tutti i database (Oracle, SQL Server, MySQL, PostgreSQL, FirebirdSQL, SQLite, Access, ....)

    La chiave primaria NON è obbligatoria, ma solo per questo fatto non è detto che sia la scelta migliore e/o fattibile in funzione dello scenario.

    Diciamolo chiaramente:
    non impostare una chiave primaria (univoca) è un errore madornale, e denota una non completa conoscienza sui meccanismi necessari alla corretta gestione dei dati in un database.
    Puoi farlo, ma è una scelta da temerari.

    Non averla può solo causare problemi; averla non ha alcuna controindicazione, al contrario fornisce enormi vantaggi.

    Quindi, che senso ha non averla?


  9. #9
    Utente di HTML.it
    Registrato dal
    Aug 2006
    Messaggi
    188
    GRAZIE per i chiarimenti.

    Senti, non di adirare se... persevero , ma io ho il campo doc_riga_id che hai visto nella query che mi 'farebbe' da chiave primaria, in quanto non possono esistere 2 righe n° 10 di uno stesso documento, essendo questo campo formato da anno,serie documentale, numero doc e numero riga.
    Richiesta suggerimenti:
    1. Posso tranquillamente entrare nella struttura dell'archivio e definirla come PK o mi consigli di aggiungere un campo contatore definito come PK?

    2. Posso definirla in fase di programmazione? (visto che sono parecchi DB e varie tabelle da aggiornare con il tuo gradito insegnamento, farei un prg da far girare presso tutti gli utenti)

    Non ho ancora provato, lo farò + tardi. Spero vivamente che il tuo insegnamento sia gradito al database come è stato gradito a me.
    Grazie
    Alla Px.


    P.S.: solo per la cronaca, i record estratti erano 1, solo, probabilmente c'è qualche cosa che però non gli garba e quindi va in errore. .

  10. #10
    Utente di HTML.it L'avatar di gibra
    Registrato dal
    Apr 2008
    residenza
    Italy
    Messaggi
    4,244
    Originariamente inviato da benjy
    GRAZIE per i chiarimenti.

    Senti, non di adirare se... persevero , ma io ho il campo doc_riga_id che hai visto nella query che mi 'farebbe' da chiave primaria, in quanto non possono esistere 2 righe n° 10 di uno stesso documento, essendo questo campo formato da anno,serie documentale, numero doc e numero riga.
    Richiesta suggerimenti:
    1. Posso tranquillamente entrare nella struttura dell'archivio e definirla come PK o mi consigli di aggiungere un campo contatore definito come PK?
    In teoria: Sì. ma devi essere sicuro al 1000 x 1000 che non possano esistere duplicati (ma poi dipende anche da altri fattori).
    In pratica: No. Non ti conviene rischiare perchè una PK deve essere univoca, oltre che indicizzata, quindi devi avere la certezza assoluta che non si creerà mai un record duplicato (cioè con gli stessi valori).

    Per me un campo PK deve essere 'dedicato' solo a quello scopo.
    Una volta assegnato, non deve più essere modificato.
    Se usi valori di altri campi, modificabili, la questione si complica (per non dire peggio).

    Se il tuo programma è multi-utente allora non conviene utilizzare il campo contatore di Access, ma utilizzare un campo contatore gestito direttamente. Come indicato qui:
    HOW TO Implement Multiuser Custom Counters in Jet 4.0 and ADO 2.1
    http://support.microsoft.com/default...b;EN-US;240317

    In teoria quanto indicato da questo articolo è ottimo, e funziona perfettamente.
    In pratica, capirai leggendolo che è ingestibile perchè occorrerebbe creare una tabella supplementare per ogni tabella in cui si intende gestire il contatore.

    Per cui, leggi l'articolo (che fa sempre bene) ma poi vai a scaricarti il mio progetto Prova Login versione 2 qui:
    http://nuke.vbcorner.net/Progetti/VB...3/Default.aspx

    in cui ho modificato il modulo modMultiUserCounter.bas in modo che tu devi semplicemente creare solo una tabella dei Contatori (senza record), che sarà usata per tutte le tabelle.


    Originariamente inviato da benjy
    2. Posso definirla in fase di programmazione? (visto che sono parecchi DB e varie tabelle da aggiornare con il tuo gradito insegnamento, farei un prg da far girare presso tutti gli utenti)
    Con il mio progetto farai ancora meglio, perchè nel modulo indicato sopra ho modificato l'acquisizione del contatore CUSTOM dalla tabella Contatori anche per le tabelle in cui non era previsto dall'inizio.

    Logicamente tu dovrai prima 'preparare' le tabelle.
    Se hai modo di intervenire direttamente sul database usando MSAccess è molto semplice:
    1 - Apri la tabella in struttura
    2 - Aggiungi il campo ID e lo imposti momentaneamente sul tipo Contatore + Chiave primaria.
    3 - Salvi la tabella (MSAccess ti numera tutti i record atuomaticamente)
    4 - Riapri la tabella e modifichi il tipo da Contatore a Numerico.

    Se invece devi farlo programmaticamente allora è un po' più complesso:
    1 - aggiungi il campo numerico chiamandolo ID<NomeCampo> (es. IDArticolo per la tabella Articoli)
    2 - valorizzi progressivamente da 1 a <n> (il numero di record esistenti)
    3 - imposti il campo come su Indicizzato, duplicati non ammessi.


    Originariamente inviato da benjy
    Non ho ancora provato, lo farò + tardi. Spero vivamente che il tuo insegnamento sia gradito al database come è stato gradito a me.
    Vi tranquillo, io ho realizzato moltissimi programmi in multi-utenza anche gestendo la concorrenza con 12-15 utenti.
    In questo modo non ho mai, dico mai (!), avuto problemi di sorta, database corrotto, o altro.

    Il mio progetto che ti ho segnalato include tutte le caratteristiche più importanti.


    Originariamente inviato da benjy
    P.S.: solo per la cronaca, i record estratti erano 1, solo, probabilmente c'è qualche cosa che però non gli garba e quindi va in errore. .
    La questione è un po' più articolata di come te l'ho spiegata io (siamo su un forum e non si possono scrivere fiumi di parole in un post pensando di spiegare e capire tutto; in genere queste cose sono spiegati nei libri oltre che frutto di esperienza vissuta sul campo), ma davvero non ne vale la pena di essere sempre a rischio con la paura che si ripresenti questa situazione solo perchè non si vuole usare una PK.
    Comunque mi piacerebbe analizzare la tua tabella...


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.