15

私がやろうとしているのは、パラメーターを使用して任意のsqlコマンドを作成し、パラメーターの値とタイプを設定してから、パラメーターを含めて解析済みのsqlコマンドを返すことです。SQLデータベースに対してこのコマンドを直接実行することはないので、接続は必要ありません。したがって、以下のサンプルプログラムを実行した場合、次のテキスト(または同様のもの)が表示されることを期待します。

WITH SomeTable (SomeColumn)
AS
(
    SELECT N':)'
    UNION ALL
    SELECT N'>:o'
    UNION ALL
    SELECT N'^_^'
)
SELECT SomeColumn FROM SomeTable

そして、サンプルプログラムは次のとおりです。

using System;
using System.Data;
using System.Data.SqlClient;

namespace DryEraseConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            const string COMMAND_TEXT = @"
WITH SomeTable (SomeColumn)
AS
(
    SELECT N':)'
    UNION ALL
    SELECT N'>:o'
    UNION ALL
    SELECT @Value
)
SELECT SomeColumn FROM SomeTable
";
            SqlCommand cmd = new SqlCommand(COMMAND_TEXT);
            cmd.CommandText = COMMAND_TEXT;
            cmd.Parameters.Add(new SqlParameter
            {
                ParameterName = "@Value",
                Size = 128,
                SqlDbType = SqlDbType.NVarChar,
                Value = "^_^"
            });
            Console.WriteLine(cmd.CommandText);
            Console.ReadKey();
        }
    }
}

これは、.net標準ライブラリを使用して達成できるものですか?最初の検索では「いいえ」と表示されますが、私は間違っていると思います。

4

4 に答える 4

22

パラメータ化されたクエリがどのように機能するかについて誤った考えがあります。あなたが話す「解析されたテキスト」は決して作成されず、パラメータ値がクエリ文字列に直接置き換え られることはありません。

そのため、パラメータ化されたクエリを使用することが非常に重要です。クエリコードからクエリデータを完全に分離できます。データはデータであり、コードはコードであり、二人は決して会うことはありません。したがって、SQLインジェクションの可能性はありません。

これが意味するのは、次のようなCommandTextがある場合です。

SELECT SomeColumn FROM SomeTable WHERE ID= @ID

最終的に次のようなクエリを実行する代わりに、次のようになります。

SELECT SomeColumn FROM SomeTable WHERE ID= 123

実際には、次のようなものを実行します。

DECLARE @ID Int
Set @ID = RetrieveQueryDataItem("@ID")
SELECT SomeColumn FROM SomeTable WHERE ID= @ID

さて、これは正確には起こりません。エンジンはそのようなコードを変換しません。代わりに、sp_executesqlプロシージャを使用します。しかし、これは何が起こっているのかを理解するのに役立つはずです。

于 2010-05-07T15:13:25.520 に答える
3

Joel Coehoornは正しいです。これは、単純な文字列の置換やエスケープ文字の追加などではありません。

ただし、パラメータを表示して、値が希望どおりかどうかを確認できます。

foreach (IDataParameter i in cmd.Parameters)
{
    Console.WriteLine(i.Value.ToString());
}
于 2010-05-07T15:16:01.973 に答える
2

SQLCommandオブジェクトは、コマンドテキストの値のパラメータを交換して実行しません。指定した正確なテキストを使用してsp_executesqlを呼び出し、パラメーターのリストを提供します。データベースに対してSQLプロファイラーを使用すると、私が何を意味するかがわかります。

ここで実際に達成しようとしていることは何ですか?

于 2010-05-07T15:18:46.583 に答える
1

LINQを使用すると、C#コードで必要な制御が可能になるため、検討したくなるでしょう。

于 2010-05-07T15:14:12.973 に答える