Frage

Ich habe eine parametrisierte SQL -Abfrage für SQL2005, die dynamisch im Code erstellt wurde, daher habe ich das ado.net verwendet SqlParameter Klasse zum Hinzufügen von SQL -Parametern zu SqlCommand.

In der oben genannten SQL wähle ich eine aus einer Tabelle bewertete Funktion mit Standardfunktionen. Ich möchte DEFAULT - Wie in der Tabelle bewertete Funktion definiert - sollte verwendet werden.

Um den Code zu behalten sauber Ich wollte den SQL nicht dynamisch hinzufügen DEFAULT Schlüsselwort und Parametrisiere, wenn ein Nicht-Default verwendet werden soll, wollte ich nur einstellen DEFAULT Als Wert von meinem SQLParameter.

Kann ich? Was ist die Best Practice in einem solchen Fall?

War es hilfreich?

Lösung

SQL -Abfrageparameter nehmen den Platz der wörtlichen Werte ein nur.

Sie können kein SQL -Schlüsselwort als Wert eines Parameters senden, genauso wie Sie keine Tabellenkennung, Spaltenkennung, Werteliste senden können (z. B. für eine IN Prädikat) oder ein Ausdruck. Der Wert des Parameters ist stets als wörtlicher Wert interpretiert, als hätten Sie eine zitierte String -Literal oder ein numerisches Literal in Ihre Anfrage aufgenommen.

Entschuldigung, aber Sie müssen ein SQL -Schlüsselwort als Teil der SQL -Abfrage angeben Vor Sie bereiten diese Frage vor.

Andere Tipps

AFAIK, der einzige Weg, SQL Server zu sagen, dass er einen Standardwert verwenden soll, ist über die DEFAULT Schlüsselwort oder um es aus der Parameterliste auszuschließen. Das bedeutet, dass die Verwendung der Verwendung der DEFAULT Das Schlüsselwort muss in Ihrer parametrisierten SQL -Anweisung enthalten sein. Also so etwas wie:

Select ...
From dbo.udf_Foo( DEFAULT, @Param2, @Param3, DEFAULT, .... )

Ich nehme an, ein anderer Ansatz wäre es, die Systemkataloge für den tatsächlichen Wert der verschiedenen abfragen DEFAULT Werte und bestimmen Sie, ob das SQLParameter auf den Standardwert auf diese Weise festgelegt werden soll. Dies erfordert jedoch eine verschlungene zweite Abfrage, um die Standardwerte zu erhalten.

Wenn Sie die folgende Funktion haben (zum Beispiel):

CREATE FUNCTION dbo.UFN_SAMPLE_FUNCTION 
(
    @Param1 nvarchar(10), 
    @Param2 int = NULL
)
RETURNS TABLE
AS 
RETURN 
   SELECT @Param1 AS Col1, @Param2 AS Col2;
GO

Dann können Sie es auf folgende Weise verwenden (Option 1):

SELECT * FROM dbo.UFN_SAMPLE_FUNCTION ('ABC', DEFAULT);

Welches ist der richtige Weg und Sie erhalten das folgende Ergebnis:

Col1       Col2
---------- -----------
ABC        NULL

Wenn Sie jedoch versuchen, eine parametrisierte Abfrage zu verwenden (Option 2):

exec sp_executesql N'SELECT * FROM dbo.UFN_SAMPLE_FUNCTION (@P1, @P2)',N'@P1 nvarchar(10),@P2 int',@P1=N'abc',@P2=default;

Sie erhalten einen Fehler:

Msg 8178, Level 16, State 1, Line 0
The parameterized query '(@P1 nvarchar(10),@P2 int)SELECT * FROM dbo.UFN_SAMPLE_FUNCTION' expects the parameter '@P2', which was not supplied.

Wenn Sie den folgenden .NET -Code haben:

public void RunTVF(string param1, int? param2)
{
    using (SqlConnection con = GetProdConection())
    {
        using (var cmd = new SqlCommand("SELECT * FROM dbo.UFN_SAMPLE_FUNCTION (@P1, @P2)", con))
        {
            cmd.CommandType = CommandType.Text;
            var param = new SqlParameter
            {
                ParameterName = "@P1",
                SqlDbType = SqlDbType.NVarChar,
                Size = 10   ,
                Value = param1
            };
            cmd.Parameters.Add(param);
            param = new SqlParameter
            {
                ParameterName = "@P2",
                SqlDbType = SqlDbType.Int,
                Value = param2
            };
            cmd.Parameters.Add(param);

            cmd.Connection.Open();
            using (IDataReader dataReader = cmd.ExecuteReader())
            {
                //...
            }
        }
    }
}

In Fall Param2 = null, wie jack oben vorgeschlagen, ist das vom Code erstellte Skript mit der Option 2 identisch und führt zu demselben Fehler. Sie können also nicht verwenden NULL In diesem Fall können Sie nicht festlegen URSPRÜNGLICH als Wert von SQLParameter auch.

Sie können eine gespeicherte Prozedur erstellen, um den Anruf in Ihr Funktion zu wickeln und Ihren Standardwert aus der Funktion in den SP zu verschieben. Beispiel:

CREATE PROCEDURE dbo.USP_SAMPLE_PROCEDURE
( 
    @Param1 nvarchar(10), 
    @Param2 int = NULL, --DEFAULT value now is here (remove it from the function)
    @Statement nvarchar(max)
)
AS
BEGIN
    SET NOCOUNT ON;
    EXEC sp_executesql @Statement,N'@P1 nvarchar(10),@P2 int',@P1=@Param1,@P2=@Param2;
END

Der .NET -Code sieht folgendermaßen aus:

public void RunWrapper(string param1, int? param2)
{
    using (SqlConnection con = GetProdConection())
    {
        using (var cmd = new SqlCommand("USP_SAMPLE_PROCEDURE", con))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            var param = new SqlParameter
            {
                ParameterName = "@Param1",
                SqlDbType = SqlDbType.NVarChar,
                Size = 10,
                Value = param1
            };
            cmd.Parameters.Add(param);
            param = new SqlParameter
            {
                ParameterName = "@Param2",
                SqlDbType = SqlDbType.Int,
                Value = param2
            };
            cmd.Parameters.Add(param);
            param = new SqlParameter
            {
                ParameterName = "@Statement",
                SqlDbType = SqlDbType.NVarChar,
                Size = -1, //-1 used in case you need to specify nvarchar(MAX)
                Value = "SELECT * FROM dbo.UFN_SAMPLE_FUNCTION (@P1, @P2)"
            };
            cmd.Parameters.Add(param);

            cmd.Connection.Open();
            using (IDataReader dataReader = cmd.ExecuteReader())
            {
                //...
            }
        }
    }
}

In diesem Fall Null als Wert für die Param2 wird in die richtige übersetzt URSPRÜNGLICH und das folgende Skript wird produziert:

exec USP_SAMPLE_PROCEDURE @Param1=N'ABC',@Param2=default,@Statement=N'SELECT * FROM dbo.UFN_SAMPLE_FUNCTION (@P1, @P2)'

Dies gibt Ihnen das folgende Ergebnis:

Col1       Col2
---------- -----------
ABC        NULL

Ich bin mir nicht sicher, ob dies die beste Praxis ist. Dies ist nur die Arbeit.

Obwohl Sie kein SQL -Schlüsselwort als Wert eines Parameters festlegen können, können Sie in diesem Fall den Standardwert erhalten.

 SELECT COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS 
      WHERE TABLE_NAME = 'table_name' AND COLUMN_NAME = 'column_name'"

Wenn Sie einen Punkt NELL -NULL -Wert als Parameterwert übergeben, wird SQL -Standard verwendet, wenn Sie einen Punkt net dbnull übergeben. Wert wird SQL Null verwendet

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top