Скрытые возможности SQL Server


215

Каковы некоторые скрытые возможности SQL Server ?

Например, недокументированные системные хранимые процедуры, уловки для выполнения вещей, которые очень полезны, но недостаточно документированы?


ответы

Спасибо всем за отличные ответы!

Хранимые процедуры

  • sp_msforeachtable: запускает команду с '?' заменяется на каждое имя таблицы (v6.5 и выше)
  • sp_msforeachdb: запускает команду с '?' заменяется на каждое имя базы данных (v7 и выше)
  • sp_who2: точно так же, как sp_who, но с гораздо большей информацией для блоков устранения неполадок (v7 и выше)
  • sp_helptext: если вам нужен код хранимой процедуры, просмотрите & UDF
  • sp_tables: возвращает список всех таблиц и представлений базы данных в области видимости.
  • sp_stored_procedures: вернуть список всех хранимых процедур
  • xp_sscanf: считывает данные из строки в местоположения аргумента, указанные каждым аргументом формата.
  • xp_fixeddrives:: найдите фиксированный диск с наибольшим свободным пространством
  • sp_help: Если вы хотите знать структуру таблицы, индексы и ограничения таблицы. Также просмотров и UDFs. Сочетание клавиш Alt + F1

обрывки

  • Возвращение строк в случайном порядке
  • Все объекты базы данных пользователя по дате последнего изменения
  • Только дата возвращения
  • Найти записи, дата которых находится где-то внутри текущей недели.
  • Найти записи, дата которых произошла на прошлой неделе.
  • Возвращает дату начала текущей недели.
  • Возвращает дату начала прошлой недели.
  • Смотрите текст процедуры, которая была развернута на сервере
  • Отбросьте все соединения с базой данных
  • Контрольная сумма таблицы
  • Контрольная сумма строки
  • Удалите все процедуры в базе данных
  • Повторно сопоставьте идентификаторы входа после восстановления
  • Вызов хранимых процедур из оператора INSERT
  • Найти процедуры по ключевому слову
  • Удалите все процедуры в базе данных
  • Запросите журнал транзакций для базы данных программно.

функции

  • HashBytes ()
  • EncryptByKey
  • Команда PIVOT

Разное

  • Дополнительные строки подключения
  • TableDiff.exe
  • Триггеры для событий входа в систему (Новое в пакете обновления 2)
  • Повышение производительности с помощью сохраняемых вычисляемых столбцов (шт.).
  • Настройка DEFAULT_SCHEMA в sys.database_principles
  • Принудительная параметризация
  • Формат хранения Vardecimal
  • Выяснение самых популярных запросов в считанные секунды
  • Масштабируемые общие базы данных
  • Функция фильтрации таблиц / хранимых процедур в SQL Management Studio
  • Флаги трассировки
  • Номер после GOповторения партии
  • Безопасность с использованием схем
  • Шифрование с использованием встроенных функций шифрования, представлений и базовых таблиц с триггерами

4
Если известно, было бы неплохо включить соответствующие версии с каждым ответом. (2000 и выше, 2005, 2000 только, и т.д.)
м.т.

В этом вопросе много добра. Пожалуйста, не удаляйте его! :-)
Sklivvz

Ответы:


91

В Management Studio вы можете поставить число после маркера окончания партии GO, чтобы партия повторялась столько раз:

PRINT 'X'
GO 10

Напечатает 'X' 10 раз. Это может спасти вас от утомительного копирования / вставки при выполнении повторяющихся вещей.


70

Многие разработчики SQL Server до сих пор не знают о предложении OUTPUT (SQL Server 2005 и новее) в операторах DELETE, INSERT и UPDATE.

Может быть чрезвычайно полезно знать, какие строки были INSERTed, UPDATEd или DELETEd, и предложение OUTPUT позволяет сделать это очень легко - оно предоставляет доступ к «виртуальным» таблицам, вызываемым insertedи deleted(как в триггерах):

DELETE FROM (table)
OUTPUT deleted.ID, deleted.Description
WHERE (condition)

Если вы вставляете значения в таблицу, имеющую поле первичного ключа INT IDENTITY, с помощью предложения OUTPUT, вы можете сразу же получить вставленный новый идентификатор:

INSERT INTO MyTable(Field1, Field2)
OUTPUT inserted.ID
VALUES (Value1, Value2)

И если вы обновляете, может быть чрезвычайно полезно знать, что изменилось - в этом случае insertedпредставляет новые значения (после ОБНОВЛЕНИЯ), а deletedссылается на старые значения до ОБНОВЛЕНИЯ:

