IBM db2Command SQL SELECT * FROM IN @namedParameter

时间:2018-04-03 02:33:30

标签: c# db2

使用下面的C#代码构造DB2 SQL查询时,结果集只有一行。如果我手动构建" IN"使用string.Join(",",ids)在cmdTxt字符串中的谓词,然后返回所有预期的行。如何使用db2Parameter对象返回所有预期的行,而不是将查询构建为要发送到服务器的长字符串?

public object[] GetResults(int[] ids)
    {
        var cmdTxt = "SELECT DISTINCT ID,COL2,COL3 FROM TABLE WHERE ID IN ( @ids ) ";
        var db2Command = _DB2Connection.CreateCommand();
        db2Command.CommandText = cmdTxt;

        var db2Parameter = db2Command.CreateParameter();
        db2Parameter.ArrayLength = ids.Length;
        db2Parameter.DB2Type = DB2Type.DynArray;
        db2Parameter.ParameterName = "@ids";
        db2Parameter.Value = ids;
        db2Command.Parameters.Add(db2Parameter);

        var results = ExecuteQuery(db2Command);

        return results.ToArray();
    }


    private object[] ExecuteQuery(DB2Command db2Command)
    {
        _DB2Connection.Open();
        var resultList = new ArrayList();
        var results = db2Command.ExecuteReader();
        while (results.Read())
        {
            var values = new object[results.FieldCount];
            results.GetValues(values);
            resultList.Add(values);
        }
        results.Close();
        _DB2Connection.Close();
        return resultList.ToArray();
    }

2 个答案:

答案 0 :(得分:0)

您无法将数组作为参数发送。你必须做一些事情来建立一个参数列表,每个值都有一个。

例如:SELECT DISTINCT ID,COL2,COL3 FROM TABLE WHERE ID IN ( @id1, @id2, ... @idN )

然后将值添加到参数集合中:

cmd.Parameters.Add("@id1", DB2Type.Integer).Value = your_val;

此外,我还会采取一些措施来改进您的代码:

  1. 在DB2对象周围使用using statements。这将在超出范围时自动正确处理对象。如果你不这样做,最终你会遇到错误。这应该在DB2ConnectionDB2CommandDB2TransactionDB2Reader对象上完成。
  2. 我建议您将查询包装在事务对象中,即使是选择也是如此。使用DB2(我的经验是z / OS大型机,这里......对于AS / 400可能不同),它为每个事务写入一个“记帐”记录(基本上是DB2所做的工作)。如果您没有显式事务,那么DB2将为您创建一个事务,并在每个语句之后自动提交,这会增加许多可以组合的后端记录。
  3. 我个人的意见也是创建一个.NET class来保存您从数据库中获取的数据。这样可以更容易地使用IntelliSense,因为您可以自动完成属性名称,.NET将知道对象的类型。现在,对于对象数组,如果您的列顺序或数据类型发生更改,则可能很难在整个代码中查找/调试这些用法。
  4. 我已经包含了我重新编写的代码版本,其中包含一些变更内容:

    public List<ReturnClass> GetResults(int[] ids)
        {
            using (var conn = new DB2Connection())
            {
                conn.Open();
    
                using (var trans = conn.BeginTransaction(IsolationLevel.ReadCommitted))
                using (var cmd = conn.CreateCommand())
                {
                    cmd.Transaction = trans;
    
                    var parms = new List<string>();
                    var idCount = 0;
                    foreach (var id in ids)
                    {
                        var parm = "@id" + idCount++;
                        parms.Add(parm);
                        cmd.Parameters.Add(parm, DB2Type.Integer).Value = id;
                    }
                    cmd.CommandText = "SELECT DISTINCT ID,COL2,COL3 FROM TABLE WHERE ID IN ( " + string.Join(",", parms) + " ) ";
    
                    var resultList = new List<ReturnClass>();
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var values = new ReturnClass();
                            values.Id = (int)reader["ID"];
                            values.Col1 = reader["COL1"].ToString();
                            values.Col2 = reader["COL2"].ToString();
                            resultList.Add(values);
                        }
                    }
                    return resultList;
                }
            }
        }
    
        public class ReturnClass
        {
            public int Id;
            public string Col1;
            public string Col2;
        }
    

答案 1 :(得分:-2)

尝试更改:

db2Parameter.DB2Type = DB2Type.DynArray;

为:

db2Parameter.DB2Type = DB2Type.Integer;

这是基于here

给出的示例