Работа с временными таблицами в ASP.NET MVC - PullRequest
2 голосов
/ 12 апреля 2011

Справочная информация:

В настоящее время я пишу веб-интерфейс для анализа наших веб-журналов, которые вставляются в SQL Server.

Одна из самых основных функций заключается в том, что вы можете искать набор результатов, указав временные рамки (обычно это инструмент для устранения неполадок недавнего трафика, а не глубокого анализа данных), а затем различные другие поля, такие как 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);

Где предложения WHERE генерируются на основе параметров GET, передаваемых в контроллер, что-то вроде:

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;, и я просто отображаю результаты в div с помощью jquery и плагина DataTable, поскольку наборы результатов, как правило, должны быть небольшими.

Теперь, на мой вопрос:

Что бы мне также хотелось, чтобы у него была куча запросов, которые запрашивают набор результатов вышеупомянутого поиска (сколько обращений к каждому серверу, среднее время ответа и т. Д.).

Я предполагаю, что способ сделать это - создать временную таблицу с результатами (поскольку, если бы я этого не сделал, мне пришлось бы генерировать базовые результаты для каждого из этих запросов по таким вещам, как время отклика для набора результатов ), но так как я новичок в этом, 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;

1 Ответ

2 голосов
/ 12 апреля 2011

Временная таблица не будет действовать после сеанса БД, в котором она была создана.Глобальная временная таблица может совместно использоваться между сеансами БД, но в зависимости от вашего сценария она может быть непредсказуемой, когда сеансы начинаются и заканчиваются, что может не дать предсказуемых результатов.

Я бы предложил создать реальную таблицу для хранениярезультаты и просто запросить это.Когда запросы выполнены, просто УДАЛИТЕ все данные.Если возможно иметь несколько соединений с использованием разных наборов результатов (следовательно, Temp Table была бы полезной), то вы можете добавить поле UNIQUEIDENTIFIER в качестве «ключа», для которого набор данных будет использоваться для этого набора запросов.Это означает, что сгенерируйте GUID на стороне приложения и передайте его в запрос, который заполняет реальную таблицу, чтобы каждый из запросов к нему мог использовать это сгенерированное приложением значение в качестве дополнительного предложения WHERE.Когда все запросы к этому «временному» набору результатов выполнены, выполните УДАЛЕНИЕ на основе этого GUID.Если по какой-либо причине запросы к определенному набору результатов отключены, и вы не знаете, когда выполняется последний, добавьте поле DATETIME к набору результатов и создайте задание агента SQL для УДАЛЕНИЯ записей старше 30 или 60 минут или любого другого.

Редактировать: Также, чтобы было ясно, ЕСЛИ все запросы действительно выполняются одним соединением, тогда вы могли бы иметь возможность использовать временную таблицу, если вы включите MARS (Несколько активных наборов результатов), поскольку я думаю, что MARS поддерживает постоянную сессию, но я не уверен, поскольку я никогда не использовал ее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...