1

I eine einfache gespeicherte Prozedur, die den type_id (int) als Ausgabeparameter zurück unter Verwendung des type_name (VARCHAR (100)) als Eingangsparameter. Wenn ich die gespeicherte Prozedur in SqlServer ausführe, funktioniert es einwandfrei und gibt das entsprechende type_id zurück.ExecuteScalar gibt nichts aus gespeicherten Prozedur

CREATE PROCEDURE [dbo].[intake_types_select_by_type_name] 
    @type_name varchar(100), 
    @type_id integer OUTPUT 
AS 
BEGIN 
    SET NOCOUNT ON; 
    SET XACT_ABORT ON 

    SELECT @type_id = type_id 
    FROM intake_types 
    WHERE type_name = @type_name 
END 

Allerdings, wenn ich die gespeicherte Prozedur aus einer Funktion in Visual Studio rufen Sie den Parameter @type_id kehrt Nichts.

Ich habe stundenlang im Internet nach einer Lösung gesucht und nichts gefunden, was hilft. Ich habe eine ähnliche gespeicherte Prozedur und Funktion in einem anderen Projekt, das die gleiche Codierung und Logik verwendet und es funktioniert gut (jedoch gibt es varchar als OUTPUT-Parameter). Ich habe diese beiden Projekte verglichen, um zu sehen, ob mir etwas Einfaches fehlt, aber keine Freude.

+2

Haben Sie versucht, 'Dim result = sp.ExecuteScalar()'? – Fabio

+0

Jedes Beispiel, das ich gesehen habe, macht etwas wie 'TypeID = (Int32) sp.ExecuteScalar()'. Bist du sicher, dass du in deinem anderen Projekt einfach einen nackten Aufruf an 'sp.ExecuteScalar()' machst? –

+0

Entfernen Sie '.Item (" @ type_id "). Direction = ParameterDirection.Output', ändern Sie' .Add ("@ type_id", SqlDbType.Int) 'in' .Add ("@ type_id", SqlDbType.Int, ParameterDirection. Output) ', und ändern Sie' ExecuteScalar' in 'ExecuteNonQuery()'. Ich weiß nicht, ob es dein Problem lösen wird, aber es ist einen Versuch wert. –

Antwort

1

Sie sollten wirklich verwenden Option Strict On und korrigieren Sie die Probleme, die darauf hinweist. Momentan werden implizite Konvertierungen zwischen Datentypen durchgeführt, wodurch Ihr Code viel langsamer und möglicherweise fehleranfällig wird.

Ich schlage vor, die folgenden:

CREATE PROCEDURE [dbo].[intake_types_select_by_type_name] 
    @type_name varchar(100) 
AS 
BEGIN 
    SET NOCOUNT ON; 
    SET XACT_ABORT ON; 

    SELECT type_id 
    FROM intake_types 
    WHERE type_name = @type_name 
END 

und die Funktion zu nennen:

Option Strict On 
' ....' 

Public Shared Function sp_intake_types_select_by_type_name(ByVal conn As DBConnection, ByVal caseName As String) As Integer 
    Dim sp As SqlCommand = conn.GetStoredProcedure("intake_types_select_by_type_name") 
    sp.Parameters.Add("@type_name", SqlDbType.VarChar, 100).Value = caseName 

    Dim result As Object = sp.ExecuteScalar() 

    If result Is Nothing Then 
     Return -1 ' check for -1 in the calling code ' 
    Else 
     Return CInt(result) 
    End If 

End Function 

Es ist fast immer eine gute Idee, um die Größe der SQL-Parameter angeben, so dass die Datenbank neu zu können - Verwenden Sie den Ausführungsplan, anstatt für jede Länge der Parameter einen neuen Ausführungsplan zu erstellen.

Bitte beachten Sie, dass es in der Regel eine schlechte Idee ist, eine SQL-Verbindung für alles zu verwenden: Sie sollten die Verbindung verwenden und sie dann entsorgen, sobald sie sofort verwendet wird. Es scheint zunächst eine gute Idee zu sein, aber es kämpft gegen die Art und Weise, wie es entworfen wurde (connection pooling kümmert sich um das schnelle Wiederöffnen von Verbindungen).

Ref: Execute Scalar to trap error in case of no records returned.

+0

Andrew, vielen Dank für die Tipps, hervorragende Erklärungen, _und_ eine funktionierende Lösung. Die ** Option Strict On ** hat zwei weitere implizite Konvertierungen aufgedeckt, die ich behoben habe. Ich werde als nächstes SQL-Verbindung verwenden/disponieren, anstatt für alles eine SQL-Verbindung zu verwenden. Ich schätze deine Zeit und deinen großartigen Input sehr! –

+0

@MichaelCallas Gern geschehen :) Ich empfehle dringend, Option Strict On als Standard für neue Projekte zu setzen, falls Sie dies noch nicht getan haben. Bezüglich einer anderen Antwort in der Post, mit der ich verlinkt bin, habe ich das VB-Snippet tatsächlich gegen eine echte Datenbank getestet, um zu bestätigen, dass "Is Nothing" funktioniert und "Is DbNull.Value" falsche Ergebnisse liefert, nur für den Fall, dass Sie weiterlesen. –

+0

Andrew, ich habe die Standardeinstellung für neue Projekte, aber dies ist ein geerbtes Projekt, also bin ich froh, dass du darauf hingewiesen hast. Ich lese auch den Link in Ihrem Post, also vielen Dank für das Follow-up. Gute Sachen zu wissen. –

Verwandte Themen