Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Differenza tra INSERT e Addnew..

78 views
Skip to first unread message

Antonio Passaro

unread,
May 19, 1999, 3:00:00 AM5/19/99
to

Ragazzi, io per memorizzare record uso sempre la INSERT ....e... la
Conn.Execute.

Ho visto alcuni esempi in cui per lo stesso motivo viene usata la
...addnew.

Qual'e' la differenza ? Quali sono i vantaggi ad utilizzare il SQL
piuttosto
che lo statement : addnew ?

Come si fa' a lockare un record in fase di modifica ?

Grazie per l'aiuto.

Antonio Passaro

a.pa...@ba.dada.it
antonio...@hotmail.com

--
Posted from mailbari.olivettiricerca.it [193.76.87.205]
via Mailgate.ORG Server - http://www.mailgate.org

Stefano Valsecchi

unread,
May 19, 1999, 3:00:00 AM5/19/99
to

Antonio Passaro wrote in message <3742A8...@NSPolivettiricerca.it>...


>
>Ragazzi, io per memorizzare record uso sempre la INSERT ....e... la
>Conn.Execute.
>Ho visto alcuni esempi in cui per lo stesso motivo viene usata la
>...addnew.
>Qual'e' la differenza ? Quali sono i vantaggi ad utilizzare il SQL
>piuttosto che lo statement : addnew ?


Ti rispondo piu' per esperienza personale che per cognizione di causa

