10 Stimmen

Was ist für das Argument Größe in Database.AddOutParameter zu verwenden, wenn eine Zeichenfolge zurückgegeben wird?

Ich erhalte eine Zeichenfolge als Ausgabeparameter, und müssen wissen, was für das Argument Größe im Aufruf von AddOutParameter festgelegt.

Ich weiß, ich könnte einfach eine große Zahl verwenden, wie int.MaxValue, aber ich möchte die besten Praktiken kennen.

In SQL Server ist die Spalte eigentlich ein eindeutiger Bezeichnertyp. Die ausgeführte T-SQL-Anweisung fügt einen Datensatz ein und setzt dann einige Ausgabevariablen auf die ID und GUID der neu eingefügten Datensätze. Dies ist der eigentliche Code, den ich verwende, allerdings mit geänderten Variablennamen.

database.AddOutParameter(cmd, "@someInt", DbType.Int32, 0);
database.AddOutParameter(cmd, "@someString", DbType.String, 0);

database.ExecuteNonQuery(cmd);

someInt = (int)database.GetParameterValue(cmd, "@someInt");
someString = database.GetParameterValue(cmd, "@someString").ToString();

Bei der Ausführung erhalte ich den folgenden Fehler...

System.InvalidOperationException: String[2]: Die Eigenschaft Größe hat eine ungültige Größe von 0.

Daher ist es für mich offensichtlich, dass man nicht einfach eine Größe von 0 mit einem String-Ausgabeparameter verwenden kann. Sie können das mit einem Int32-Ausgabeparameter tun, aber ich denke, eine Zeichenfolge braucht eine gültige Größe. Was ist also die beste Praxis für die Einstellung der Größe? Kann es einfach eine riesige Größe ohne Auswirkungen auf die Leistung überhaupt sein? Kann ich es einfach auf int.MaxValue oder etwas festlegen? Gibt es eine Konstante, die hier verwendet werden kann; (sah keine String.MaxValue - Sie können wahrscheinlich sagen, ich bin neu in C#, mit einem Java-Hintergrund).

Sollte ich herausfinden, was die maximale Größe einer eindeutigen Bezeichnerspalte ist und die Größe auf diese festlegen? Wie sieht es aus, wenn ich das Gleiche für eine VARCHAR- oder NVARCHAR-Spalte tue?

Ich wünschte, das Framework würde das einfach für mich tun; ich möchte nicht für jeden String, den ich als Ausgabe erhalte, eine Größe angeben. Hat jemand irgendwelche Vorschläge hier für beste Praxis?

Ich habe die nachstehenden Beiträge sowie die MSDN-Dokumentation gelesen, aber ich habe noch keine Antwort auf diese Frage gefunden, die sich am besten eignet.

AddOutParameter - nicht-magische Zahl, um die Länge von DBType.Int32 zu ermitteln

Lesen von VARBINARY(MAX) aus SQL Server in C#

17voto

Conrad Frix Punkte 50686

Wie wir herausgefunden haben, haben Sie den falschen Typ für einen UniqueIdentifier verwendet. Sie sollten verwenden DbType.Guid statt einer Zeichenkette, aber Sie haben in den Kommentaren andere Fragen aufgeworfen, die ich nicht in einem Kommentar beantworten konnte und bei denen ich mir nicht sicher war, so dass ich sie testen musste.

Sie sind

  • Welche Größe sollten Sie für die verschiedenen String-Ausgabeparameter festlegen?
  • Spielt es eine Rolle, ob es ein Nvarchar oder varchar ist?
  • Was passiert, wenn man sie zu groß oder zu klein macht?

Ich begann mit der Verwendung von SqlCommandBuilder.DeriveParameters um herauszufinden, was ADO.NET und SQL Server denken, dass es sein sollte, und führte dann die Stored Procedure aus, um zu sehen, was unsere Rückgabewerte waren.

Sql Type     | DbType                | Size | Returned string.Length()
----------------------------------------------------------------
Varchar(10)  | AnsiString            | 10   | 9
Char(10)     | AnsiStringFixedLength | 10   | 10
Nvarchar(10  | String                | 10   | 9
Varchar(max) | AnsiString            | -1   | 20,480 
NVarchar(max)| String                | -1   | 20,480

Wie erwartet stimmten die abgeleiteten Größen mit dem Längenfeld für alle Zeichentypen überein, mit Ausnahme von max und den Rückgabewerten, die die erwartete Länge hatten. Bei der Betrachtung der max-Typen und DbTypes ergaben sich jedoch einige neue Fragen zu den ersten drei.

  • Was hat es mit dem Typ AnsiString auf sich, und wenn wir ihn stattdessen auf DbType.String setzen, hat das Auswirkungen auf die Ausgabe, wenn wir die gleiche Größe beibehalten? Antwort: Nein, wahrscheinlich weil .NET-Strings Unicode sind.

  • Ist die Erhöhung der Paramater.Size einen der Nicht-Max-Werte beeinflussen? Antwort: Ja, aber nur char(10). Es erhöht die Ausgabegröße durch Hinzufügen von Leerzeichen.

  • Ist die Verringerung des Paramater.Size einen der Nicht-Max-Werte beeinflussen? Ja, die Rückgabewerte werden abgeschnitten.

  • Ist eine Größe von -1 magisch? Antwort: Ja, wenn Sie die Größe auf -1 setzen, werden die Werte so zurückgegeben, als ob Sie sie korrekt eingestellt hätten.

Testcode .NET 4.0 SQL Server 2008

SQL-Code

CREATE PROCEDURE SomeOutput( 
@tenVC varchar(10)  output,
@tenC char(10) output,
@tenNVC nvarchar(10) output,
@maxVC varchar(max) output,
@maxNVC nvarchar(max) output,
@Indentifier uniqueidentifier output)
AS 

SELECT @tenC = '123456789',
       @tenVC = '123456789',
       @tenNVC = '123456789',
       @Indentifier = NEWID(),
       @maxVC = '',
       @maxNVC = ''

SELECT 
       @maxVC = @maxVC + '1234567890',
       @maxNVC = @maxNVC + '1234567890'
FROM
        master..spt_values 
WHERE
      type= 'P'    

C#-Code

static void Main(string[] args)
{

    using (SqlConnection cnn = new SqlConnection("Server=.;Database=Test;Trusted_Connection=True;"))
    {
        SqlCommand cmd = new SqlCommand("SomeOutput", cnn);
        cmd.CommandType = CommandType.StoredProcedure;
        cnn.Open();
        SqlCommandBuilder.DeriveParameters(cmd);

        Printparams(cmd.Parameters, "Derived");

        foreach (SqlParameter param in cmd.Parameters)
        {
            //By default output parameters are InputOutput
            //This will cause problems if the value is both null
            if (param.Direction == ParameterDirection.InputOutput )
                param.Direction = ParameterDirection.Output;

        }

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters ,"Executed");

        cmd.Parameters["@tenVC"].DbType = DbType.String;
        cmd.Parameters["@tenNVC"].DbType = DbType.AnsiString;

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "DbType change");

        foreach (SqlParameter param in cmd.Parameters)
        {
            if (param.DbType != DbType.Int32
                && param.DbType != DbType.Guid
                && param.Size != -1)
            {
                param.Size = param.Size * 2;

            }
        }

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "Mangeled sizes up");

        foreach (SqlParameter param in cmd.Parameters)
        {
            if (param.DbType != DbType.Int32 
                && param.DbType != DbType.Guid
                && param.Size != -1)
            {
                param.Size = param.Size / 4;

            }
        }

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "Mangeled sizes down");

        cmd.Parameters["@maxVC"].Size = Int32.MaxValue;
        cmd.Parameters["@maxNVC"].Size = Int32.MaxValue;

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "Fixed max sizes");

        foreach (SqlParameter param in cmd.Parameters)
        {
            if (param.DbType != DbType.Int32
                && param.DbType != DbType.Guid)
            {
                param.Size = -1;

            }
        }

        cmd.ExecuteNonQuery();

        Printparams(cmd.Parameters, "is negative one magic");

        }
}