UPDATE (table)
SET field1 = value1, field2 = value2
OUTPUT inserted.ID, deleted.field1, inserted.field1
WHERE (condition)

Если будет возвращено много информации, вывод OUTPUT также может быть перенаправлен во временную таблицу или табличную переменную ( OUTPUT INTO @myInfoTable).

Чрезвычайно полезно - и очень мало известно!

Марк


52

sp_msforeachtable: Запускает команду с '?' заменяется на каждое имя таблицы. например

exec sp_msforeachtable "dbcc dbreindex('?')"

Вы можете выполнить до 3 команд для каждой таблицы

exec sp_msforeachtable
    @Command1 = 'print ''reindexing table ?''',
    @Command2 = 'dbcc dbreindex(''?'')',
    @Command3 = 'select count (*) [?] from ?'

Также, sp_MSforeachdb


2
Вы можете получить имя таблицы в запросе, используя одинарные кавычки вокруг знака вопроса. sp_msforeachtable "выберите количество (*), '?' как табенм из?
Джоди

51

Дополнительная строка подключения:

MultipleActiveResultSets = TRUE;

Это позволяет ADO.Net 2.0 и выше считывать несколько наборов результатов только для пересылки и только для чтения на одном соединении с базой данных, что может повысить производительность, если вы много читаете. Вы можете включить его, даже если вы делаете смесь типов запросов.

Имя приложения = MyProgramName

Теперь, когда вы хотите просмотреть список активных соединений, выполнив запрос к таблице sysprocesses, имя вашей программы появится в столбце имя_программы вместо ".Net SqlClient Data Provider"


7
Я сделал имя приложения обязательным требованием в моей компании. Каждое новое приложение должно иметь уникальное имя. Упрощает отслеживание того, какое приложение заблокировало / сломало что-то.
Нил Н

2
Имя приложения также доступно в качестве фильтра в профилировщике. Это очень помогает, если вы хотите видеть только ваши запросы, а не запросы ваших коллег.
Матиас Ф

33

TableDiff.exe

  • Инструмент Различия в таблицах позволяет обнаруживать и согласовывать различия между исходной и целевой таблицами или представлением. Утилита Tablediff может сообщать о различиях в схеме и данных. Самая популярная особенность tablediff - это то, что он может генерировать скрипт, который вы можете запустить в месте назначения, чтобы согласовать различия между таблицами.

Ссылка на сайт


31

Менее известный метод TSQL для возврата строк в случайном порядке:

-- Return rows in a random order
SELECT 
    SomeColumn 
FROM 
    SomeTable
ORDER BY 
    CHECKSUM(NEWID())

6
Отлично подходит для небольших наборов результатов. Я бы не использовал его в таблице с более чем 10000 строками, если у вас нет свободного времени
Джон Шиэн

Я использовал его на столах гораздо больших размеров, и это было не слишком медленно.
Mitch Wheat

Какова цель контрольной суммы ()? Вы можете заказать, просто NEWID ().
Джонас Линкольн

6
Я даже видел приличные результаты на 100 000 000 (100 мил) строк без CHECKSUM (). Кроме того, я должен спросить, почему бы не просто заказать по NEWID?
Трой Демонбрюн

5
@GateKiller: я откатил ваши изменения, потому что контрольная сумма () не является ошибкой; это уменьшает размер столбца сортировки.
Mitch Wheat

30

В Management Studio вы можете быстро получить разделенный запятыми список столбцов для таблицы:

  1. В обозревателе объектов разверните узлы под данной таблицей (чтобы вы увидели папки для столбцов, ключей, ограничений, триггеров и т. Д.)
  2. Укажите папку Columns и перетащите в запрос.

Это удобно, если вы не хотите использовать отвратительный формат, возвращаемый путем щелчка правой кнопкой мыши по таблице и выбора «Сценарий таблицы как ...», а затем «Вставить в ...». Этот прием работает с другими папками, поскольку он дает вам разделенный запятыми список имен, содержащихся в папке.


23

Конструкторы строк

Вы можете вставить несколько строк данных с помощью одного оператора вставки.

INSERT INTO Colors (id, Color)
VALUES (1, 'Red'),
       (2, 'Blue'),
       (3, 'Green'),
       (4, 'Yellow')

Я проголосовал за это, но затем попробовал это в MSSQL 2005, и это не работает. Только 2008?
Richardtallent