Il vantaggio principale dell'SQL e' la compatibilita' con un numero maggiore
di basi di dati: mi e' capitato di incontrare alcuni provider ODBC che non
supportano il metodo AddNew, come ad esempio il provider per Oracle scritto
dalla Oracle stessa. (Per fortuna Microsoft ne ha scritto uno identico che
pero' supporta questi metodi). La INSERT sql, al contrario e' supportata da
tutti i provider che mi e' capitato di incontrare.

Vantaggi della AddNew:
- Maggior facilita' d'uso: non richiede di imparare l'SQL, ma usa la
sintassi vbscript
- Lavori direttamente con i tipi di dati corretti e non hai il problema di
doverli convertire in stringa per metterli nell'istruzione INSERT. Questo
non sarebbe tanto un problema se alcuni formati non fossero ambigui: ad es.
le date vanno in formato inglese o italiano?


Se qualcuno sa integrare con altri vantaggi e svantaggi, ben venga!

>Come si fa' a lockare un record in fase di modifica ?

Con la INSERT dovrebbe pensarci il database in automatico
Con la addNew lo specifichi al momento dell'apertura del recordset
impostando il quarto parametro della Open


Ciao

stefano

Antonio Passaro

unread,
May 24, 1999, 3:00:00 AM5/24/99
to

Stefano, grazie per la risposta...

A proposito della seguente:

> >Come si fa' a lockare un record in fase di modifica ?
>
> Con la INSERT dovrebbe pensarci il database in automatico
> Con la addNew lo specifichi al momento dell'apertura del recordset
> impostando il quarto parametro della Open
>

cio' vale anche quando faccio una UPDATE di un record ?

Altro quesito:

Cosa succede se diversi utenti registrano ordini contemporaneamente ?
(su Internet)
Voglio dire: che memorizzano un record "testata ordini", poi hanno
la necessita di recuperare L'ID (contatore) di quell'ordine per
poi memorizzare i "righi ordini" (che hanno bisogno dell'ID ordine).

Non si rischia il mescolamento di righi ordini su ordini diversi?

Grazie ancora

Antonio Passaro

Stefano Valsecchi

unread,
May 25, 1999, 3:00:00 AM5/25/99
to

Antonio Passaro wrote in message <3743BC...@NSPolivettiricerca.it>...


>> Con la INSERT dovrebbe pensarci il database in automatico
>> Con la addNew lo specifichi al momento dell'apertura del recordset
>> impostando il quarto parametro della Open
>>
>cio' vale anche quando faccio una UPDATE di un record ?


Penso proprio di si'


>Altro quesito:
>
>Cosa succede se diversi utenti registrano ordini contemporaneamente ?
>(su Internet)
>Voglio dire: che memorizzano un record "testata ordini", poi hanno
>la necessita di recuperare L'ID (contatore) di quell'ordine per
>poi memorizzare i "righi ordini" (che hanno bisogno dell'ID ordine).
>
>Non si rischia il mescolamento di righi ordini su ordini diversi?

Questo dipende da come ripeschi l'ID!

Caso 1: solo SQL (INSERT, UPDATE, etc.)

in questo caso immagino che tu faccia una INSERT per memorizzare il record
nella tabella "Testata ordini" e quindi una SELECT sulla stessa tabella per
recuperare l'ID.
Se le condizioni che usi nella SELECT non sono ben specificate, allora c'e'
il rischio di trovare l'ID sbagliato. (Questo comunque e' un problema che
puoi avere anche se non c'e' un'altra INSERT quasi simultanea da parte di un
altro utente).

Caso 2: AddNew e altri metodi simili

In questo caso non ci sono problemi: dopo l'uso del metodo Update, il record
corrente resta quello appena salvato. Quindi se vai subito a leggere l'id
con un'espressione del tipo miorecordset("Id"), ottieni sicuramente quello
giusto.

Ciao

Stefano

Antonio Passaro

unread,
May 27, 1999, 3:00:00 AM5/27/99
to

> [Previous] [Next] [Reply] [Index] [Mailgate.ORG Web Server]

> in questo caso immagino che tu faccia una INSERT per memorizzare il record
> nella tabella "Testata ordini" e quindi una SELECT sulla stessa tabella per
> recuperare l'ID.
> Se le condizioni che usi nella SELECT non sono ben specificate, allora c'e'
> il rischio di trovare l'ID sbagliato.

Scusa Stefano: quali dovrebbero essere le condizioni....

> Caso 2: AddNew e altri metodi simili
>
> In questo caso non ci sono problemi:

Si e' vero ma se uso una fonte ODBC che non supporta questo metodo ?

Grazie per l'aiuto.

Antonio Passaro

Stefano Valsecchi

unread,
May 27, 1999, 3:00:00 AM5/27/99
to

Antonio Passaro wrote in message <374BC3...@NSPolivettiricerca.it>...

>> Caso 1: SQL


>> in questo caso immagino che tu faccia una INSERT per memorizzare il
record
>> nella tabella "Testata ordini" e quindi una SELECT sulla stessa tabella
per
>> recuperare l'ID.
>> Se le condizioni che usi nella SELECT non sono ben specificate, allora
c'e'
>> il rischio di trovare l'ID sbagliato.
>
>Scusa Stefano: quali dovrebbero essere le condizioni....


In questi casi, normalmente, ha uno o piu' campi che identificano
univocamente ciascun record all'interno della tabella (a parte naturalmente
il campo ID che gia' di per se' ha questa funzione). Per essere sicuro di
estrarre il record appena inserito, nelle condizioni (alias nella parte
della SELECT che sta dopo WHERE) devi indicare il valore che hai appena
inserito in questi campi.

Se invece non esiste nessun campo con queste caratteristiche (cioe' esiste
la possibilita' di avere due record perfettamente identici tranne che per il
campo ID), allora il rischio di estrarre un id sbagliato esiste sempre!

Per sapere se hai ottenuto l'id giusto, un metodo puo' essere quello di
contare i record restituiti dalla SELECT: se ce n'e' uno solo, e'
sicuramente corretto.
Come gestire pero' il caso in cui ne ottieni piu' di uno?
Sinceramente penso che questa domanda non abbia risposta.


>> Caso 2: AddNew e altri metodi simili
>>
>> In questo caso non ci sono problemi:
>
>Si e' vero ma se uso una fonte ODBC che non supporta questo metodo ?


Questo e' il grosso problema di AddNew e metodi simili: non sono supportati
da tutti.
Se non e' supportato, non ti resta altro da fare che tornare al caso 1.


Ciao


Stefano

Matro

unread,
Jun 12, 1999, 3:00:00 AM6/12/99
to

On 27 May 1999 11:27:19 +0200, "Stefano Valsecchi" <vals...@txt.it>
wrote:

>In questi casi, normalmente, ha uno o piu' campi che identificano
>univocamente ciascun record all'interno della tabella (a parte naturalmente
>il campo ID che gia' di per se' ha questa funzione). Per essere sicuro di

>Per sapere se hai ottenuto l'id giusto, un metodo puo' essere quello di


>contare i record restituiti dalla SELECT: se ce n'e' uno solo, e'
>sicuramente corretto.

