ado.netのSQLパラメーター値として「デフォルト」をどのように指定しますか?
-
24-10-2019 - |
質問
コードで動的に作成されたSQL2005用にターゲットにされたパラメーター化されたSQLクエリがあるため、ADO.NETを使用しました SqlParameter
SQLパラメーターを追加するクラス SqlCommand
.
前述のSQLでは、テーブルから選択した機能から選択します。動的なSQLにこれらのデフォルトパラメーターの値を時々指定したい場合もあります。また、SQLを指定したい場合もあります。 DEFAULT
- 表で定義されているように、価値のある関数 - 使用する必要があります。
コードを保持するため 掃除 SQLを動的に追加したくありませんでした DEFAULT
キーワードとパラメーター化非デフォルトを使用する場合、設定したかっただけです DEFAULT
私の価値として SQLParameter
.
私はできますか?そのような場合のベストプラクティスとは何ですか?
解決
SQLクエリパラメーターは、リテラル値に取って代わります それだけ.
テーブル識別子、列識別子、値のリストを送信できないのと同じように、SQLキーワードをパラメーターの値として送信することはできません(例: IN
述語)、または式。パラメーターの値はです いつも クエリに引用された文字列または数値リテラルを含めたかのように、文字通りの価値として解釈されます。
申し訳ありませんが、SQLクエリの一部としてSQLキーワードを含める必要があります 前 そのクエリを準備します。
他のヒント
AFAIK、SQL Serverにデフォルト値を使用するように伝える唯一の方法は、 DEFAULT
キーワードまたはパラメーターリストから除外します。それは、の使用を意味します DEFAULT
キーワードは、パラメーター化されたSQLステートメントにある必要があります。だから、次のようなもの
Select ...
From dbo.udf_Foo( DEFAULT, @Param2, @Param3, DEFAULT, .... )
別のアプローチは、さまざまなものの実際の値をシステムカタログに照会することだと思います DEFAULT
値を決定し、SQLParameterをそのようにデフォルト値に設定するかどうかを決定しますが、デフォルト値を取得するには複雑な2番目のクエリが必要です。
次の関数がある場合(たとえば):
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と同一であり、同じエラーが発生します。したがって、使用できません ヌル この場合、設定できません デフォルト SQLParameterの値として。
あなたができることは、ストアドプロシージャを作成して、コールをFuncionにラップし、デフォルト値を関数から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 正しいものに翻訳されます デフォルト 次のスクリプトが作成されます。
exec USP_SAMPLE_PROCEDURE @Param1=N'ABC',@Param2=default,@Statement=N'SELECT * FROM dbo.UFN_SAMPLE_FUNCTION (@P1, @P2)'
これにより、次の結果が得られます。
Col1 Col2
---------- -----------
ABC NULL
これがベストプラクティスであるかどうかはわかりません。これは単なる回避策です。
SQLキーワードをパラメーターの値として設定することはできませんが、この場合、デフォルト値を取得することができます。
SELECT COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'table_name' AND COLUMN_NAME = 'column_name'"
ドットネットNULL値をパラメーター値として渡す場合、ドットネットdbnull.valueを渡すと、SQLデフォルトを使用します。