Возможно ли, что Выполнить SQL-запрос без отображения результатов?
like
Select * from Table_Name
после запуска этого запроса результат не должен отображаться на сервере sql.
Возможно ли, что Выполнить SQL-запрос без отображения результатов?
like
Select * from Table_Name
после запуска этого запроса результат не должен отображаться на сервере sql.
Выполнение приведет к возврату набора записей. У него может не быть строк, конечно, но получить результат
Вы можете подавлять строки, но не набор результатов с SET FMTONLY
SET FMTONLY ON
SELECT * FROM sys.tables
SET FMTONLY OFF
SELECT * FROM sys.tables
Никогда не использовал его лично, хотя...
Я удивлен, что никто не придумал ответ: включите опцию "отбросить результаты запроса после исполнения"; Я почти уверен, что это был интервьюер. SET FMT ONLY
- это совсем другое дело IMHO.
В SSMS
Причина, по которой вы, возможно, захотите сделать это, - это не дожидаться и тратить ресурсы для того, чтобы результаты были загружены в сетку, но все же иметь возможность, например, Фактический план выполнения.
Звучит как сомнительный вопрос для меня. Я сделал это, мне нужно было это сделать, но вам нужно было сделать это только при довольно неясных обстоятельствах. Неясно, но иногда очень важно.
Как говорит @gbn, один программный способ - SET FMTONLY
(спасибо, теперь мне не нужно выкапывать его из старых файлов script). Некоторые программы и утилиты делают это при запросе SQL; сначала они отправляют запрос с FMTONLY ON, чтобы определить макет результирующей структуры таблицы, а затем, когда они подготовили, что они запускают его с FMTONLY OFF, чтобы получить фактические данные. (Я обнаружил это, когда процедура называлась второй процедурой, вторая процедура вернула набор данных, а по неясным причинам весь дом карточек упал.)
Это также можно сделать в SSMS. Для всех окон запросов в разделе "Инструменты/Параметры", "Результаты запроса /SQL Server/Results to XX" установите флажок "Отменить результаты после выполнения запроса"; только для текущего окна, в разделе "Параметры запроса/запроса", "Результаты/XX", тот же флажок. Преимущество здесь в том, что запрос будет выполняться на сервере базы данных, но результаты данных не будут возвращены. Это может быть неоценимым, если вы проверяете план запроса, но не хотите получать полученные 10 ГБ данных (по всей сети на свой ноутбук) или если вы проводите серьезное циклическое тестирование, поскольку SSMS может принимать только так много наборов результатов от заданного "запуска" перед остановкой запроса с сообщением "слишком много результирующих наборов". [Хм, double- проверьте меня на том, что "только план запроса" bit-- Я думаю, что он делает это, но это было долгое время.]
insert anothertable
Select * from Table_Name
Выполняет выбор, но ничего не возвращает
set noexec on
Select * from Table_Name
Парсы, но не выполняет и так ничего не возвращает.
Возможно, интервьюер хотел задать другой вопрос:
Как выполнить SQL-запрос, не возвращая количество результатов?
В этом случае ответ будет SET NOCOUNT ON
.
Если вам нужен запрос для выполнения, но не нужен фактический набор результатов, вы можете обернуть запрос в EXISTS (или NOT EXISTS): IF EXISTS (SELECT * FROM TABLE_NAME...). Или поочередно вы можете выбрать INTO #temp, а затем отбросить временную таблицу.
Является ли цель подавлять все строки? Затем используйте фильтр, который оценивается как false для каждой строки:
SELECT * FROM Table_Name WHERE 1 = 2
В моем случае я тестировал, что данные ведут себя во всех представлениях, например. любые функции cast() не вызывают ошибок преобразования и т.д., так что подавление фактических данных не было вариантом, отображение было не слишком плохим, но немного потерянным ресурсом и лучше не выполнять diplsay при отправке результатов только в текст.
Я придумал следующий script, чтобы протестировать все представления таким образом, единственная проблема заключается в том, что он сталкивается с представлениями, у которых есть столбцы text/ntext.
declare csr cursor local for select name from sys.views order by name
declare @viewname sysname
declare @sql nvarchar(max)
open csr
fetch next from csr into @viewname
while @@fetch_status = 0 begin
--set @sql = 'select top 1 * from ' + @viewname
set @sql = 'declare @test nvarchar(max) select @test = checksum(*) from ' + @viewname
print @viewname
exec sp_executesql @sql
fetch next from csr into @viewname
end
close csr
deallocate csr
Еще один пример использования - это просто, когда вы просто хотите прочитать все строки таблицы, например, тестирование на повреждение. В этом случае вам не нужны сами данные, только тот факт, что он читабельен или нет. Однако имя опции "Отменить результаты ПОСЛЕ исполнения" немного запутанно - это говорит мне, что результат получен и только затем отбрасывается. Напротив, он извлекает данные точно, но не сохраняет их в любом месте (по умолчанию строки помещаются в сетку или любой другой вывод, который вы выбрали) - полученные строки отбрасываются "на лету" (а не после выполнения).
Я удивлен, что сообщество не может легко найти прецедент для этого. Большие наборы результатов берут память на клиенте, что может стать проблемой, если многие SSMS-окна активны (для меня нет ничего необычного, чтобы иметь 2- 3 экземпляра SSMS, каждый из которых содержит 50- 70 активных окон). В некоторых случаях, как и в примере Кирилла, SSMS может закончиться нехваткой памяти и просто неспособна обрабатывать большой результирующий набор. Например, у меня был случай, когда мне нужно было отлаживать хранимую процедуру, возвращающую сотни миллионов строк. Невозможно запустить SSMS на моей машине разработки без отбрасывания результатов. Процедура была для пакета SSIS, где он использовался в качестве источника данных для загрузки таблицы хранилища данных. Отладка в SSMS включала в себя выполнение функциональных изменений non- (поэтому набор результатов не представлял для меня интереса) и проверку статистики выполнения и фактических планов выполнения запросов.
Мне нужен был proc, чтобы вернуть все записи, обновленные указанным пользователем, через определенный момент времени, только показывая результаты, где существовали записи. Вот он:
-- Written by David Zanke
-- Return all records modified by a specified user on or after a specified date.
If mod date does not exist, return row anyhow
Set Nocount on
Declare @UserName varchar(128) = 'zanked'
, @UpdatedAfterDate Varchar( 30) = '2016-10-08'
, @TableName varchar( 128)
, @ModUser varchar( 128)
, @ModTime varchar( 128)
, @sql varchar( 2000 )
-- In a perfect world, left join would be unecessary since every row that captures the last mod user would have last mod date.
-- Unfortunately, I do not work in a perfect world and rows w/ last mod user exist w/o last mod date
Declare UserRows Cursor for Select distinct c1.table_name, c1.column_name, c2.column_name From INFORMATION_SCHEMA.COLUMNS c1
Left Join INFORMATION_SCHEMA.COLUMNS c2 On c1.Table_Name = c2.Table_Name And c2.Column_name like '%DTTM_RCD_LAST_UPD%'
Where c1.column_name like '%UPDATED_BY_USER%'
Open UserRows
Fetch UserRows Into @tablename, @ModUser, @ModTime
While ( @@FETCH_STATUS = 0 )
Begin
-- capture output from query into a temp table
Select @sql = 'Select ''' + @TableName + ''' TableName, * Into ##HoldResults From ' + @TableName + ' Where ' + @ModUser + ' = ''' + @userName + ''''
+ Case When @ModTime Is Null Then '' Else ' And ' + @ModTime + ' >= ''' + @UpdatedAfterDate + '''' End
Exec ( @sql)
-- only output where rows exist
If @@ROWCOUNT > 0
Begin
Select * from ##HoldResults
End
Drop Table ##HoldResults
Fetch UserRows Into @tablename, @ModUser, @ModTime
End
Close UserRows;
Deallocate UserRows