11
Да, это новая функция 2008 года.
Роб Бок

2
Эту функцию я упустил, когда пришел с DB2 на SQL Server. В DB2 произошло значительное улучшение скорости при использовании этого вместо отдельных операторов вставки
Натан Куп

22

Если вы хотите знать структуру таблицы, индексы и ограничения:

sp_help 'TableName'

Объедините этот совет с его сочетанием клавиш! Сначала выделите имя таблицы, а затем нажмите ALT + F1
Майкл Дж Сварт

22

HashBytes () для возврата хеша своего ввода MD2, MD4, MD5, SHA или SHA1.


Хороший! Правильная ссылка: msdn.microsoft.com/en-us/library/ms174415(SQL.90).aspx (версия 2005 г.)
Sklivvz

Вы правы, это была версия документации в 2008 году, хотя страницы в значительной степени идентичны. Исправлено сейчас.
Джоэл Коухорн

20

Выяснение самых популярных запросов

  • С помощью sys.dm_exec_query_stats вы можете определить множество комбинаций анализа запросов по одному запросу.

Связь с комнадом

select * from sys.dm_exec_query_stats 
order by execution_count desc

17

7
Я видел Иисуса в результатах моего запроса!
P Daddy

6
Пффф ... Какой болван тратит свое время, балуясь вкладкой пространственных результатов. Ой, подождите ... Вы знаете, я думал, что этот пост выглядел знакомым, теперь я помню, почему.
Майкл Дж Сварт

16

ИСКЛЮЧИТЬ И ИНТЕРСЕКТ

Вместо написания сложных объединений и подзапросов эти два ключевых слова являются гораздо более элегантным сокращением и удобочитаемым способом выражения намерения вашего запроса при сравнении двух результатов запроса. Начиная с SQL Server 2005, они сильно дополняют UNION, который существует уже несколько лет в языке TSQL.

Концепции EXCEPT, INTERSECT и UNION являются фундаментальными в теории множеств, которая служит основой и основой реляционного моделирования, используемого всеми современными СУБД. Теперь результаты типа диаграммы Венна могут быть более интуитивно понятными и легко генерируемыми с помощью TSQL.


16

Я знаю, что это не совсем скрыто, но не так много людей знают о команде PIVOT . Мне удалось изменить хранимую процедуру, в которой использовались курсоры, и потребовалось 2 минуты, чтобы запустить быстрый 6-секундный фрагмент кода, который был в десять раз меньше числа строк!


16

полезно при восстановлении базы данных для целей тестирования или чего-либо еще. Корректно сопоставляет идентификаторы входа в систему:

EXEC sp_change_users_login 'Auto_Fix', 'Mary', NULL, 'B3r12-36'

У меня раньше этот процесс не работал, и мне пришлось сменить владельца объектов на временного пользователя, удалить первоначального пользователя, повторно добавить оригинал и вернуть право собственности. Тьфу ...
StingyJack

15

Отбросьте все соединения с базой данных:

Use Master
Go

Declare @dbname sysname

Set @dbname = 'name of database you want to drop connections from'

Declare @spid int
Select @spid = min(spid) from master.dbo.sysprocesses
where dbid = db_id(@dbname)
While @spid Is Not Null
Begin
        Execute ('Kill ' + @spid)
        Select @spid = min(spid) from master.dbo.sysprocesses
        where dbid = db_id(@dbname) and spid > @spid
End

Есть ли однострочный или удаленный параметр базы данных, который делает это для меня? Я заметил, что если вы пытаетесь «удалить базу данных» через пользовательский интерфейс, есть флажок «закрыть существующие подключения», который подразумевает, что это логический параметр.
DevinB

1
На самом деле, я только что нашел решение в две строки. ALTER DATABASE [@ DATABASE_NAME @] SET READ_ONLY с Rollback Немедленное --this разъединяет всех пользователей ALTER DATABASE [@ DATABASE_NAME @] SET READ_WRITE С ROLLBACK IMMEDIATE DROP DATABASE [@ DATABASE_NAME @]
DevinB

1
ALTER DATABASE MyDB SET SINGLE_USER WITH ROLLBACK IMMEDIATEтакже предотвратит возникновение новых подключений.
ErikE

15

Контрольная сумма таблицы

Select CheckSum_Agg(Binary_CheckSum(*)) From Table With (NOLOCK)

Контрольная сумма строки

Select CheckSum_Agg(Binary_CheckSum(*)) From Table With (NOLOCK) Where Column = Value

