2010-12-13 3 views
0

В SQL Server 2008 у меня есть приложение, в котором пользователи могут запускать запросы к базе данных. Я хочу, чтобы они не запускали запрос, который будет возвращать миллионы результатов и ресурсов системы налогообложения. В настоящее время решение обертка любой запрос ввода в счете функция (*), как так:Общий синтаксис столбца SQL Server

Select count(*) as COUNT 
from (SELECT SOMETHING FROM SOMETABLE) as TMPCOUNT0; 

отлично работает до тех пор, пока пользователь не пытается запустить COUNT(*) самостоятельно.

Select count(*) as COUNT 
from (SELECT COUNT(*) FROM SOMETABLE) as TMPCOUNT0; 

--(should return 1) 

Однако SQL Server не нравится, что мой внутренний COUNT(*) столбец не имеет имени в моей производной таблицы и ошибки с помощью:

Нет Имя столбца не было указано для столбца 1 «TMPCOUNT0».

Я знаю, что я мог бы исправить это, если бы я при выполнении запроса, указав имя для внутреннего счета, но так как конечные пользователи не знают об этом, я надеюсь найти более элегантное решение.

Любые идеи?

+0

Я всегда делаю это: SELECT count ('x') FROM SOMETABLE; он не должен извлекать ни один столбец. Я бы не использовал count() дважды. –

+0

@ Эрик К. Юнг: это городской миф, что 'COUNT (1)' более эффективен, чем 'COUNT (*)' - оптимизатор запросов SQL Server достаточно умен, чтобы понять, что это всего лишь операция COUNT - это не будет «извлекать» все данные только из-за (*) в выражении ... –

+0

@ Эрик К. Юнг, @marc_s: городской миф действительно :-) http://stackoverflow.com/questions/1221559/count-vs- count1/1221649 # 1221649 – gbn

ответ

0

Ошибка

Нет Имя столбца не было указано для столбца 1 'TMPCOUNT0'.

произошло из-за того, что вы не указали имя столбца во внутреннем запросе.

Внутренний запрос должен читаться как

SELECT COUNT(*) **as c** FROM SOMETABLE as TMPCOUNT0 

Этот запрос возвращает 1, но вы должны указать имя псевдонима для этого графа во внутреннем запросе.

Select count(c) as [COUNT] from (SELECT COUNT(*) as c FROM SOMETABLE) as TMPCOUNT0 
+0

Это не поможет OP, так как он не контролирует внутренний запрос. –

+0

другим вариантом было бы получить результат во временной таблице и взять счет оттуда, сделав так, чтобы он мог контролировать результаты. – wizzardz

+0

Построение всей временной таблицы все еще требует неприятностей. –

3

Не знаете, как решить вы COUNT (*) вопрос, но что об ограничении результата, указав

SELECT TOP(1000) ...

или в качестве альтернативы

SET ROWCOUNT 1000

вернуть первый тысяч строк.

4

Перед тем, как существовали Stack Exchange Data Explorer Я играл с небольшим сайтом, чтобы люди могли запускать запросы в общедоступном наборе данных переполнения стека. Мое первоначальное предложение было оснащено Atom 330 с только 2 ГБ оперативной памяти, размещенной у меня дома, и поэтому я очень беспокоился о ограниченных запросах, чтобы они не могли полностью захватить мой сервер и затопить мое домашнее широкополосное соединение.

В чем я оказался в сочетании с опцией SET ROWCOUNT, упомянутой в @Philip Fourie's answer и SET QUERY_GOVERNOR_COST_LIMIT. Последний требует много настроек, и оба могут быть переопределены, если пользователь знает или думает попробовать, поэтому я также выполнил вход в каждый запрос, чтобы я мог заметить злоупотребления.

У этой комбинации есть слабые места, но это работает неплохо.

+0

+1 для QUERY_GOVERNOR_COST_LIMIT - никогда не знал об этом! – egrunin

Смежные вопросы