Archivi Blog

#47: VB.NET – ADO.NET 2.0 – Supporto a Vista 64 bit e Access 2007

Prendendo spunto da una discussione nel forum dedicato a VB & .NET (http://www.visual-basic.it/forum/thread.asp?m=163649) della Community Visual Basic Tips & Tricks (www.visual-basic.it), ma anche da un mio problema personale proprio su questo argomento, ho pensato che fosse opportuno fissare un paio di appunti e di precisazioni, in particolare sull’uso del Provider JET 4.0 per l’accesso ai database in formato Access 2007 e sul problema del sistema operativo Windows Vista a 64 bit.

Partiamo dal caso dei 64 bit. Come molti sapranno, Vista è distribuito in due edizioni: a 32 bit, che è la piattaforma che molti di noi sono abituati ad utilizzare da molto tempo, e a 64 bit. Prossimamente, le nuove versioni di Windows arriveranno esclusivamente a 64 bit e quindi ci dobbiamo abituare a convivere con questa nuova piattaforma, con le sue particolarità.

Il problema deriva dal fatto che Windows Vista a 64 bit non supporta JET 4.0, in quanto questo provider dati è fornito solo a 32 bit.

Le alternative per risolvere questo problema sono sostanzialmente due:

  • evitare di utilizzare Access e orientarsi direttamente all’uso di SQL Server Express, Compact o edizioni superiori (consigliato!);
  • compilare il progetto Visual Basic 2008 o Visual C# 2008 con il solo supporto per la piattaforma x86 (cioè a 32 bit).

Per questa seconda possibilità, dobbiamo eseguire i seguenti passi:

  1. fare click con il pulsante destro del mouse sul nome del progetto e scegliere “Proprietà”;
  2. passare alla scheda “Compilazione”;
  3. fare click sul pulsante “Opzioni di compilazione avanzate”;
  4. nella combo “CPU di destinazione” selezionare “x86”, anziché “AnyCPU”.

A questo punto potremo eseguire l’applicazione anche su Vista a 64 bit, tenendo però conto che la nostra applicazione non sarà compilata a 64 bit ma bensì a 32 bit. Questo potrebbe comportare qualche problema nel futuro, se Microsoft deciderà prima o poi di chiudere il supporto ai 32 bit sui sistemi operativi a 64 bit.

Vediamo ora come si utilizza il provider JET 4.0 per Access: in particolare le stringhe di connessione ai database Access cambiano a seconda che utilizziamo Access 2003 o Access 2007:

' Access 2003:
Dim stringaconn As String = _
    "Provider=Microsoft.JET.OLEDB.4.0;Data Source=" & _
    "c:\test\prova2.mdb"

' Access 2007:
Dim stringaconn As String = _
    "Provider=Microsoft.ACE.OLEDB.12.0;" & _
    "Data Source=c:\test\prova2.accdb;" & _
    "Persist Security Info=False;"

Per maggiori dettagli sulle stringhe di connessione di ciascun provider dati (anche non-Access), date un’occhiata al sito www.connectionstrings.com.

Scriviamo quindi il programma finale per inserire un record in una tabella Access (2003 o 2007):

  1. creiamo un nuovo progetto in Visual Basic 2008;
  2. nel form predefinito aggiungiamo due TextBox di nome txtCognome e txtNome, nonché un pulsante per eseguire il frammento di codice;
  3. inserire il seguente codice a livello di form (di nome Form1):
Imports System.Data.OleDb

Public Class Form1
   Private Sub cmdInserisci_Click(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles cmdInserisci.Click

      ' Access 2003:
      'Dim stringaconn As String = _
      '    "Provider=Microsoft.JET.OLEDB.4.0;Data Source=" & _
      '    "c:\test\prova2.mdb"

      ' Access 2007:
      Dim stringaconn As String = _
         "Provider=Microsoft.ACE.OLEDB.12.0;" & _
         "Data Source=c:\test\prova2.accdb;" & _
         "Persist Security Info=False;"

      Dim objconn As New OleDbConnection(stringaconn)
      objconn.Open()
      Dim stringasql As String = _
         "Insert into prova2(Cognome,Nome) " & _
         "values(@cognome, @nome)"
      Dim objcomm As New OleDbCommand(stringasql, objconn)
      objconn = New OleDbConnection(stringaconn)
      objconn.Open()
      objcomm = New OleDbCommand(stringasql, objconn)
      objcomm.Parameters.Add(New OleDbParameter("@cognome", _
         Me.txtCognome.Text))
      objcomm.Parameters.Add(New OleDbParameter("@nome", _
         Me.txtNome.Text))
      Try
         Dim righeAggiornate As Integer = objcomm.ExecuteNonQuery
         If righeAggiornate = 1 Then MessageBox.Show("tutto bene")
      Catch ex As Exception
         MessageBox.Show(ex.Message & _
            Environment.NewLine & ex.StackTrace, "Errore")
      Finally
         objconn.Close()
         Me.txtCognome.Text = ""
         Me.txtNome.Text = ""
         Me.txtCognome.Focus()
      End Try
   End Sub
End Class

Naturalmente, per utilizzare alternativamente Access 2003 o Access 2007, è sufficiente commentare/decommentare la definizione della stringa di connessione opportuna.

Annunci

#45: ADO.NET Leggere la chiave del record appena inserito in SQL Server

Uno dei problemi che più frequentemente mi vengono posti riguarda la possibilità di inserire un nuovo record in una tabella e di conoscere il valore assegnato dal DBMS al campo auto incrementante.

Questo problema è solitamente risolto, peraltro in modo brillante ed elegante, con una specifica stored procedure (SP) di SQL Server. Qualcuno, però, chiede come si può fare direttamente da codice, senza “scomodare” una stored procedure.

Ad un primo esame, non abbiamo la possibilità di inserire il record e subito dopo leggere il valore del campo IDENTITY, perché nel frattempo, tra la nostra scrittura del record e la nostra lettura della chiave, qualche altro utente potrebbe aver inserito un nuovo record.

Queste due operazioni, invece, devono essere fatte in un unico blocco, cioè devono essere eseguite in un’unica transazione (principio di “atomicità” della transazione).

A questo proposito c’è una particolarità di SQL Server che possiamo utilizzare per risolvere questo problema: in T-SQL possono essere eseguite più istruzioni in sequenza, senza soluzione di continuità, semplicemente separando ciascuna istruzione con un punto e virgola (;).

In questo modo le singole istruzioni saranno eseguite una dopo l’altra senza interrompere la transazione e restituendo, così, il corretto valore della colonna IDENTITY.

Un esempio di codice di questa tecnica è il seguente:

      Dim cn As System.Data.SqlClient.SqlConnection
      Dim cnStr = "Data Source = HP\SQL2008EXPRESS;" & _
         "Initial Catalog=NOMEDATABASE;" & _
         "Password=PIPPO;" & _
         "User ID=sa;" & _
         "Persist Security Info=True"
      cn = New System.Data.SqlClient.SqlConnection(cnStr)
      cn.Open()
      Dim cmd As New System.Data.SqlClient.SqlCommand( _
         "SET NOCOUNT ON; INSERT INTO Tabella (ANAnome) " & _
         "VALUES ('De Ghetto Mario'); " & _
         "SELECT SCOPE_IDENTITY() AS ANAID;", cn)
      Dim risultato = cmd.ExecuteScalar()
      MessageBox.Show("Il nuovo ID inserito è " & risultato)
      cn.Close()
      cn = Nothing

Attenzione a impostare correttamente i parametri della stringa di connessione (nome dell’istanza, nome del database, utente e password), altrimenti non potrete collegarvi correttamente alla fonte dati.

[VB.NET] Salvare la stringa di connessione al database

In alcuni articoli che ho pubblicato in questo blog ho spiegato come sia possibile utilizzare una stringa per connettersi a un database e come sia possibile e doveroso salvarla in un file di configurazione dell’applicazione.

Qualche lettore mi ha chiesto come sia possibile modificare a runtime la stringa di connessione memorizzata nel file di configurazione, visto che con My.Settings non è possibile farlo, dato che è a sola lettura.

Cercando su CodeProject ho trovato questo articolo interessante che risolve proprio questo problema: “How to persist changes to My.Settings.ConnectionStrings“.

Le tecniche illustrate non sono particolarmente complesse e quindi possono essere agevolmente utilizzate da chiunque, senza particolari problemi.

Alla fine dell’articolo, l’autore si raccomanda di verificare che nelle proprietà dell’applicazione sia impostata la proprietà “Salva My.Settings alla chiusura“.

[ADO.NET 2.0] Accesso dati con VB 2005

Un iscritto a VB T&T (Antonio1981) ha segnalato il seguente articolo che tratta l’accesso ai dati ad un database in Access con Visual Basic 2005 e ADO.NET 2.0: http://www.ilsoftware.it/articoli.asp?ID=3219&pag=0.

L’articolo spiega in modo abbastanza dettagliato le operazioni da fare per:
– creare un nuovo progetto
– effettuare una connessione con la procedura “Configurazione guidata origine dati”
– creare un DataSet
– visualizzare dei dati
– utilizzare il “generatore di query”
– visualizzare i dati con “DataGridView”
– creare e utilizzare query SQL con parametri.

Nella pagina segnalata c’è inoltre un link (con l’icona di una stampante) che apre l’articolo in una forma più comodamente stampabile.

#8 Leggere un singolo valore con una query

In certe occasioni è necessario leggere un singolo valore da una tabella o comunque ottenere un singolo valore calcolato da una query.

Prima di vedere in pratica questa semplice tecnica, sono opportune due precisazioni:

  1.  bisogna importare il namespace Imports System.Data.Oledb
  2.  per quanto riguarda le tecniche di connessione ad un database si faccia riferimento al mio articolo su ADO.NET 2.0.

Ecco finalmente il codice:

     Dim stringaConnessione As String = "una stringa di connessione valida" 
     ' apertura connessione 
     Dim Cn As New Data.OleDb.OleDbConnection(stringaConnessione) 
     Cn.Open() 
     ' preparazione ed esecuzione della richiesta 
     Dim SQL As String = "SELECT CodiceFiscale FROM Anagrafica " & _ 
         "WHERE IDcliente = 'PK425';" 
     Dim comando As New Data.OleDb.OleDbCommand(Sql, Cn) 
     Dim ID As Integer = comando.ExecuteScalar() 
     ' chiusura connessione 
     Cn.Close()