none
Stored Procedure abfragen mit ADO.Net RRS feed

  • Frage

  • Guten Tag,

    wie rufe ich eine Stored Procedure mit Parameter auf?

    Die Deklaration lautet:

    PROCEDURE dbo.cboAdressSelektion (@suchbegriff varchar(50))

    Die Prozedur gibt eine SELECT-Abfrage zurück.

    Unter VB6/ADO konnte ich die rst.source auf z.B: "cboAdressSelektion('Ha')" setzen und öffnen.

    Wie geht das mit VB 2010/ADO.NET? Ich erspare mir jetzt mal die Wiedergabe aller Variationen, die ich bereits vergebens versucht hatte. Sie enden beim dr = cmd.ExecuteReader alle mit "falsche Syntax bei 'cboAdressSelektion'".

    Wie macht man das richtig?

    Jochen

    Mittwoch, 8. September 2010 10:37

Antworten

  • Hallo Jochen, Uwe,

    der Sql Client verwendet benannte Parameter, mit dem "?" wird das nichts.

    Exemplarisch als eine Methode, die eine DataTable abfüllt:

      Public Function ZeiterfassungKonkret(ByVal az As String) As DataTable
        Dim table As New DataTable("Zeiterfassung")
        Using connection As New SqlConnection(My.Settings.NorthwindConnectionString)
          connection.Open()
          Using command As New SqlCommand("SELECT * FROM ZeiterfassungKonkret(@Az)", connection)
            ' Parameter erstellen und zuweisen
            command.Parameters.Add("@Az", SqlDbType.VarChar, 50).Value = az
    
            ' DataTable via Adapter erstellen
            Using adapter As New SqlDataAdapter(command)
              adapter.MissingMappingAction = MissingMappingAction.Passthrough
              adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
    
              adapter.Fill(table)
              Return table
            End Using
          End Using
        End Using
      End Function
    
    
    Gruß Elmar

    • Als Antwort vorgeschlagen Uwe RickenMVP Donnerstag, 9. September 2010 07:35
    • Als Antwort markiert Sansibla Donnerstag, 9. September 2010 13:01
    Mittwoch, 8. September 2010 19:17
    Beantworter

