17

コードで動的に作成されるSQL2005を対象としたパラメーター化されたSQLクエリがあるため、ADO.NETSqlParameterクラスを使用してSQLパラメーターをに追加しましたSqlCommand

前述のSQLでは、デフォルトのあるテーブル値関数から選択します。動的SQLでこれらのデフォルトパラメータの値を指定する場合もDEFAULTあれば、テーブル値関数で定義されているSQLを使用するように指定する場合もあります。

コードをクリーンに保つために、SQLキーワードを動的に追加して、デフォルト以外を使用するときにパラメーター化するのではなく、の値としてDEFAULT設定したかっただけです。DEFAULTSQLParameter

できますか?そのような場合のベストプラクティスは何ですか?

4

5 に答える 5

15

SQLクエリパラメータは、リテラル値のみの代わりになります。

INテーブル識別子、列識別子、値のリスト(述語など)、または式を送信できないのと同じように、SQLキーワードをパラメーターの値として送信することはできません。パラメータの値は、引用符で囲まれた文字列リテラルまたは数値リテラルをクエリに含めたかのように、常にリテラル値として解釈されます。

申し訳ありませんが、クエリを準備するに、SQLクエリの一部としてSQLキーワードを含める必要があります。

于 2010-06-03T23:46:26.577 に答える
6

AFAIK、SQL Serverにデフォルト値を使用するように指示する唯一の方法は、DEFAULTキーワードを使用するか、パラメーターリストから除外することです。つまり、DEFAULTキーワードの使用は、パラメーター化されたSQLステートメントに含まれている必要があります。だから、次のようなもの:

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

別のアプローチは、さまざまな値の実際の値についてシステムカタログをクエリし、DEFAULTその方法でSqlParameterをデフォルト値に設定するかどうかを決定することだと思いますが、デフォルト値を取得するには複雑な2番目のクエリが必要です。

于 2010-06-03T23:38:08.687 に答える
3

次の機能がある場合(たとえば):

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

次に、次の方法で使用できます(オプション1)。

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.

次の.netコードがある場合:

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

次に、Jackが上記で提案したようにparam2 = nullの場合、コードによって生成されるスクリプトはオプション2と同じになり、同じエラーが発生します。したがって、この場合はNULLを使用できません。SQLParameterの値としてDEFAULTを設定することもできません。

実行できるのは、関数への呼び出しをラップし、デフォルト値を関数からSPに移動するストアドプロシージャを作成することです。例:

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

この場合、 param2の値としてnullが正しいDEFAULTに変換され、次のスクリプトが生成されます。

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

これにより、次の結果が得られます。

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

これがベストプラクティスかどうかはわかりません。これは単なる回避策です。

于 2014-09-14T11:49:40.490 に答える
1

SQLキーワードをパラメーターの値として設定することはできませんが、この場合は、デフォルト値を取得することができます。

 SELECT COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS 
      WHERE TABLE_NAME = 'table_name' AND COLUMN_NAME = 'column_name'"
于 2017-11-12T15:15:30.320 に答える
-1

パラメータ値としてドットネットのnull値を渡すと、sql DEFAULTが使用されます。ドットネットのDBNull.Valueを渡すと、sqlNULLが使用されます。

于 2011-08-01T09:56:59.790 に答える