Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    [VB.Net/Ado] Errore metodo MoveLast e proprietà Recordcount

    Ciao ragazzi

    Il mio problemino è questo:
    ho un recordset di Ado; eseguo l'apertura e ne verifico lo stato, dopodichè se vado a fare il .MoveLast o il .Recordcount mi va' in errore.
    L'errore per il MoveLast è: 'Il set di righe non supporta operazioni di recupero all'indietro.'
    Mentre per il Recordcount mi restituisce -1.
    Il codice originario è questo:
    codice:
    ...
    strSql = "exec sp_fkeys '" + ElencoTabelle(indTab) + "'"
    adoRsSql = adoConn.Execute(strSql)
    
    '   verifica che il recordset sia aperto
    If adoRsSql.State = 1 Then
       If Not adoRsSql.EOF Then
          adoRsSql.MoveLast()
          adoRsSql.MoveFirst()
          PBar_Avanzamento.Maximum = adoRsSql.RecordCount
    ...
    
       End If
    End If
    ho provato a impostare la proprietà Cursortype su Static ma non ha funzionato lo stesso. Così ho scritto l'apertura diversamente e nonostante il cursortype Static l'errore non se ne è andato.
    Ecco la seconda soluzione:
    codice:
    ...
    strSql = "exec sp_fkeys '" + ElencoTabelle(indTab) + "'"
    adoRsSql.Open(strSql, adoConn, ADODB.CursorTypeEnum.adOpenStatic)
    Il database è di SqlServer8 e la stored procedure "sp_fkeys" è di sistema. Restituisce le relazioni per la tabella indicata nel filtro della stringa sql.



    Mi sapete dare qualche spiegazione?




    Grazie a tutti

    lady

    05.08.2005 - by alka
    Auguri all'angelo custode dei moderatori.

  2. #2
    Utente di HTML.it L'avatar di biste
    Registrato dal
    Apr 2001
    Messaggi
    877
    Perché utilizzi ADO liscio con VB.NET? Mi hai rovinato la mattinata...

    In ogni caso il modo più corretto per eseguire la sp in ADO è utilizzare Command (con parametri) + RecordSet.

    Se hai provato i diversi tipi di cursore non saprei dirti la causa precisa in questo caso, posso comunque dirti che MoveLast e MoveFirst sono metodi molto lenti, se ti è possibile evitali modificando le logiche della procedura (e magari utilizza ADO.NET dove ti posso anche essere di maggiore aiuto)
    UGIdotNET
    Microsoft .NET MCAD
    C++, C#, VB6, VB.NET, ASP, ASP.NET
    SQL Server 2000

  3. #3
    Originariamente inviato da biste
    Perché utilizzi ADO liscio con VB.NET? Mi hai rovinato la mattinata...

    In ogni caso il modo più corretto per eseguire la sp in ADO è utilizzare Command (con parametri) + RecordSet.

    Se hai provato i diversi tipi di cursore non saprei dirti la causa precisa in questo caso, posso comunque dirti che MoveLast e MoveFirst sono metodi molto lenti, se ti è possibile evitali modificando le logiche della procedura (e magari utilizza ADO.NET dove ti posso anche essere di maggiore aiuto)
    mi spiace di averti causato tanto dolore

    scherzi a parte, purtroppo qui le cose le vogliono "al volo" e il tempo di studiare non ce l'ho. quindi ho dovuto scrivere su .net ma con la logica del vb6, come è evidente.

    allora seguo il tuo consiglio e tento col Command, sia mai che risolvo

    per Ado.Net... cambia molto?
    perchè se rimane abbastanza simile posso pure tentare... con te come tutor ovvio

    05.08.2005 - by alka
    Auguri all'angelo custode dei moderatori.

  4. #4
    Utente di HTML.it L'avatar di biste
    Registrato dal
    Apr 2001
    Messaggi
    877
    codice:
    Dim conn As New SqlConnection("DATA SOURCE=<server>;INITIAL CATALOG=<database>;UID=<user>;PWD=<password>")
    
    Dim cmd As New SqlCommand("sp_fkeys", conn)
    cmd.CommandType = CommandType.StoredProcedure
    cmd.Parameters.Add("@pktable_name", "<Nome Tabella>")
    
    Dim da As New SqlDataAdapter(cmd)
    Dim dt As New DataTable
    
    da.Fill(dt)
    
    da.Dispose()
    cmd.Dispose()
    conn.Dispose()
    
    Console.WriteLine(dt.Rows.Count) 'Numero di righe ritornate
    For Each row As DataRow In dt.Rows
    'Ciclo le righe
    Next
    dt.Dispose()
    Aggiungi Imports System.Data e Imports System.Data.SqlClient in alto
    UGIdotNET
    Microsoft .NET MCAD
    C++, C#, VB6, VB.NET, ASP, ASP.NET
    SQL Server 2000

  5. #5
    Originariamente inviato da biste
    codice:
    Dim conn As New SqlConnection("DATA SOURCE=<server>;_
    INITIAL CATALOG=<database>;UID=<user>;PWD=<password>")
    
    Dim cmd As New SqlCommand("sp_fkeys", conn)
    cmd.CommandType = CommandType.StoredProcedure
    cmd.Parameters.Add("@pktable_name", "<Nome Tabella>")
    
    Dim da As New SqlDataAdapter(cmd)
    Dim dt As New DataTable
    
    da.Fill(dt)
    
    da.Dispose()
    cmd.Dispose()
    conn.Dispose()
    
    Console.WriteLine(dt.Rows.Count) 'Numero di righe ritornate
    For Each row As DataRow In dt.Rows
    'Ciclo le righe
    Next
    dt.Dispose()
    Aggiungi Imports System.Data e Imports System.Data.SqlClient in alto
    ok.
    allora, visto che il programma non riconosce System.Data e System.Data.SqlClient ho incluso nelle references del progetto la dll System.Data.dll

    senti biste, il codice è pronto per l'esecuzione.
    solo una cosa. sul metodo Add del Command mi esce fuori un warning:
    'Public Function Add(parameterName As String, value As Object) As System.Data.SqlClient.SqlParameter' is obsolete:
    'Add(String parameterName, Object value) has been deprecated.
    Use AddWithValue(String parameterName, Object value).

    ritieni si possa soprassedere?


    grazie mille, sei un angelo

    05.08.2005 - by alka
    Auguri all'angelo custode dei moderatori.

  6. #6
    Utente di HTML.it L'avatar di biste
    Registrato dal
    Apr 2001
    Messaggi
    877
    ok.
    allora, visto che il programma non riconosce System.Data e System.Data.SqlClient ho incluso nelle references del progetto la dll System.Data.dll
    Perfetto

    sul metodo Add del Command mi esce fuori un warning:
    'Public Function Add(parameterName As String, value As Object) As System.Data.SqlClient.SqlParameter' is obsolete:
    'Add(String parameterName, Object value) has been deprecated.
    Use AddWithValue(String parameterName, Object value).

    ritieni si possa soprassedere?
    Ah stai usando VB 2005. Hanno aggiunto appunto questo nuovo metodo per cui quello che ti ho consigliato rimane solo per retrocompatibilità e sarà rimosso nelle prossime versioni.
    Sì ti consiglio di usare AddWithValue.
    UGIdotNET
    Microsoft .NET MCAD
    C++, C#, VB6, VB.NET, ASP, ASP.NET
    SQL Server 2000

  7. #7
    biste, grazie mille il codice gira senza problemi

    ho sostituito il metodo Add con AddWithValue.


    il risultato è questo:

    codice:
    Private Sub sRelazioni(ByRef strFile As String)
    
    Dim strTit As String = ""
    Dim indTab As Integer = 0   
    Dim numRow As Integer = 0
       '
    Dim conn As New SqlConnection("DATA SOURCE='(local)';_
               INITIAL CATALOG='master';UID='sa';PWD=''")
    
       '   ciclo l'array
    For indTab = 0 To UBound(ElencoTabelle) - 1
    
       Dim cmd As New SqlCommand("sp_fkeys", conn)
       cmd.CommandType = CommandType.StoredProcedure
    
       Dim da As New SqlDataAdapter(cmd)
       cmd.Parameters.AddWithValue("@pktable_name", _
                  "'" + ElencoTabelle(indTab) + "'")
    
       Dim dt As New DataTable
       da.Fill(dt)
    
       numRow = dt.Rows.Count 
       If numRow > 0 Then
    
          strTit = ""
          For Each row As DataRow In dt.Rows
    
              'Ciclo le righe
              If strTit <> ElencoTabelle(indTab) Then
                 strTit = "        * " + ElencoTabelle(indTab)
                 strFile = vbCrLf + strTit + vbCrLf
              End If
              strFile = strFile + "                   - " _
                        + row("FK_NAME").Value + ", "
              strFile = strFile + row("PKTABLE_NAME").Value + ", "
              strFile = strFile + row("FKTABLE_NAME").Value + ", "
              strFile = strFile + Trim(row("PKCOLUMN_NAME").Value) _
                        + ", "
              strFile = strFile + Trim(row("FKCOLUMN_NAME").Value) _
                        + vbCrLf
    
          Next
    
       End If
    
       dt.Dispose()
       da.Dispose()
       cmd.Dispose()
    
    Next indTab
    
    conn.Dispose()
    
    End Sub
    si può evitare di dichiarare il command ogni volta che entro nel ciclo?
    io ho provato a metterlo fuori, ma poi si genera questo errore: "arameter '@pktable_name' was supplied multiple times."
    se invece lo lascio nel ciclo va bene.

    che mi dici?


    05.08.2005 - by alka
    Auguri all'angelo custode dei moderatori.

  8. #8
    Utente di HTML.it L'avatar di biste
    Registrato dal
    Apr 2001
    Messaggi
    877
    Rieccomi

    Ho modificato un po' il codice per quello che chiedevi, ora il command viene dichiarato soltanto una volta fuori dal ciclo ed internamente viene soltanto cambiato il valore del parametro.
    Ho poi ottimizzato le concatenazioni delle stringhe utilizzando StringBuilder come è sempre consigliabile fare.
    Se ci sono problemi o qualcosa che non ti è chiaro chiedimi pure.

    codice:
        Private Sub sRelazioni(ByRef strFile As String)
    
            Dim strTit As New Text.StringBuilder
            Dim fileSb As New Text.StringBuilder(strFile)
            Dim indTab As Integer = 0
            Dim numRow As Integer = 0
            '
            Dim conn As New SqlConnection("DATA SOURCE='(local)';INITIAL CATALOG='master';UID='sa';PWD=''")
            Dim cmd As New SqlCommand("sp_fkeys", conn)
            cmd.CommandType = CommandType.StoredProcedure
            cmd.Parameters.Add("@pktable_name", SqlDbType.VarChar)
            Dim da As New SqlDataAdapter(cmd)
    
            '   ciclo l'array
            For indTab = 0 To ElencoTabelle.Length - 1
                cmd.Parameters("@pktable_name").Value = ElencoTabelle(indTab)
    
                Dim dt As New DataTable
                da.Fill(dt)
    
                numRow = dt.Rows.Count
                If numRow > 0 Then
    
                    strTit.Remove(0, strTit.Length)
    
                    For Each row As DataRow In dt.Rows
    
                        'Ciclo le righe
                        If strTit.ToString() <> ElencoTabelle(indTab) Then
                            strTit.Append("        * ")
                            strTit.Append(ElencoTabelle(indTab))
                            fileSb.AppendFormat("{0}{1}{0}", Environment.NewLine, strTit)
                        End If
                        fileSb.AppendFormat("                   - {0}, ", row("FK_NAME").Value.ToString())
                        fileSb.AppendFormat("{0}, ", row("PKTABLE_NAME").Value.ToString())
                        fileSb.AppendFormat("{0}, ", row("FKTABLE_NAME").Value.ToString())
                        fileSb.AppendFormat("{0}, ", row("PKCOLUMN_NAME").Value.ToString())
                        fileSb.AppendFormat("{0}, {1}", row("FKCOLUMN_NAME").Value.ToString(), Environment.NewLine)
                    Next
                End If
                dt.Dispose()
    
            Next
            da.Dispose()
            cmd.Dispose()
            conn.Dispose()
            strFile = fileSb.ToString()
        End Sub
    UGIdotNET
    Microsoft .NET MCAD
    C++, C#, VB6, VB.NET, ASP, ASP.NET
    SQL Server 2000

  9. #9
    Originariamente inviato da biste
    Rieccomi

    Ho modificato un po' il codice per quello che chiedevi, ora il command viene dichiarato soltanto una volta fuori dal ciclo ed internamente viene soltanto cambiato il valore del parametro.
    Ho poi ottimizzato le concatenazioni delle stringhe utilizzando StringBuilder come è sempre consigliabile fare.
    Se ci sono problemi o qualcosa che non ti è chiaro chiedimi pure.

    codice:
        Private Sub sRelazioni(ByRef strFile As String)
    ....
        End Sub
    Ciao biste
    Intanto ti ringrazio per l'aiuto

    Dunque, durante l'esecuzione mi genera errore sulla riga in rosso:
    codice:
    For indTab = 0 To ElencoTabelle.Length - 1
        cmd.Parameters("@pktable_name").Value = ElencoTabelle(indTab)
        Dim dt As New DataTable
        da.Fill(dt)
    
    ....
    La description dell'errore è questa: "The primary or foreign key table name must be given."

    Succede che la Lenght dell'array mi restituisce un numero in più rispetto all'Ubound e di conseguenza poi il valore che va a cercare è Nothing:
    codice:
    ?UBound(ElencoTabelle)
    82
    ?ElencoTabelle.Length
    83
    mettere un -2 non mi sembra una soluzione valida. tu sai il motivo di questa differenza?


    un bacio

    05.08.2005 - by alka
    Auguri all'angelo custode dei moderatori.

  10. #10
    biste, un'altra cosa.

    codice:
    strFile = fileSb.ToString()
    la stringa è vuota.



    ************

    EDIT:
    i'm sorry!
    non mi ero accorta che non ci sono relazioni impostate nel db

    05.08.2005 - by alka
    Auguri all'angelo custode dei moderatori.

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.