un metodo semplice e piuttosto veloce con un db sul server è quello di
scrivere una stored procedure che restituisce un id univoco; la
procedure rilascia un id e lo marca come "consegnato", quindi, in caso
di transazione eseguita correttamente, si chiama una seconda stored
procedure (o la stessa con un flag attivato) che comunica l'effettivo
utilizzo dell'id in questione. altri metodi lato client (select subito
dopo l'inserimento) possono raggiungere lo stesso risultato ma sono
molto lenti quando il db ha molti record e non ha indici ad hoc per
tali operazioni.

>>> Caso 2: AddNew e altri metodi simili
>>> In questo caso non ci sono problemi:
>>Si e' vero ma se uso una fonte ODBC che non supporta questo metodo ?

rileggere il campo corrente dopo una .Update di ADO purtroppo
raramente da' il risultato voluto; nel caso di connessione a
sqlserver7, per ritornare l'id di un campo identity (il corrispondente
del campo contatore su access) occorre eseguire SELECT @@IDENTITY, ma
via Ado è impossibile dopo una .Update, xchè ado considera la
transazione chiusa (chiude il cursore) e la variabile di sistema
@@IDENTITY si resetta... in soldoni, interrogando il campo definito
come identity subito dopo una .Update otterrete 0.


--------

MATRO

RealPopup, the freeware winpopup replacer
http://members.tripod.com/Matro/realpopup.html

Stefano Valsecchi

unread,
Jun 15, 1999, 3:00:00 AM6/15/99
to

Matro wrote in message <3761b4a7...@194.243.161.66>...


>un metodo semplice e piuttosto veloce con un db sul server è quello di
>scrivere una stored procedure che restituisce un id univoco; la
>procedure rilascia un id e lo marca come "consegnato", quindi, in caso
>di transazione eseguita correttamente, si chiama una seconda stored
>procedure (o la stessa con un flag attivato) che comunica l'effettivo
>utilizzo dell'id in questione. altri metodi lato client (select subito
>dopo l'inserimento) possono raggiungere lo stesso risultato ma sono
>molto lenti quando il db ha molti record e non ha indici ad hoc per
>tali operazioni.


Ok, ma se hai un db access non funziona


>rileggere il campo corrente dopo una .Update di ADO purtroppo
>raramente da' il risultato voluto; nel caso di connessione a
>sqlserver7, per ritornare l'id di un campo identity (il corrispondente
>del campo contatore su access) occorre eseguire SELECT @@IDENTITY, ma
>via Ado è impossibile dopo una .Update, xchè ado considera la
>transazione chiusa (chiude il cursore) e la variabile di sistema
>@@IDENTITY si resetta... in soldoni, interrogando il campo definito
>come identity subito dopo una .Update otterrete 0.


Domando perdono se dico una cavolata, dal momento che non ho mai usato
sqlserver.
Usando access, il seguente codice mette nella variabile mioid il valore del
campo contatore del record appena inserito

miorecordset.AddNew
...
miorecordset.Update

mioid = miorecordset("id")


Dove "id" e' il nome che ho dato al campo contatore al momento della
definizione della tabella.

Stando alla documentazione di ado, questo dovrebbe funzionare anche in
sqlserver, senza ricorrere a @@IDENTITY che si trova gia' nel campo delle
stored procedure.

E' corretto o c'e' qualcosa di sqlserver che non conosco?

Ciao

Stefano


Matro

unread,
Jun 19, 1999, 3:00:00 AM6/19/99
to

On 15 Jun 1999 14:19:20 +0200, "Stefano Valsecchi" <vals...@txt.it>
wrote:

>Domando perdono se dico una cavolata, dal momento che non ho mai usato
>sqlserver.
>Usando access, il seguente codice mette nella variabile mioid il valore del
>campo contatore del record appena inserito

ho scritto qua:

>>via Ado è impossibile dopo una .Update, xchè ado considera la
>>transazione chiusa (chiude il cursore) e la variabile di sistema
>>@@IDENTITY si resetta... in soldoni, interrogando il campo definito
>>come identity subito dopo una .Update otterrete 0.

questo a grandi linee, come altre info posso dirti che sqlserver usa
un altro cursore per determinare @@IDENTITY, mentre ado è stato
disegnato per funzionare con un unico cursore per ogni recordset.

Ad ogni modo, l'ottimo (sottolineo OTTIMO) MSDN ha questo articolo che
ritengo opportuno riportare (chiedo scusa ai non interessati...)


