如果超过 DB2 中分配的时间,则终止 SQL 查询执行

Kill SQL query execution if it exceeds allotted time in DB2

我正在 .NET 中创建一个程序,它使用 IBM DB2 .NET 提供程序 (IBM.Data.DB2) 连接到 DB2 数据库 (v9.7) 和 运行 select 查询。

如果提交的 select 查询return 数据花费超过 5 秒,程序应终止 SQL 执行。

为了按照 IBM's documentation 实现这一点,我可以在连接中使用 QueryTimeout 参数。

string connStr = "Server=server:12345;Database=db;UID=user;PWD=pass; QueryTimeout = 5;";

            DB2Connection conn = null;
            DB2Command cmd = null;

            conn = new DB2Connection(connStr);
            conn.Open();
            Console.WriteLine("IBM DB2: " + conn.IsOpen);
            if (conn.IsOpen)
            {
                Console.WriteLine(conn.ConnectionTimeout);
                cmd = conn.CreateCommand();
                cmd.CommandText = "select * from user.orders";                    
                DB2DataReader reader = cmd.ExecuteReader();
                int counter = 0;
                while (reader.Read())
                {
                    counter += 1;
                    Console.WriteLine(reader.GetDB2Int64(0));
                }                    
                reader.Close();                    
            }
            conn.Close();

当我运行在winSQL中查询时,查询大约需要20秒来执行。但是当我在这个程序中执行它时,我花了同样的 20 秒。根据文档,查询应该在 5 秒内终止。

为什么执行没有停止?

PS:我也试过将cmd.CommandTimeout设置为5,但还是不行停止执行。

阅读 IBM 网站上的 DB2Command.CommandTimeout 属性 教程。我希望这会解决你的问题。 C# 示例代码如下:

[C#]

public void CreateMyDB2Command()
{
  string mySelectQuery = "SELECT * FROM EMPLOYEE ORDER BY EMPNO";
  DB2Command myCommand = new DB2Command(mySelectQuery);
  myCommand.CommandTimeout = 20;
}

上述示例的问题在于 ExecuteReader() 创建了一个指向数据库的游标,该游标在读取数据时提取数据,因此查询永远不会超时。

但是使用 DataAdapter 到数据集,一次性提取数据。所以下面似乎终止了执行。

string connStr = "Server=server:12345;Database=db;UID=user;PWD=pass;";
conn = new DB2Connection(connStr);
conn.Open();

if (conn.IsOpen)
{
    Console.WriteLine(conn.ConnectionTimeout);
    cmd = conn.CreateCommand();
    cmd.CommandText = "select * from orders";
    cmd.CommandTimeout = 5;

    DB2DataAdapter adp = new DB2DataAdapter(cmd);
    DataSet ds = new DataSet();
    adp.Fill(ds);
    foreach (DataRow row in ds.Tables[0].Rows){
        Console.WriteLine(row[0]);
    }
}
conn.Close();