0

解決策を見つけるためにグーグルを試しましたが、得られるのはまったく無関係な結果、またはここにあるような 2 次元配列を含む結果だけです。 -14d7-49e9-b721-db4501db62c8/how-does-one-increment-a-value-in-a-two-dimensional-array

これを宣言したとしましょう:

var db = Database.Open("Content");
var searchTerms = searchText.Split('"').Select((element, index) => index % 2 == 0 ? element.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) : new string[] { element }).SelectMany(element => element).ToList();
int termCount = searchTerms.Count;

(注: 本当に知っておく必要がsearchTermsあるのは、ユーザーが検索バーに入力した多数の検索語が保持されていることだけです。LINQ 式が行っているのは、qoutes で囲まれたテキストが単一の検索語として扱われるようにすることだけです。この質問の目的のために、これらすべてを知る必要はありません。 )

searchTerms次に、(リスト内の項目の数ごとにループする for ループを使用して) SELECTSQL クエリとして使用する文字列をコンパイルしました。

@0, @1, etc.これは、クエリがパラメーター化されるように、この文字列の一部がプレースホルダーでコンパイルされていることを示す例です。

searchQueryString = "SELECT NULL AS ObjectID, page AS location, 'pageSettings' AS type, page AS value, 'pageName' AS contentType, ";

for (int i=0; i<termCount; i++)
{
    if(i != 0)
    {
        searchQueryString += "+ ";
    }

    searchQueryString += "((len(page) - len(replace(UPPER(page), UPPER(@" + i + "), ''))) / len(@" + i + ")) ";
}

searchQueryString += "AS occurences ";

(注: 上記のコードについて本当に知っておく必要があるのは i @ シンボルに の増分値を連結して、プレースホルダー値を動的にコンパイルしていることだけです。 )

上記のすべてが正常に機能しますが、後で、この行に沿って何かを使用する必要があります (実行時まで必要な引数の数だけはわかりません)。

foreach (var row in db.Query(searchQueryString, searchTerms[0]))
{
    @row.occurences
}

明確化のために: リスト内のアイテムの数に等しい数の追加の引数(つまり、引数に加えて)が必要であり 正しいインデックスを参照する必要があります(効果的に各インデックスを最低から最高まで参照し、もちろん、コンマで区切って順番に。searchQueryString searchTerms

また、もちろん、リストの適切なインデックスを参照するために増分値を使用する必要がありますが、そこまで到達できれば、その方法もわかりません。そのために何らかの形で使用できi++ますか?

C# が強力であることは知っていますが、質問が多すぎるのではないでしょうか?

4

3 に答える 3

1

可変数のパラメーターには params キーワードを使用します。params を使用すると、任意の関数に渡される引数は、コンパイラによって一時配列の要素に変更されます。

static int AddParameters(params int[] values)
{
    int total = 0;
    foreach (int value in values)
    {
      total += value;
    }
    return total;
}

として呼び出すことができます

int add1 = AddParameters(1);
int add2 = AddParameters(1, 2);
int add3 = AddParameters(1, 2, 3);
int add4 = AddParameters(1, 2, 3, 4);

//-----------以下のコメントに基づいて編集された返信--- このようなものを SQL で使用できます

void MYSQLInteractionFunction(String myConnectionString)
 {
    String searchQueryString = "SELECT NULL AS ObjectID, page AS location, 'pageSettings' AS type, page AS value, 'pageName' AS contentType, ";
    SqlConnection myConnection = new SqlConnection(myConnectionString);
    SqlCommand myCommand = new SqlCommand(searchQueryString, myConnection);
    myConnection.Open();

    SqlDataReader queryCommandReader = myCommand.ExecuteReader();
    // Create a DataTable object to hold all the data returned by the query.
    DataTable dataTable = new DataTable();

    // Use the DataTable.Load(SqlDataReader) function to put the results of the query into a DataTable.
    dataTable.Load(queryCommandReader);

    Int32 rowID = 0; // or iterate on your Rows - depending on what you want
    foreach (DataColumn column in dataTable.Columns)
    {
       myStringList.Add(dataTable.Rows[rowID][column.ColumnName] + " | ");
       rowID++;
     }
     myConnection.Close();

     String[] myStringArray = myStringList.ToArray();
     UnlimitedParameters(myStringArray);
}

static void UnlimitedParameters(params string[] values)
{
    foreach (string strValue in values)
    {
        // Do whatever you want to do with this strValue
     }
 }
于 2013-07-09T16:15:15.693 に答える
0

質問がどれほど複雑に見えたとしても、答えは非常に単純なものになりました。私はこれまでにこれをやったことがなく、他の人は私が探していたものとはあまりにも明白だと思ったかもしれないので、見落としがちだったと思います. しかし、私は以前に可変長のパラメーターを渡そうとしたことがなく、それが可能かどうかもわかりませんでした (まあ、私は何とかそれが可能であることを知っていたと思いますが、私の方法とはかけ離れていた可能性があります)。知っていた)。

いずれにせよ、私は試しました:

foreach (var row in db.Query(searchQueryString, searchTerms)) //searchTerms is a list of strings.
{
    //Do something for each row returned from the sql query.
}

可変長の引数を処理できる場合 (Database.Query()メソッドの最初の引数の後に渡される各引数は、クエリ文字列 (例: ) のプレースホルダーのフィラーとして扱われることを思い出してください@0, @1, @2, etc.)配列。

リストを渡すとエラーがスローされるため、その仮定に間違いはありませんでした。しかし、ついに決裂し、リストを配列に変換し、リストの代わりに配列を渡そうとしたときは驚きました。

確かに、これが私の元の質問に対する短い答えです。単純に配列を指定すると、簡単に機能します(少し簡単すぎるため、機能しないと確信していた理由だと思います)。

string[] searchTermsArray = searchTerms.ToArray();

foreach (var row in db.Query(searchQueryString, searchTermsArray)) //searchTermsArray is an array of strings.
{
    //Do something for each row returned from the sql query.
}

上記のコード スニペットは、元の質問に正しく答えるために必要なすべてです。

于 2013-07-10T13:40:37.330 に答える
0

質問から何が必要かよくわかりませんが、SQL の一連のプレースホルダーを別の値に置き換えているようです。その場合は、 String.Format を使用して、次のように値を置き換えることができます。

        object val = "a";
        object anotherVal = 2.0;
        var result = string.Format("{0} - {1}", new[] { val, anotherVal });

このように、適切なサイズになるように引数配列を作成するだけで、必要な数の値を置き換えることができます。

オンザフライで SQL クエリを作成している場合は、SQL インジェクションに注意する必要があります。この観点からすると、ユーザーが指定したテキストを直接クエリに代入することは、ちょっとしたことではありません。これを回避する最善の方法は、SQL インジェクションを防ぐために自動的にサニタイズされるクエリでパラメーターを使用することです。ただし、「params array」引数を使用して、必要なものを実現できます。次に例を示します。

    public IDataReader ExecuteQuery(string sqlQuery, params string[] searchTerms)
    {
        var cmd = new SqlCommand { CommandText = sqlQuery };

        for (int i = 0; i < searchTerms.Length; i++)
        {
           cmd.Parameters.AddWithValue(i.ToString(), searchTerms[i]);
        }

        return cmd.ExecuteReader();
    }

明らかに、必要に応じて、searchTerms 配列の長さに基づいて、このメソッド内で SQL 文字列を作成することもできます。

于 2013-07-09T16:06:39.493 に答える