Question

J'ai une requête SQL paramétrées pour SQL2005 ciblée qui est créé dynamiquement dans le code, donc je la classe SqlParameter ADO.NET pour ajouter des paramètres à sql SqlCommand.

Dans le SQL ci-dessus je sélectionner à partir d'un tableau avec fonction de valeur par défaut a. Je veux que mon sql dynamique pour spécifier parfois une valeur pour ces paramètres par défaut, et d'autres fois, je veux préciser que le DEFAULT SQL - tel que défini dans le tableau fonction de valeur -. Doit être utilisé

Pour conserver le code clean Je ne veux pas ajouter dynamiquement le mot-clé DEFAULT SQL et paramétrez quand un non-défaut doit être utilisé, je voulais juste ensemble DEFAULT que la valeur de mon SQLParameter.

Puis-je? Quelle est la meilleure pratique dans un tel cas?

Était-ce utile?

La solution

paramètres de requête SQL prennent la place des valeurs littérales uniquement .

Vous ne pouvez pas envoyer un mot-clé SQL comme la valeur d'un paramètre, comme vous ne pouvez pas envoyer un identifiant de table, identifiant de la colonne, la liste des valeurs (par exemple pour un prédicat IN), ou une expression. La valeur du paramètre est toujours interprété comme une valeur littérale, comme si vous aviez inclus un littéral de chaîne entre guillemets ou un littéral numérique dans votre requête.

Désolé, mais vous devez inclure un mot-clé SQL dans le cadre de la requête SQL avant vous préparer cette requête.

Autres conseils

AFAIK, la seule façon de dire SQL Server d'utiliser une valeur par défaut est via le mot-clé DEFAULT ou pour l'exclure de la liste des paramètres. Cela signifie que l'utilisation du mot-clé DEFAULT doit être dans votre paramétrés instruction SQL. Donc, quelque chose comme:

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

Je suppose une autre approche serait d'interroger les catalogues système pour la valeur réelle des différentes valeurs de DEFAULT et déterminer si pour définir la SqlParameter à la valeur par défaut de cette façon, mais qui nécessite une deuxième requête alambiquée pour obtenir les valeurs par défaut.

Si vous avez la fonction suivante (par exemple):

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

Ensuite, vous pouvez utiliser la manière suivante (option 1):

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

ce qui est de manière correcte et vous obtenez le résultat suivant:

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

Mais si vous essayez d'utiliser la requête paramétrée (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;

vous obtiendrez une erreur:

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.

Si vous avez le code .net suivant:

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())
            {
                //...
            }
        }
    }
}

puis, en cas param2 = null comme Jack suggéré ci-dessus, le script produit par le code sera identique à l'option 2 et se traduira par la même erreur. Donc, vous ne pouvez pas utiliser NULL dans ce case.You ne peut pas définir DEFAULT la valeur de SqlParameter soit.

Ce que vous pouvez faire est de créer une procédure stockée pour envelopper l'appel à votre funcion et déplacez votre valeur par défaut de la fonction à la SP. Exemple:

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

Le code .NET regardera la façon suivante:

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())
            {
                //...
            }
        }
    }
}

Dans ce cas, null comme valeur pour param2 sera traduit à la bonne DEFAULT et le script suivant sera produit:

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

qui vous donnera le résultat suivant:

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

Je ne suis pas sûr que ce soit la meilleure pratique. Ceci est juste le travail autour.

Bien que vous ne pouvez pas définir un mot-clé SQL comme la valeur d'un paramètre, vous pourriez aller dans ce cas et obtenir la valeur par défaut.

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

si vous passez un point valeur NULL nette comme étant la valeur du paramètre, il utilisera DEFAULT sql si vous passez un point DBNull.Value net, il utilisera sql NULL

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top