首页 > 解决方案 > 有没有办法在日志表中记录事务后立即在控制台中显示事务

问题描述

我有一个表记录了进程,我想创建一个控制台应用程序,一旦将消息写入表,它将循环并更新控制台。

最终结果将是我查看控制台而不是查询数据库。

我有一个可以提取数据并显示的查询,但是我正在寻找最佳实践/更好的解决方案,因为我觉得我的不符合标准

string ConnectionString = "connectionstring here";

string TableName = "table name here";

while (true)
{

    SqlConnection myConnection = new SqlConnection(ConnectionString);

    myConnection.Open();

    SqlDataReader myReader = null;
    SqlCommand myCommand = new SqlCommand("select LogDate, Message from " + TableName + " where convert(date, logdate, 103) = convert(date, getdate(), 103) order by logdate;", myConnection);
    myReader = myCommand.ExecuteReader();

    while (myReader.Read())
    {
        Console.WriteLine(myReader["LogDate"].ToString() + " -> " +             
        myReader["Message"].ToString());
                //Thread.Sleep(200);
    }

    myConnection.Close();

}

标签: c#sql-server

解决方案


我觉得值得一提的三件事:

  • 通过连接不受控制的值来构建动态 SQL 时要小心。如果TableName中间有空格会发生什么(或者更糟的是,类似的 SQL 命令TableName; DECLARE @CurrentLogin VARCHAR(100) = SYSTEM_USER; EXEC('DROP LOGIN ' + @CurrentLogin);,不要执行!)。由于您正在动态更改表,因此您无法对此查询进行参数化,尽管您可以采取一些措施来降低注入风险,例如确保TableName变量小于 X 个字符(通常 20 个就足够了),并且不t 包含空格、分号或关键 SQL 词,如EXECor DROP
  • 您正在选择和过滤特定列,因此此查询不适用于大多数表,仅适用于具有这些列的表。您应该考虑删除动态表参数并改​​用 a Switch,只允许查询您要查询的表。这将使您的查询受到限制但更安全。
  • logdate您的过滤器在与常量 ( ) 进行比较之前转换表列 ( getdate()),这将使索引logdate(如果有) 不适用。我相信您想查看当天的记录,因此您正在对日期代码103yyyy-MM-dd)进行比较。您应该避免转换表值并改用双重过滤器,假设logdateDATETIME. 如果logdate不能在比今天更高的日期,您可以跳过第二次检查:

    WHERE
        logdate >= CONVERT(DATE, GETDATE()) AND
        logdate < CONVERT(DATE, GETDATE() + 1)
    ORDER BY
        logdate
    

最终结果将是我查看控制台而不是查询数据库。

控制台将为您查询数据库,您只是在更改用户界面。

如果您有许多控制台日志,您可以进行动态过滤,datetime而不是每次都查询所有当前日期。因此,每个查询都会带来datetime您上次查询的记录,从而带来所有记录。您可以通过添加一个完整datetime参数来做到这一点,仅检索高于前一个的记录并将当前日期时间存储在此变量中。


推荐阅读