我目前正在编写一个Web前端,用于分析插入SQL Server的Web日志。
最基本的功能之一是,您可以通过指定时间范围来搜索一组结果(这通常是用于排除最近流量,而不是深度数据挖掘的工具),然后是各种其他字段,例如ClientIP,Uri等
我最初使用LINQ做了这个,但开始对它感到恼火,并决定用StringBuilder构建查询并使用Dapper.NET会更容易。所以我仍然为我的表生成了dmbl(实际上有31个表,每天一个,但是一个视图将它们组合在一起)。然后在我的控制器中创建类似以下内容的查询:
public ActionResult Index(SearchParams sp)
{
var db = new LogTableDataContext();
var query = new StringBuilder();
...
var fields = " Time, ClientIp, Method, Uri, Bytes, Server, Tr, TermState, UserAgent, Host ";
query.Append(" SELECT ");
if (sp.top.HasValue)
query.Append(" Top ").Append(sp.top);
query.Append(fields);
query.Append(" from Logs ");
query.Append(" WHERE 1=1 ");
if (wherestrings.HasValue())
query.Append(wherestrings);
var resultsModel = new UberRows { rows = results, generated_query = query.ToString(), query_params = sp.GetPropertyNamesAndValues() };
return View(resultsModel);
根据传递给控制器的GET参数生成WHERE子句,如:
public string GenerateWhereString()
{
var wherestring = new StringBuilder();
if (this.Uri.HasValue())
wherestring.Append(" AND Uri = @Uri ");
if (this.ClientIp.HasValue())
wherestring.Append(" AND ClientIp = @ClientIP ");
if (this.Server.HasValue())
UberRows只有public List<HAProxyLogViewer.Log> rows;
,我只是使用jquery和DataTable插件在div中渲染结果,因为结果集通常应该很小。
我还想要查询上述搜索结果集的一堆查询(每个服务器有多少次点击,平均响应时间等)。
我猜测这样做的方法是创建一个包含结果的临时表(因为如果我不这样做,我将不得不为结果集的响应时间等事项生成每个查询的基本结果),但由于我是新手,c#和asp.mvc我不确定这将如何工作并被绑定到MVC,我的ORM和dmbl类。假设我对临时表是正确的,我将如何使用它?
所以纯SQL就像:
SELECT Time, ClientIp, Method, Uri, Bytes, Server, Tr, TermState, UserAgent, Host
INTO #resultsTable
FROM Logs
WHERE 1=1 AND Time BETWEEN dateadd(minute, -1440, getutcdate()) and getutcdate()
AND UserAgent = 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)';
SELECT Time, ClientIp, Method, Uri, Bytes, Server, Tr, TermState, UserAgent, Host
FROM #resultsTable;
SELECT Server, COUNT(*)
FROM #resultsTable
GROUP BY Server;
SELECT AVG(Tr)
FROM #resultsTable;
DROP TABLE #resultsTable;
答案 0 :(得分:2)
临时表不会超出创建它的数据库会话。全局临时表可以跨数据库会话共享,但根据您的方案,当会话开始和结束时可能无法预测,因此可能无法提供可预测的结果。
我建议创建一个真实的表来保存结果并查询。完成查询后,只需删除所有数据。如果可以使用不同的结果集来建立多个连接(因此Temp Table会很棒),那么您可以添加UNIQUEIDENTIFIER字段作为“键”,用于这组查询所使用的数据集。这意味着,在应用程序端生成GUID,并将其传递到填充实际表的查询中,以便针对它的每个查询都可以将该应用程序生成的值用作附加的WHERE子句。完成针对该“临时”结果集的所有查询后,根据该GUID执行DELETE。如果由于某种原因,针对特定结果集的查询已断开且您不知道最后一个执行的时间,请将DATETIME字段添加到结果集并创建SQL代理作业以删除超过30或60分钟的记录或其他任何内容
编辑: 另外,要明确的是,如果所有查询都是通过单个连接完成的,那么如果您启用MARS(多个活动结果集),那么可能仍然可以使用临时表MARS保持一致的会话,但我不确定,因为我从未使用它。