Приховані особливості 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: Якщо ви хочете знати структуру таблиці, індекси та обмеження таблиці. Також перегляди та UDF. Ярлик - Alt + F1

Сніппети

  • Повернення рядків у випадковому порядку
  • Усі об'єкти користувача бази даних за останньою зміненою датою
  • Тільки дата повернення
  • Знайдіть записи, дата яких припадає десь на поточному тижні.
  • Знайдіть записи, дата яких відбулася минулого тижня.
  • Повертає дату початку поточного тижня.
  • Повертає дату початку минулого тижня.
  • Дивіться текст процедури, розгорнутої на сервер
  • Відкиньте всі підключення до бази даних
  • Столова контрольна сума
  • Рядна контрольна сума
  • Відкиньте всі процедури в базу даних
  • Після відновлення повторно зіставіть ідентифікатори для входу
  • Виклик збережених процедур з заяви INSERT
  • Знайдіть процедури за ключовим словом
  • Відкиньте всі процедури в базу даних
  • Запросити журнал транзакцій для бази даних програмно.

Функції

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

Різне

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

4
Якщо відомо, було б непогано включити відповідні версії з кожною відповіддю. (2000 р. І вище, 2005, 2000 рр. Лише тощо)
bw

У цьому питанні багато добра. Будь ласка, не видаляйте його! :-)
Склівз

Відповіді:


91

У студії управління ви можете поставити число після маркера закінчення партії GO, щоб викликати повтор партії таку кількість разів:

PRINT 'X'
GO 10

Буде надруковано "X" 10 разів. Це може врятувати вас від копіткої копії / вклеювання, коли робите повторювані речі.


70

Багато розробників SQL Server все ще не знають про пункт OUTPUT (SQL Server 2005 і новіші) у операторах DELETE, INSERT та UPDATE.

Це може бути надзвичайно корисно знати, які рядки були ВСТАНОВЛЕНІ, 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 "select count (*), '?" як tabenm з? "
Джоді

51

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

MultipleActiveResultSets = вірно;

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

Назва програми = MyProgramName

Тепер, коли ви хочете побачити список активних з'єднань, запитуючи таблицю системних процесів, ім’я програми з’явиться в стовпці_імен_програма замість ".Net SqlClient Provider Data"


7
Я зробив назву заявки вимогою у своїй компанії. Кожен новий додаток повинен мати унікальне ім’я. Здійснює відстеження, яку програму заблокували / зламали щось набагато простіше.
Ніл N

2
Назва програми також доступна як фільтр у профілі. Це дуже допомагає, якщо ви хочете бачити лише ваші запити, а не запити своїх колег.
Mathias F

33

TableDiff.exe

  • Інструмент «Різниця таблиць» дозволяє виявити та вирівняти відмінності між початковою та цільовою таблицею або поданням. Утиліта Tablediff може повідомляти про відмінності на схемі та даних. Найпопулярнішою особливістю tablediff є той факт, що він може генерувати сценарій, який можна запустити в пункті призначення, який вирівняє відмінності між таблицями.

Посилання


31

Менш відома техніка TSQL для повернення рядків у випадковому порядку:

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

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

Я використовував його на набагато більших таблицях, і це було не надто повільно.
Мітч пшениця

Яка мета CHECKSUM ()? Ви можете замовити просто NEWID ().
Йонас Лінкольн

6
Я навіть бачив гідні результати на 100 000 000 (100 мільйонів) рядків, без CHECKSUM (). Крім того, я також повинен запитати, чому б не просто ЗАМОВИТИ NEWID?
Troy DeMonbreun

5
@GateKiller: Я відмовив вашу редакцію, тому що Checksum () не є помилкою; це зменшує розмір стовпця сортування.
Мітч Пшеничний

30

У студії управління ви можете швидко отримати список стовпців для таблиці, розділених комами:

  1. У Провіднику об’єктів розгорніть вузли під заданою таблицею (так ви побачите папки для стовпців, ключів, обмежень, тригерів тощо)
  2. Наведіть курсор на папку Стовпці та перетягніть запит.

Це зручно, коли ви не хочете використовувати жахливий формат, повернений, клацнувши правою кнопкою миші на таблиці та вибравши таблицю сценаріїв як ..., а потім Вставити в ... Цей трюк працює з іншими папками, оскільки він дасть вам перелік розділених комами імен, що містяться в папці.


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 відбулося значне покращення швидкості при використанні цього замість окремих операторів вставки
Nathan Koop

22

Якщо ви хочете знати структуру таблиці, індекси та обмеження:

sp_help 'TableName'

Поєднайте цю пораду за допомогою клавіші швидкого доступу! Спочатку виділіть назву таблиці, а потім натисніть ALT + F1
Michael J Swart

22

HashBytes () для повернення хеша MD2, MD4, MD5, SHA або SHA1 свого вводу.


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

Ви маєте рацію, що це була версія версії документів 2008 року, хоча сторінки майже однакові. Виправлено зараз.
Joel Coehoorn