2
Это позволяет вам создать контрольную сумму для всех данных в таблице. Это простой и быстрый способ проверить, совпадают ли две строки или две таблицы.
GateKiller,

15

Я не уверен, является ли это скрытой функцией или нет, но я наткнулся на это и обнаружил, что это полезно во многих случаях. Вы можете объединить набор полей в одном операторе выбора, а не использовать курсор и циклически проходить через оператор выбора.

Пример:

DECLARE @nvcConcatonated nvarchar(max)
SET @nvcConcatonated = ''

SELECT @nvcConcatonated = @nvcConcatonated + C.CompanyName + ', '
FROM tblCompany C
WHERE C.CompanyID IN (1,2,3)

SELECT @nvcConcatonated

Полученные результаты:

Acme, Microsoft, Apple,

2
Вы также можете использовать COALESCE (), чтобы сделать то же самое без необходимости инициализировать переменную. SELECT @nvcConcatonated = COALESCE (@nvcConcatonated + ',', '') + CAST (C.CompanyName as VARCHAR (255)) ИЗ ...
Кристофер Кляйн,

Это также работает в обновлении заявления. Иногда полезно делать такие вещи, как объединение списка идентификаторов, которые были обновлены.
EBarr

14

Если вам нужен код хранимой процедуры, вы можете:

sp_helptext 'ProcedureName'

(не уверен, что это скрытая функция, но я использую ее все время)


Не знаю почему, но вывод sp_helptext немного глуповат на любых слишком длинных строках оригинала. При создании сценариев Sprocs этого не происходит, так что, может быть, существует другой, более надежный механизм экспорта? sp_helptext 'MyView' также полезно.
Кристен

Я не уверен, что ты имеешь в виду. Для меня код SP выдаётся в том же формате, в котором я их написал в оригинальном файле (со всеми CR и т. Д.)
Эдуардо

Я не помню точных деталей, но это связано с тем, как хранится текст - я думаю, что-то с размером страницы. Вывод в основном правильный, но время от времени вы получаете дополнительный разрыв строки.
RolandTumble

13

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

CREATE TABLE #toto (v1 int, v2 int, v3 char(4), status char(6))
INSERT #toto (v1, v2, v3, status) EXEC dbo.sp_fulubulu(sp_param1)
SELECT * FROM #toto
DROP TABLE #toto

1
К сожалению, нельзя использовать с @TableVariable
Кристен

Проблема с этой очень полезной техникой заключается в том, что в отличие от большинства таблиц, вы должны полностью определить все столбцы. Ленивый способ сделать это - создать #table внутри proc, который вы вызываете в самом конце, затем sp_help в tempdb, скопировать и вставить, удалить код из proc. Готово
чеснок Адольфа

12

В SQL Server 2005/2008 для отображения номеров строк в результате запроса SELECT:

SELECT ( ROW_NUMBER() OVER (ORDER BY OrderId) ) AS RowNumber,
        GrandTotal, CustomerId, PurchaseDate
FROM Orders

ORDER BY является обязательным условием. Предложение OVER () указывает SQL Engine сортировать данные по указанному столбцу (в данном случае OrderId) и назначать числа в соответствии с результатами сортировки.


было бы проще, если бы они использовали синтаксический suger в движке sql для синтаксического анализа его синтаксического слова как «RowNumberInTable»
нет

1
+1 для оконных функций. Вы можете делать что-то НАД подмножеством записей, используя OVER (PARTITION BY ...) msdn.microsoft.com/en-us/library/ms189461%28v=SQL.100%29.aspx
Мэтт Стивенсон,

10

Полезно для анализа аргументов хранимой процедуры: xp_sscanf

Считывает данные из строки в местоположения аргумента, указанные каждым аргументом формата.

В следующем примере xp_sscanf используется для извлечения двух значений из исходной строки на основе их позиций в формате исходной строки.

DECLARE @filename varchar (20), @message varchar (20)
EXEC xp_sscanf 'sync -b -fproducts10.tmp -rrandom', 'sync -b -f%s -r%s', 
  @filename OUTPUT, @message OUTPUT
SELECT @filename, @message

Вот набор результатов.

-------------------- -------------------- 
products10.tmp        random

4
У меня должно быть тупой момент (нет, правда). Можете ли вы сказать мне, где мы можем использовать это?
Радж Море

9

Только дата возвращения

Select Cast(Floor(Cast(Getdate() As Float))As Datetime)

или

