一旦在日志表中记录交易,是否有一种方法可以在控制台中显示交易

时间:2019-02-11 07:59:16

标签: c# sql-server

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

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

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

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();

}

2 个答案:

答案 0 :(得分:1)

我发现值得一提的三件事:

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

    DATETIME
  

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

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

如果控制台日志很多,则可以通过logdate进行动态过滤,而不是每次都查询所有当前日期。因此,每个查询都将带来您查询的最后WHERE logdate >= CONVERT(DATE, GETDATE()) AND logdate < CONVERT(DATE, GETDATE() + 1) ORDER BY logdate 条记录,从而带来所有 new 条记录。您可以通过添加完整的datetime参数,仅检索比前一个更高的记录并将当前日期时间存储在此变量上来实现此目的。

答案 1 :(得分:0)

您可以使用SqlDependency来通知您的应用程序,以免发生更改,而不必使用pull模型并重复查询数据(即使没有更改)。 link包含概述和示例。

尽管要注意的一件事是SqlDependency对象是在考虑服务器应用程序的情况下构建的。这并不意味着将其推广到许多聆听变化的客户。有关其他信息,请参见此link