Цел
Защо да използвате недокументирани master..spt-values
Sybase и следователно неговият копеле MS SQL предоставят различни функции и функции за продукта, който се реализира в системни процедури (за разлика от двоичните файлове като sqlserver, които се стартират като услуга). Тези процедури за системни процедури са написани в SQL код и се наричат sp_%.
С изключение на някои тайни вътрешни елементи, те имат същите ограничения и нужди като всеки друг SQL код. Те са част от продукта Sybase ASE или SQL Server. Като такива те не са задължителни да го документира; и вътрешните битове не могат разумно да бъдат етикетирани като "недокументирани".
master..spt_values
съдържа всички различни битове и части, които са необходими на споменатите системни процедури, в SQL таблица, за да изготвят различните отчети. sp
означава системна процедура; spt
означава таблици за системни процедури; и разбира се values
е съдържанието.
Таблици за справка
Какво е (значението на) Type ='P'
Хората често описват spt_values
като "денормализиран", но това е неправилният термин. Правилният термин е сгънат , или опаковани . Това са около 26 логични справочни таблици, всяка красиво нормализирана, сгънати в една физическа таблица, с Type
колона за разграничаване на логическите таблици.
Сега в нормална база данни това би било груба грешка (просто вижте отговорите за "една таблица за търсене или много"). Но в каталог на сървъри е желателно да замести 26 физически таблици.
-
"L" означава LockType Lookup; "V" означава DeviceType Lookup (V е съкращение от Device в целия сървър); и т.н. Тип "P2" съдържа побитови ординали, за разширяване на битове, които са пакетирани в INT.
-
Необходим е набор от последователни числа в рамките на известни граници, който е наличен под формата на SQL таблица, за да се извърши проекция, която много от системните процедури трябва да направят. Тип „P“ е списък с последователни числа между 0 и 2047.
-
Терминът Проекция се използва тук като технически точното значение, естественият логически смисъл, а не значението на релационната алгебра, което е неестествено.
Следователно има само една цел за spt_values,
да съдържа 26 сгънати, иначе отделни, референтни таблици и една прожекционна таблица.
Разширение
Обикновеното използване на spt_values
тогава е като обикновен справочник или ENUM
маса. Първо, стойностите за търсене:
SELECT * -- list Genders
FROM Gender
Използва се по същия начин, по който Лицето има GenderCode, който трябва да бъде разширен (много разширен, тези странни дни):
SELECT P.*, -- list Person
G.Name -- expand GenderCode to Name
FROM Person P
JOIN Gender G
ON P.GenderCode = G.GenderCode
напр. sp_lock
създава отчет за активни заключвания, показващ типовете заключване като низове имена . Но master..syslocks
съдържа типове заключване като числа , не съдържа тези имена; и ако беше така, щеше да е лошо денормализирана таблица! Ако изпълните заявката (код на Sybase ASE, ще трябва да конвертирате):
SELECT * -- list LockTypes
FROM master..spt_values
WHERE type = "L"
ще забележите 66 числа на LockType и имена в таблицата за търсене. Това позволява sp_lock
за изпълнение на прост код като Person::Gender по-горе:
SELECT spid, -- list Active Locks
DB_NAME(dbid),
OBJECT_NAME(id, dbid),
v.name, -- expand lock name
page,
row
FROM master..syslocks L,
master..spt_values LT
WHERE L.type = LT.number --
AND type = "L" -- LockType Lookup table
ORDER by 1, 2, 3, 4, 5, 6 -- such that perusal is easy
Проекция
Какво е (значението на) Тип ='P'?
Какво е Projection и как се използва?
Кажете, например, вместо активните заключвания, произведени от заявката по-горе, искате списък с всички 66 LockTypes, показващи броя на активните заключвания (или Null). Нямате нужда от курсор или WHILE
цикъл. Можем да проектираме таблицата за търсене на LockType, чрез броят на активните заключвания:
SELECT LT.name, -- list LockTypes
[Count] = ( -- with count
SELECT COUNT(*)
FROM master..syslocks
WHERE type = LT.number
)
FROM master..spt_values LT
WHERE type = "L"
Има няколко метода, това е само един. Друг метод е да използвате извлечена таблица вместо подзаявката. Но все още имате нужда от проекцията.
Това обикновено е това, което spt_values
се използва за разширяване или проекция. Сега, когато знаете, че е там, можете също да го използвате. Безопасно е (в master
база данни) и се използва от почти всички системни процедури, което означава, че системните процедури не могат да се изпълняват без него.
за разделяне на колона?
А, не разбирате кода „Разделяне на една CSV колона на няколко реда“.
-
Забравете за
spt_values
за момент и прегледайте този код отново. Просто се нуждае от списък с последователни числа, така че да може да премине през списъка със стойности в CSV колоната, байт по байт. Кодът се активира само за всеки байт, който е запетая или край на низа. -
Къде да получите набор от последователни числа под формата на SQL таблица, вместо да СЪЗДАВАТЕ такава от нулата и да ВМЕСВАТЕ в нея? Защо,
master..spt_values
разбира се. Ако знаете, че е там. -
(Можете да научите малко за вътрешните елементи на ASE или SQL Server, само като прочетете кода на системните съхранени процедури.)
-
Имайте предвид, че всяко CSV поле в една колона е груба грешка при нормализиране, нарушава 2NF (съдържа повтарящи се стойности) и 1NF (не атомна). Забележете, че не е опакована или сгъната, това е повтаряща се група, не е нормализирана. Едно от многото негативни последици от такава груба грешка е, вместо да се използва прост SQL за навигация в повтарящата се група като редове, трябва да се използва сложен код, за да се определи и извлече съдържанието на ненормализираното CSV поле. Тук
spt_values P
предоставя вектор за този сложен код, което го улеснява.
Каква е ползата от него?
Мисля, че отговорих на това. Ако не го имахте, всяка системна процедура, която изисква списък с числа, ще трябва да СЪЗДАВА временна таблица; и ВМЕСЕТЕ редовете в него; преди да стартирате кода си. Разбира се, липсата на необходимост да изпълнявате тези стъпки, прави системните процедури много по-бързи.
Сега, когато трябва да извършите проекция, напр. календарни дати в бъдещето или каквото и да е, можете да използвате spt_values
, вместо да се налага всеки път да създавате своя собствена временна таблица (или да създавате своя собствена частна постоянна таблица и да я поддържате).