Select DateAdd(Day, 0, DateDiff(Day, 0, Getdate()))

Короткая версия - ВЫБЕРИТЕ CAST (FLOOR (CAST (@DateTime AS FLOAT)) AS DATETIME)
Meff

Да, черт возьми. CASTFLOORCAST правила.
StingyJack

Не могу найти ссылку на него, но мне кажется, что я помню тесты, которые предполагали, что SELECT DateAdd (Day, 0, DateDiff (Day, 0, @DateTime)) был быстрее. Рад быть просветленным, в любом случае!
Кристен

Нашел этот sqlteam.com/forums/topic.asp?TOPIC_ID=35296#107617, но он не включал метод CAST / FLOOR. Неформальный тест для набора записей среднего размера показывает, что DATEADD может быть примерно на 7% быстрее, чем CAST / FLOOR - этого недостаточно для беспокойства в большинстве ситуаций
Кристен,

Однако я добавил другой метод; мое быстрое тестирование показывает, что метод литья пола на 800 наносекунд быстрее. Так что ничего особенного в этом нет.
GateKiller

9

dm_db_index_usage_stats

Это позволяет узнать, были ли недавно обновлены данные в таблице, даже если в таблице нет столбца DateUpdated.

SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID( 'MyDatabase')
AND OBJECT_ID=OBJECT_ID('MyTable')

Код от: http://blog.sqlauthority.com/2009/05/09/sql-server-find-last-date-time-updated-for-any-table/

Информация, на которую ссылаются: SQL Server - Какова дата / время последней вставленной строки таблицы?

Доступный в SQL 2005 и позже


7

Вот некоторые функции, которые я считаю полезными, но многие люди не знают о них:

sp_tables

Возвращает список объектов, которые могут быть запрошены в текущей среде. Это означает любой объект, который может появиться в предложении FROM, кроме объектов синонимов.

Ссылка на сайт

sp_stored_procedures

Возвращает список хранимых процедур в текущей среде.

Ссылка на сайт


7

Найти записи, дата которых находится где-то внутри текущей недели.

where dateadd( week, datediff( week, 0, TransDate ), 0 ) =
dateadd( week, datediff( week, 0, getdate() ), 0 )

Найти записи, дата которых произошла на прошлой неделе.

where dateadd( week, datediff( week, 0, TransDate ), 0 ) =
dateadd( week, datediff( week, 0, getdate() ) - 1, 0 )

Возвращает дату начала текущей недели.

select dateadd( week, datediff( week, 0, getdate() ), 0 )

Возвращает дату начала прошлой недели.

select dateadd( week, datediff( week, 0, getdate() ) - 1, 0 )

Хорошо, но индекс TransDate не будет использоваться. Я бы лучше написал
vaso

где TransDate> = convert (datetime, floor (convert (float, dateadd (день, -datepart (weekday, @date) +1, @date)))) и TransDate> = convert (datetime, floor (преобразовать (float, dateadd) (день, 7-й день (день недели, @date) +1, @date))))
vaso

коррекция: где TransDate> = convert (datetime, floor (convert (float, dateadd (день, -datepart (weekday, @date) +1, @date))))) и TransDate <convert (datetime, floor (convert (float, dateadd (день, 7-дата, часть (день недели, @date) +1, @date))))
vaso

7

Не столько скрытая функция, сколько настройка сопоставления клавиш в Management Studio в разделе Инструменты \ Параметры \ Клавиатура: по умолчанию для Alt + F1 используется sp_help «выделенный текст», но я не могу жить без добавления Ctrl + F1 для sp_helptext «выделенный текст»


Я использую также для настройки команды USE, для перемещения по БД
Джонни Д. Кано-Leftware-

7

Сохранялся вычисленным-столбцы

  • Вычисляемые столбцы могут помочь вам перенести стоимость вычислений во время выполнения на этап модификации данных. Вычисляемый столбец сохраняется с остальной частью строки и прозрачно используется, когда выражение в вычисляемых столбцах и запрос совпадают. Вы также можете создавать индексы на PCC для ускорения фильтрации и сканирования диапазона выражения.

Ссылка на сайт


7

Бывают случаи, когда нет подходящего столбца для сортировки, или вам просто нужен порядок сортировки по умолчанию для таблицы, и вы хотите перечислить каждую строку. Для этого вы можете поместить «(выберите 1)» в предложение «упорядочить по», и вы получите то, что хотите. Аккуратно, а?

select row_number() over (order by (select 1)), * from dbo.Table as t

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.