INFO: Identity (AutoIncrement) Columns in ADO or RDS Last reviewed:
November 17, 1998 Article ID: Q195910

The information in this article applies to: ActiveX Data Objects
(ADO), versions 1.0, 1.5, 2.0 Remote Data Service for ADO versions
1.0, 1.1, 1.5, 2.0 SUMMARY How to use identity values in client
cursors is one of the most prevalent issues facing developers who use
ActiveX Data Objects (ADO) or the Remote Data Service (RDS). This
article examines some of the issues you might encounter with identity
columns in MDAC technologies through ADO or RDS 2.0. Microsoft is
currently investigating ways to make this process simpler for future
versions of ADO beyond ADO 2.0. MORE INFORMATION Retrieving the new
auto-numbered fields in a client cursor is rather complex. With ADOs
universal approach to data, this difficult because database systems do
not have a standard way to retrieve this information. Jet handles
this well when it communicates with an Access database because that is
its native database format. Jet also handles this scenario well when
working with a SQL Server database because it uses a server-side
cursor behind the scenes to perform the insertion. (**** MATRO) With
SQL Server, you can run a query of SELECT @@identity to retrieve the
last identity value used on that particular connection. Currently, the
Access ODBC driver and the Access OLE DB provider do not have that
support. Oracle does not have auto- numbered fields. With the ADO
client cursor engine, the new rows are added to the database as a
result of a query that looks like the following: INSERT INTO
MyTable (Field1, ...) VALUES (Value1, ...) There is no two-way
communication. As a result, the auto-numbered field is not in the
Recordset and ADO has no way to retrieve that row from the database in
the Resync method without it. ADO is not able to tell you the
auto-numbered value for the row you just entered. (MATRO*****) Resync
is great for determining why conflicts occur and retrieving
information about a particular row. For example, you might have a
trigger that modifies a field in the row you just updated and you
might want to retrieve that information immediately after performing
your update. Remember that ADO's client cursor engine uses action
queries to update the database and this type of information would not
be returned otherwise. However, in a case where you want to retrieve a
new identity value, Resync is not the answer. It needs some way to
find the current row in the table, which in this case is that identity
value. The only way to create the identity value is to add new rows
to the database manually. You can walk through the Recordset and
determine which rows are pending updates by looking for a Status of
adRecNew. You can open up a new server-side cursor and use the
information from the Recordset. Then you can use the AddNew method on
the server-side cursor, checking the ID field after calling Update. If
you are using Access as your server, this is your only option. SQL
Server has a special query that allows you to retrieve the last auto-
increment value used on that particular connection. The query is as
follows: SELECT @@identity However, it does not solve every
problem. If your insert fires a trigger that inserts a row into
another table that also uses an auto-incrementing field, running this
query after your insert will retrieve the value for the insert that
the trigger performed. Also, this query will return Null after ADO
inserts the row through Update or UpdateBatch because ADO wraps the
insertion in a stored procedure. Once the stored procedure is
finished, this query will not return the value used in that stored
procedure. If you are using SQL Server and you need to retrieve these
values, you have a couple of options available to you beyond the
server-side cursor method described previously. One is to build your
own INSERT INTO query and run the SELECT @@identity query afterwards.
The other option is to call a stored procedure designed to insert the
new row through an INSERT INTO query and return the identity value
through the SELECT @@identity query in the form of an output
parameter. It is not recommended that you try to pass information
back from a middle tier to a client application to an effort to keep
the Recordset on the client fresh enough to perform repeated updates.
While it is possible in some cases, the code that is required to do
this can be cumbersome. In the case of a new row with an identity
field, the identity field is marked as read-only in the Recordset.
Even if your middle-tier component returns the value of the identity
field, you cannot force the information into the Recordset on the
client in an effort to perform updates on that row, unless you want to
pass the new identity value back to the middle tier along with the
changes made to that row. Instead, it is preferable to have the client
request that information again to make changes to it. Alternately,
you do not have to utilize an identity/autonumber column in your
database. You could implement a business object that dispenses
"identity" column information directly to your application. This
dispenser should be free-threaded, in case multiple applications are
using it, and it probably needs to work with clients across a network.
In this case, a Microsoft Transaction Server implementation would work
the best. (c) Microsoft Corporation 1998, All Rights Reserved.
Contributions by David Sceppa, Microsoft Corporation.

0 new messages