LoginSignup
4
0

More than 5 years have passed since last update.

Spring.NETでパラメータをセットする際にハマった

Last updated at Posted at 2018-04-25

Qiita初投稿です。
お手柔らかに。

概要

  • SQL文を動的生成する必要があった。
  • さらにその中でIN句を使うケースがあった。
  • パラメータを渡してもうまくSQLが生成されず、少々ハマった。

実装

※引数のkeysには"1"~"27"の値を渡しています。

hoge.cs
    public fugaClass findByKeys(string[] keys) 
    {
        StringBuilder query = new StringBuilder("SELECT * FROM hogeTable");

        // WHERE句生成
        StringBuilder conditions = new StringBuilder("WHERE key IN (");
        for(int i=0; i < keys.length; i++) 
        {
            conditions.Add(" @Val" + generateAlphabet(i));
            if (i != keys.Length - 1) conditions.Add(",");
        }
        IDbParameters params = CreateDbParameters();
        for(int i=0; i < keys.length; i++) 
        {
            params.Add("Val" + generateAlphabet(i), DbType.String).Value = key
        }

        HogeCallback callback = new HogeCallBack
        AdoTemplate.QueryWithRowCallback(CommandType.Text, query.ToString(), callback, params);

        return callback.result;
    }

    private string generateAlphabet(int index) {
        string str = "";
        do {
            str = Convert.ToChar(index % 26 + 0x41) + str;
        } while ((index = index / 26 - 1) != -1);

        return str;
    }

生成されるSQL

SELECT * FROM hogeTable WHERE key IN (@ValA, @ValB,...@ValAA)

パラメータを渡した後のSQL

SELECT * FROM hogeTable WHERE key IN ('1', '2',...'1'A)

なんじゃこりゃ。
どうやら同文字列が先に存在したらそっちに値が渡ってしまうようです。(説明下手)

改善

hoge.cs
    public fugaClass findByKeys(string[] keys) 
    {               
        StringBuilder query = new StringBuilder("SELECT * FROM hogeTable");

        // WHERE句生成
        StringBuilder conditions = new StringBuilder("WHERE key IN (");
        for(int i=0; i < keys.length; i++) 
        {
            conditions.Add(" @Val" + generateAlphabet(i));
            if (i != keys.Length - 1) conditions.Add(",");
        }
        IDbParameters params = CreateDbParameters();
        // 降順でパラメータを追加
        for(int i=keys.length; i >= 0; i--) 
        {
            params.Add("Val" + generateAlphabet(i), DbType.String).Value = key
        }

        HogeCallback callback = new HogeCallBack
        AdoTemplate.QueryWithRowCallback(CommandType.Text, query.ToString(), callback, params);

        return callback.result;
    }

    private string generateAlphabet(int index) {
        string str = "";
        do {
            str = Convert.ToChar(index % 26 + 0x41) + str;
        } while ((index = index / 26 - 1) != -1);

        return str;
    }

生成されるSQL

SELECT * FROM hogeTable WHERE key IN (@ValA, @ValB,...@ValAA)

パラメータを渡した後のSQL

SELECT * FROM hogeTable WHERE key IN ('1', '2',...'27')

OK!

まとめ

  • 連番、連続した文字列でパラメータ文字列を生成した時は降順にセットを行う
  • 調べてわかったが、LIKE句で実装すると楽らしい

投稿者はC#初心者です・・・。
素のコードをそのまま張り付けているわけではないので、なにか不備などありましたらご指摘お願いいたします。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0