代码之家  ›  专栏  ›  技术社区  ›  Llyle bonjorno

如何在ADO.NET中将“DEFAULT”指定为SQL参数值?

  •  13
  • Llyle bonjorno  · 技术社区  · 14 年前

    我有一个针对SQL2005的参数化SQL查询,它是在代码中动态创建的,所以我使用了ADO.NET SqlParameter 类添加sql参数 SqlCommand .

    在前面提到的SQL中,我从一个表值函数中选择has defaults。有时我希望动态sql为这些默认参数指定一个值,有时我希望指定sql DEFAULT -如表值函数中所定义,应使用。

    清洁的 违约 SQLParameter .

    我可以吗?在这种情况下,最佳做法是什么?

    5 回复  |  直到 14 年前
        1
  •  15
  •   Bill Karwin    14 年前

    SQL查询参数将取代文字值 只有 .

    IN 谓词)或表达式。参数的值为 解释为文本值,就像在查询中包含带引号的字符串文本或数字文本一样。

    之前 你准备好这个问题。

        2
  •  6
  •   Thomas    14 年前

    另外,告诉SQLServer使用默认值的唯一方法是通过 DEFAULT 违约 关键字必须在参数化SQL语句中。比如说:

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

    违约

        3
  •  2
  •   Alex    10 年前

    如果您具有以下功能(例如):

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

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

    哪种方法是正确的,您将得到以下结果:

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

    但如果尝试使用参数化查询(选项2):

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

    您将得到一个错误:

    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.
    

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

    无效的 在这种情况下,您不能设置 违约 作为SQLParameter的值。

    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
    

    .NET代码的外观如下:

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

    在这种情况下 无效的 参数2 将被翻译成正确的 将生成以下脚本:

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

    将得到以下结果:

    列1列2
    ABC空
    

    我不确定这是否是最佳做法。这只是工作。

        4
  •  1
  •   Chris Catignani Sagar Barapatre    7 年前

    虽然不能将SQL关键字设置为参数的值,但在本例中,可以获取默认值。

     SELECT COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS 
          WHERE TABLE_NAME = 'table_name' AND COLUMN_NAME = 'column_name'"
    
        5
  •  -1
  •   Jack    13 年前

    如果您传递一个dotnetnull值作为参数值,它将使用sql默认值 如果您传递一个dot net DBNull.Value,它将使用sql NULL