Ausgänge

Derived
@RETURN_VALUE : Int32 : 0 : ReturnValue : 0 :
@tenVC : AnsiString : 10 : InputOutput : 0 :
@tenC : AnsiStringFixedLength : 10 : InputOutput : 0 :
@tenNVC : String : 10 : InputOutput : 0 :
@maxVC : AnsiString : -1 : InputOutput : 0 :
@maxNVC : String : -1 : InputOutput : 0 :
@Indentifier : Guid : 0 : InputOutput : 0 :

Executed
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : AnsiString : 10 : Output : 9 : 123456789
@tenC : AnsiStringFixedLength : 10 : Output : 10 : 123456789
@tenNVC : String : 10 : Output : 9 : 123456789
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : eccc3632-4d38-44e8-9edf-031

DbType change
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : 10 : Output : 9 : 123456789
@tenC : AnsiStringFixedLength : 10 : Output : 10 : 123456789
@tenNVC : AnsiString : 10 : Output : 9 : 123456789
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 94cb0039-8587-4357-88fb-25c

Mangeled sizes up
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : 20 : Output : 9 : 123456789
@tenC : AnsiStringFixedLength : 20 : Output : 20 : 123456789
@tenNVC : AnsiString : 20 : Output : 9 : 123456789
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 4de88f14-9963-4a78-b09b-bb6

Mangeled sizes down
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : 5 : Output : 5 : 12345
@tenC : AnsiStringFixedLength : 5 : Output : 5 : 12345
@tenNVC : AnsiString : 5 : Output : 5 : 12345
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 5e973e72-14e5-4b75-9cff-e88

Fixed max sizes
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : 5 : Output : 5 : 12345
@tenC : AnsiStringFixedLength : 5 : Output : 5 : 12345
@tenNVC : AnsiString : 5 : Output : 5 : 12345
@maxVC : AnsiString : 2147483647 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : 2147483647 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 6cab2b41-d4ba-42d2-a93a-e59

is negative one magic
@RETURN_VALUE : Int32 : 0 : ReturnValue : 1 : 0
@tenVC : String : -1 : Output : 9 : 123456789
@tenC : AnsiString : -1 : Output : 10 : 123456789
@tenNVC : AnsiString : -1 : Output : 9 : 123456789
@maxVC : AnsiString : -1 : Output : 20480 : 123456789012345678901234567
@maxNVC : String : -1 : Output : 20480 : 123456789012345678901234567
@Indentifier : Guid : 0 : Output : 36 : 0d69ed57-fab7-49c8-b03a-d75

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X