20

З'ясування найпопулярніших запитів

  • За допомогою sys.dm_exec_query_stats ви можете визначити безліч комбінацій аналізів запитів за допомогою одного запиту.

Посилання з комнадою

select * from sys.dm_exec_query_stats 
order by execution_count desc

17

7
Я бачив Ісуса в результатах мого запиту!
П тато

6
Pfff ... Який шматок витрачає час, возившись із вкладкою просторових результатів. О, зачекайте ... Ви знаєте, я думав, що цей пост виглядає знайомим, тепер я пам'ятаю, чому.
Michael J Swart

16

ВИКЛИЧНІ та ІНТЕРЕСНІ

Замість того, щоб писати детальні приєднання та підзапити, ці два ключові слова є набагато більш елегантним скороченням і читабельним способом вираження намірів вашого запиту при порівнянні двох результатів запиту. Як і в SQL Server 2005, вони сильно доповнюють UNION, який вже існує роками в мові TSQL.

Концепції EXCEPT, INTERSECT та UNION є основоположними в теорії множин, яка служить основою та основою реляційного моделювання, що використовується всіма сучасними RDBMS. Тепер результати типу діаграми Венна можна інтуїтивніше і досить легко генерувати за допомогою TSQL.


16

Я знаю, що це не зовсім приховано, але не дуже багато людей знають про команду PIVOT . Я зміг змінити збережену процедуру, яка використовувала курсори, і мені знадобилося 2 хвилини, щоб перейти на швидкий шматок 6 секунд коду, який становив одну десяту кількість рядків!


16

корисно при відновленні бази даних для цілей тестування чи будь-чого іншого. Переназначте правильне ідентифікатор входу:

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

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

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

Я не впевнений, це прихована особливість чи ні, але я натрапив на це, і вважаю, що це корисно у багатьох випадках. Ви можете конкретизувати набір поля в одному операторі вибору, а не використовувати курсор і перебирати через оператор select.

Приклад:

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 @nvcConcatonized = COALESCE (@nvcConcatonized + ',', '') + CAST (C.CompanyName як VARCHAR (255)) ВІД ...
Крістофер Кляйн

Це також працює в операторі оновлення. Іноді корисно робити такі дії, як об'єднання списку ідентифікаторів, які були оновлені.
EBarr

14

Якщо ви хочете код збереженої процедури, ви можете:

sp_helptext 'ProcedureName'

(не впевнений, чи це прихована функція, але я її постійно використовую)


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

Я не впевнений, що ти маєш на увазі. Для мене код SP виписується в тому самому форматі, який я написав у оригінальному файлі (з усіма КР тощо)
Едуардо Молтені,

Я не пам'ятаю точних деталей, але це стосується способу зберігання тексту - я вважаю, що це стосується розміру сторінки. Вихідний результат в основному правильний, але раз у раз ви отримуєте додатковий розрив рядка.
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
Kristen

Біль при цій дуже корисній техніці полягає в тому, що на відміну від більшості #tables, ви повинні повністю визначити всі стовпці. Ледачий спосіб зробити це - створити # table всередині прок-коду, який ви телефонуєте, в кінці, а потім sp_help в tempdb, скопіюйте та вставте, видаліть код з proc. Готово
часник адольфа

12

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

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

ЗАМОВЛЕННЯ - це обов'язкове застереження. Пункт OVER () вказує SQL Engine на сортування даних у вказаному стовпці (у цьому випадку OrderId) та присвоєння номерів за результатами сортування.


не було б простіше, якби вони використали синтаксичний suger в sql engine, щоб розібрати його слово синтаксису як "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
У мене, мабуть, є німий момент (ні, насправді). Чи можете ви сказати мені, де ми можемо це використати?
Raj More

9

Тільки дата повернення

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

або

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

Коротка версія - ВИБІРТЕ КАСТ (ПІДКЛЮЧЕННЯ (@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-update-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 не буде використовуватися. Я б краще писав
вазо

де TransDate> = перетворити (datetime, floor (конвертувати (float, dateadd (день, -datepart (dayday, @date) +1, @date)))) і TransDate> = convert (datetime, floor (convert (float, dateadd) (день, 7-денна частина (будній день, @ дата) +1, @ дата))))
vaso

виправлення: де TransDate> = перетворити (datetime, floor (конвертувати (float, dateadd (день, -datepart (dayday, @date) +1, @date))))) і TransDate <convert (datetime, floor (convert (float, dateadd (день, 7-datepart (будній день, @date) +1, @date))))
vaso

7

Не стільки прихована функція, але налаштування відображень ключів у студії управління в розділі Інструменти \ Параметри \ Клавіатура: Alt + F1 за замовчуванням спричиняє sp_help "вибраний текст", але я не можу жити без додавання Ctrl + F1 для sp_helptext "вибраного тексту"


Я використовую для налаштування команди USE також для переміщення по DB
Jhonny D. Cano -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.