Alle Antworten

  • Hallo Jochen,

    Du kannst ein SqlParameter-Objekt anlegen, diesem Wert und Name des Parameters mitgeben, und diesen Parameter dann der Parameters-Liste des SqlCommand-Objekts hinzufügen.

    Der große Vorteil von diesen Objekten ist, dass man sich als Entwickler nicht mehr darum zu kümmern braucht, ob möglicherweise gefährliche Werte in den Parametern stehen (SqlInjection).

    In C# sieht das z.B. so aus:

    // 1. create a command object identifying
     //   the stored procedure
     SqlCommand cmd = new SqlCommand(
     "CustOrderHist", conn);
     // 2. set the command object so it knows
     //  to execute a stored procedure
     cmd.CommandType = CommandType.StoredProcedure;
     // 3. add parameter to command, which
     //  will be passed to the stored procedure
     cmd.Parameters.Add(
     new SqlParameter("@CustomerID", custId));
    

     

    Hoffentlich hilft das,

    viele Grüße,

     

    Roland

     

    • Als Antwort markiert Sansibla Mittwoch, 8. September 2010 11:19
    • Tag als Antwort aufgehoben Sansibla Mittwoch, 8. September 2010 13:52
    Mittwoch, 8. September 2010 11:05
  • danke, es war das CommandType.StoredProcedure!

    j

    Mittwoch, 8. September 2010 11:20
  • Jetzt habe ich mich da doch etwas zu früh gefreut: Bei

    CREATE FUNCTION dbo.ZeiterfassungKonkret (@Az varchar(50))
    RETURNS TABLE AS

    kriege ich es nämlich nicht hin. "CommandType.StoredProcedure" natürlich nicht, CommandType.Text führt zu Fehler wie oben beschrieben.

    Eigentlich müsste es ja auch "CommandType.TableDirect" sein, aber das lässt sich schon nicht zuweisen, denn

    Der Enumerationswert von CommandType, 512, wird vom .Net Framework-SqlClient-Datenprovider nicht unterstützt.
    Parametername: CommandType

    Nochn Tipp?

    Jochen

    Mittwoch, 8. September 2010 14:01
  • Hallo Sansibla,

    dabei handelt es sich um den CommandType Text

    Public Sub CreateSqlCommand()
      Dim command As New SqlCommand()
      command.CommandTimeout = 15
      command.CommandType = CommandType.Text
    End Sub
    

    Uwe Ricken
    Microsoft Certified Database Administrator SQL Server 2005
    db Berater GmbH
    http://www-db-berater.de
    Mittwoch, 8. September 2010 14:25
  • sorry, aber

                cnn = New SqlConnection(NetAdoCnnStr)
                cmd = New SqlCommand("ZeiterfassungKonkret", cnn)
                cmd.CommandType = CommandType.Text
                cmd.CommandTimeout = 15
                cmd.Parameters.Add(New SqlParameter("@Az", Az))
                cnn.Open()
                With cmd.ExecuteReader
                End With

    vermeldet noch immer einen "Syntaxfehler bei ZeiterfassungKonkret"! Und zwar ruckartig - auch bei Timeout 1500 praktisch sofort.

    Ich verwende SQL Server 2005 Express. Näheres zu meiner "ZeiterfassungKonkret" lässt sich übrigens googeln!

    Jochen

    Mittwoch, 8. September 2010 14:58
  • Da machst Du aber einen Denkfehler!
    
    Set cmd = New SqlCommand("SELECT * FROM dbo.ZeiterfassungKonkret(?)", cnn
    With cmd
      .CommandType = CommandType.Text
      .CommandTimeOut = 15
      .Parameters.Add(Ne SqlParameter("@Az", Az)
      .ExecuteReader
    End With
    

     


    Uwe Ricken
    Microsoft Certified Database Administrator SQL Server 2005
    db Berater GmbH
    http://www-db-berater.de
    Mittwoch, 8. September 2010 15:03
  • Hallo Jochen, Uwe,

    der Sql Client verwendet benannte Parameter, mit dem "?" wird das nichts.

    Exemplarisch als eine Methode, die eine DataTable abfüllt:

      Public Function ZeiterfassungKonkret(ByVal az As String) As DataTable
        Dim table As New DataTable("Zeiterfassung")
        Using connection As New SqlConnection(My.Settings.NorthwindConnectionString)
          connection.Open()
          Using command As New SqlCommand("SELECT * FROM ZeiterfassungKonkret(@Az)", connection)
            ' Parameter erstellen und zuweisen
            command.Parameters.Add("@Az", SqlDbType.VarChar, 50).Value = az
    
            ' DataTable via Adapter erstellen
            Using adapter As New SqlDataAdapter(command)
              adapter.MissingMappingAction = MissingMappingAction.Passthrough
              adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
    
              adapter.Fill(table)
              Return table
            End Using
          End Using
        End Using
      End Function
    
    
    Gruß Elmar

    • Als Antwort vorgeschlagen Uwe RickenMVP Donnerstag, 9. September 2010 07:35
    • Als Antwort markiert Sansibla Donnerstag, 9. September 2010 13:01
    Mittwoch, 8. September 2010 19:17
    Beantworter
  • Hallo Jochen, Uwe,

    der Sql Client verwendet benannte Parameter, mit dem "?" wird das nichts.

    Hallo Elmar,

    Du hast natürlich Recht - ich bin noch zu sehr in der klassischen Welt.
    Habe gerade meine ASP.NET Programme noch einmal überprüft. Da verwende ich es genau so, wie Du schreibst.

    Ich sollte mich von den alten Zöpfen trennen ;)


    Uwe Ricken
    Microsoft Certified Database Administrator SQL Server 2005
    db Berater GmbH
    http://www-db-berater.de
    Donnerstag, 9. September 2010 07:34
  • Danke allesamt, mit dem davorgesetzten "SELECT * FROM " funkt es.

    Ich verstehe nicht genug von der Theorie drumrum, aber ist das nicht eigentlich Plan B?

    Egal, Hauptsache es läuft.

    Schöne Grüße aus einem massiv verregneten Hamburg!

    Jochen

    Donnerstag, 9. September 2010 12:53
  • Hallo Jochen,

    nee, dort gilt immer Plan A ;-)
    Eine Tabellenwertfunktion  unterscheidet sich in ihrem Aufruf
    nicht von einer "normalen" Anweisung und so wird
    CommandType .Text (Voreinstellung) verwendet.

    CommandType.StoredProcedure ist beim SQL Server für "richtige"
    Prozeduren (CREATE PROCEDURE) reserviert.

    CommandType.Table wird vom SQL Server nicht unterstützt.
    Es ist für Provider mit ISAM-Zugriff gedacht -
    z. B. Jet/Access oder SQL Server Compact
    (Und ein Überbleibsel aus ADO Classic).

    Gruß Elmar

    Donnerstag, 9. September 2010 13:18
    Beantworter