Database
 sql >> база данни >  >> RDS >> Database

Основи на табличните изрази, част 10 – Изгледи, SELECT * и промени в DDL

Като част от поредицата за таблични изрази, миналия месец започнах отразяването на изгледите. По-конкретно, започнах отразяването на логическите аспекти на изгледите и сравних техния дизайн с този на извлечените таблици и CTE. Този месец ще продължа отразяването на логическите аспекти на изгледите, като съсредоточа вниманието си върху промените SELECT * и DDL.

Кодът, който ще използвам в тази статия, може да бъде изпълнен във всяка база данни, но в моите демонстрации ще използвам TSQLV5 – същата примерна база данни, която използвах в предишни статии. Можете да намерите скрипта, който създава и попълва TSQLV5 тук, и неговата ER диаграма тук.

Използването на SELECT * във вътрешната заявка на изгледа е лоша идея

В заключителната част на статията от миналия месец зададох въпрос като храна за размисъл. Обясних, че по-рано в поредицата направих случай в полза на използването на SELECT * в изразите на вътрешната таблица, използвани с производни таблици и CTE. Вижте част 3 от поредицата за подробности, ако трябва да опресните паметта си. След това ви помолих да помислите дали същата препоръка все още ще бъде валидна за израза на вътрешната таблица, използван за дефиниране на изглед. Може би заглавието на този раздел вече беше спойлер, но ще кажа отдясно, че с изгледите всъщност е много лоша идея.

Ще започна с изгледи, които не са дефинирани с атрибута SCHEMABINDING, който предотвратява съответните промени в DDL на зависими обекти, и след това ще обясня как нещата се променят, когато използвате този атрибут.

Ще прескоча направо към пример, тъй като това ще бъде най-лесният начин да представя аргумента си.

Използвайте следния код, за да създадете таблица, наречена dbo.T1, и изглед, наречен dbo.V1 въз основа на заявка с SELECT * срещу таблицата:

ИЗПОЛЗВАЙТЕ TSQLV5; ИЗПУСКАНЕ НА ИЗГЛЕД, АКО СЪЩЕСТВУВА dbo.V1; ИЗПУСКАНЕ НА ТАБЛИЦА, АКО СЪЩЕСТВУВА dbo.T1; ИЗПУСКАНЕ НА ТАБЛИЦА dbo.T1( keycol INT NOT NULL ОГРАНИЧЕНИЕ НА ИДЕНТИЧНОСТ PK_T1 ПРАВИЛЕН КЛЮЧ, intcol INT NOT NULL, charcol VARCHAR(1); ВМЕСТЕ В dbo.T1(intcol, charcol) СТОЙНОСТИ (10, 'A'), (20, 'B');GO СЪЗДАДЕТЕ ИЛИ ПРОМЕНЯТЕ ИЗГЛЕЖДАНЕ dbo.V1AS SELECT * ОТ dbo.T1;GO

Обърнете внимание, че в момента таблицата има колоните keycol, intcol и charcol.

Използвайте следния код, за да направите заявка за изгледа:

ИЗБЕРЕТЕ * ОТ dbo.V1;

Получавате следния изход:

keycol intcol charcol----------- ----------- ----------1 10 A2 20 B

Тук няма нищо особено.

Когато създавате изглед, SQL Server записва информация за метаданни в редица каталожни обекти. Той записва някаква обща информация, която можете да потърсите чрез sys.views, дефиницията на изглед, която можете да заявите чрез sys.sql_modules, информация за колони, която можете да заявите чрез sys.columns, и повече информация е достъпна чрез други обекти. Това, което също е от значение за нашата дискусия, е, че SQL Server ви позволява да контролирате разрешенията за достъп спрямо изгледите. Това, за което искам да ви предупредя, когато използвате SELECT * в израза на вътрешната таблица на изгледа, е какво може да се случи, когато промените в DDL бъдат приложени към основните зависими обекти.

Използвайте следния код, за да създадете потребител, наречен user1, и да предоставите на потребителя разрешения да избира колоните keycol и intcol от изгледа, но не и charcol:

ИЗПУСКАНЕ НА ПОТРЕБИТЕЛЯ, АКО СЪЩЕСТВУВА потребител1; СЪЗДАДЕТЕ ПОТРЕБИТЕЛ user1 БЕЗ ВХОД; ПРЕДОСТАВЯ ИЗБОР НА dbo.V1(keycol, intcol) НА потребител1;

В този момент нека да проверим някои от записаните метаданни, свързани с нашия изглед. Използвайте следния код, за да върнете записа, представляващ изгледа от sys.views:

ИЗБЕРЕТЕ SCHEMA_NAME(schema_id) AS schemaname, name, object_id, type_descFROM sys.viewsWHERE object_id =OBJECT_ID(N'dbo.V1');

Този код генерира следния изход:

schemaname name object_id type_desc----------- ----- ----------- ----------dbo V1 130099504 ПРЕГЛЕД 

Използвайте следния код, за да получите дефиницията на изглед от sys.modules:

ИЗБЕРЕТЕ дефиниция ОТ sys.sql_modulesWHERE object_id =OBJECT_ID(N'dbo.V1');

Друга възможност е да използвате функцията OBJECT_DEFINITION по следния начин:

ИЗБЕРЕТЕ OBJECT_DEFINITION(OBJECT_ID(N'dbo.V1'));

Получавате следния изход:

СЪЗДАВАНЕ НА ИЗГЛЕД dbo.V1AS SELECT * ОТ dbo.T1;

Използвайте следния код, за да потърсите дефинициите на колоните на изгледа от sys.columns:

ИЗБЕРЕТЕ име AS column_name, column_id, TYPE_NAME(system_type_id) AS data_typeFROM sys.columnsWHERE object_id =OBJECT_ID(N'dbo.V1');

Както се очаква, получавате информация за трите колони на изгледа keycol, intcol и charcol:

column_name column_id data_type----------- ----------- ----------keycol 1 intintcol 2 intcharcol 3 varchar

Наблюдавайте идентификаторите на колони (редни позиции), които са свързани с колоните.

Можете да получите подобна информация, като потърсите стандартния изглед на информационна схема INFORMATION_SCHEMA.COLUMNS, както следва:

ИЗБЕРЕТЕ COLUMN_NAME, ORDINAL_POSITION, DATA_TYPEFROM INFORMATION_SCHEMA.COLUMNSWHERE TABLE_SCHEMA =N'dbo' И TABLE_NAME =N'V1';

За да получите информацията за зависимостта на изгледа (обекти, към които се отнася), можете да потърсите sys.dm_sql_referenced_entities, както следва:

ИЗБЕРЕТЕ OBJECT_NAME(referenced_id) AS referenced_object, referenced_minor_id, COL_NAME(referenced_id, referenced_minor_id) AS column_nameFROM sys.dm_sql_referenced_entities(N'dbo.V1', N'OBJECT');

Ще намерите зависимостта от таблица T1 и от нейните три колони:

referenced_object referenced_minor_id column_name----------------- ------------------ ------- ----T1 0 NULLT1 1 keycolT1 2 intcolT1 3 charcol

Както вероятно се досещате, стойността reference_minor_id за колони е идентификаторът на колоната, който видяхте по-рано.

Ако искате да получите разрешенията на user1 срещу V1, можете да заявите sys.database_permissions, както следва:

ИЗБЕРЕТЕ OBJECT_NAME(major_id) AS referenced_object, minor_id, COL_NAME(major_id, minor_id) AS column_name, permission_nameFROM sys.database_permissionsWHERE major_id =OBJECT_ID(N'dbo.V1') AND granteeN'uUSER_ID(N'dbo.V1') AND granteeN'user_ID; предварително> 

Този код генерира следния изход, потвърждавайки, че наистина user1 има разрешения за избор само срещу keycol и intcol, но не и срещу charcol:

referenced_object minor_id column_name permission_name----------------- ----------- ------------ -- --------------V1 1 ключ SELECTV1 2 intcol SELECT

Отново, minor_id стойността е идентификаторът на колоната, който видяхте по-рано. Нашият потребител, user1, има разрешения за колоните, чиито идентификатори са 1 и 2.

След това изпълнете следния код, за да се представяте за user1 и да опитате да заявите всички колони на V1:

ИЗПЪЛНЕНИЕ КАТО ПОТРЕБИТЕЛ =N'user1'; ИЗБЕРЕТЕ * ОТ dbo.V1;

Както бихте очаквали, получавате грешка в разрешенията поради липсата на разрешение за заявка за charcol:

Съобщение 230, ниво 14, състояние 1, ред 141
Разрешението SELECT беше отказано в колоната 'charcol' на обекта 'V1', база данни 'TSQLV5', схема 'dbo'.

Опитайте да заявите само keycol и intcol:

ИЗБЕРЕТЕ keycol, intcol ОТ dbo.V1;

Този път заявката се изпълнява успешно, генерирайки следния изход:

keycol intcol----------- -----------1 102 20

Засега няма изненади.

Изпълнете следния код, за да се върнете към първоначалния си потребител:

ВРЪЩАНЕ;

Сега нека приложим няколко структурни промени към основната таблица dbo.T1. Изпълнете следния код, за да добавите първо две колони, наречени datecol и binarycol, и след това да пуснете колоната intcol:

ALTER TABLE dbo.T1 ADD datecol DATE NOT NULL DEFAULT('99991231'), binarycol VARBINARY(3) NOT NULL DEFAULT(0x112233); ALTER TABLE dbo.T1 DROP COLUMN intcol;

SQL Server не отхвърли структурните промени в колони, които се препращат от изгледа, тъй като изгледът не е създаден с атрибута SCHEMABINDING. Сега за улова. Към този момент SQL Server все още не е опреснил информацията за метаданните на изгледа в различните каталожни обекти.

Използвайте следния код, за да направите заявка за изгледа, все още с вашия първоначален потребител (все още не е user1):

ИЗБЕРЕТЕ * ОТ dbo.V1;

Получавате следния изход:

keycol intcol charcol----------- ---------- ----------1 A 9999-12-312 B 9999-12-31 

Забележете, че intcol всъщност връща съдържанието на charcol, а charcol връща съдържанието на datecol. Не забравяйте, че в таблицата вече няма intcol, но има datecol. Също така, вие не получавате обратно новата колона binarycol.

За да опитате да разберете какво се случва, използвайте следния код, за да заявите метаданните на колоната на изгледа:

ИЗБЕРЕТЕ име AS column_name, column_id, TYPE_NAME(system_type_id) AS data_typeFROM sys.columnsWHERE object_id =OBJECT_ID(N'dbo.V1');

Този код генерира следния изход:

column_name column_id data_type----------- ----------- ----------keycol 1 intintcol 2 intcharcol 3 varchar

Както можете да видите, метаданните на изгледа все още не са обновени. Можете да видите intcol като колона ID 2 и charcol като колона ID 3. На практика intcol вече не съществува, charcol се предполага, че е колона 2, а datecol трябва да бъде колона 3.

Нека проверим дали има някаква промяна в информацията за разрешение:

ИЗБЕРЕТЕ OBJECT_NAME(major_id) AS referenced_object, minor_id, COL_NAME(major_id, minor_id) AS column_name, permission_nameFROM sys.database_permissionsWHERE major_id =OBJECT_ID(N'dbo.V1') AND granteeN'uUSER_ID(N'dbo.V1') AND granteeN'user_ID; предварително> 

Получавате следния изход:

referenced_object minor_id column_name permission_name----------------- ----------- ------------ -- --------------V1 1 ключ SELECTV1 2 intcol SELECT

Информацията за разрешенията показва, че user1 има разрешения за колони 1 и 2 в изгледа. Въпреки това, въпреки че метаданните смятат, че колона 2 се нарича intcol, тя всъщност е съпоставена с charcol в T1 на практика. Това е опасно, тъй като user1 не трябва да има достъп до charcol. Ами ако в реалния живот тази колона съдържа чувствителна информация като пароли.

Нека отново се представяме за user1 и да потърсим всички колони на изгледа:

EXECUTE AS USER ='user1'; ИЗБЕРЕТЕ * ОТ dbo.V1;

Получавате грешка в разрешението, която казва, че нямате достъп до charcol:

Съобщение 230, ниво 14, състояние 1, ред 211
Разрешението SELECT беше отказано в колоната 'charcol' на обекта 'V1', база данни 'TSQLV5', схема 'dbo'.

Вижте обаче какво се случва, когато изрично поискате keycol и intcol:

ИЗБЕРЕТЕ keycol, intcol ОТ dbo.V1;

Получавате следния изход:

keycol intcol----------- ----------1 A2 B

Тази заявка е успешна, само че връща съдържанието на charcol под intcol. Нашият потребител, user1, не трябва да има достъп до тази информация. Опа!

В този момент се върнете обратно към първоначалния потребител, като изпълните следния код:

ВРЪЩАНЕ;

Опресняване на SQL модула

Можете ясно да видите, че използването на SELECT * в израза на вътрешната таблица на изгледа е лоша идея. Но не е само това. Като цяло е добра идея да опреснявате метаданните на изгледа след всяка промяна на DDL на препратирани обекти и колони. Можете да направите това с помощта на sp_refreshview или по-общия модул sp_refreshmodule, както следва:

EXEC sys.sp_refreshsqlmodule N'dbo.V1';

Запитвайте отново изгледа, след като метаданните му са обновени:

ИЗБЕРЕТЕ * ОТ dbo.V1;

Този път получавате очаквания резултат:

keycol charcol datecol binarycol----------- ---------- ---------- ---------1 A 9999 -12-31 0x1122332 B 9999-12-31 0x112233

Колоната charcol е наименувана правилно и показва правилните данни; не виждате intcol и виждате новите колони datecol и binarycol.

Запитване на метаданните на колоната на изгледа:

ИЗБЕРЕТЕ име AS column_name, column_id, TYPE_NAME(system_type_id) AS data_typeFROM sys.columnsWHERE object_id =OBJECT_ID(N'dbo.V1');

Резултатът вече показва правилната информация за метаданните на колоната:

column_name column_id data_type------------ ----------- ----------ключ 1 intcharcol 2 varchardatecol 3 datebinarycol 4 varbinary 

Запитване за разрешенията на user1 спрямо изгледа:

ИЗБЕРЕТЕ OBJECT_NAME(major_id) AS referenced_object, minor_id, COL_NAME(major_id, minor_id) AS column_name, permission_nameFROM sys.database_permissionsWHERE major_id =OBJECT_ID(N'dbo.V1') AND granteeN'uUSER_ID(N'dbo.V1') AND granteeN'user_ID; предварително> 

Получавате следния изход:

referenced_object minor_id column_name permission_name----------------- ----------- ------------ -- --------------V1 1 клавиша SELECT

Информацията за разрешенията вече е вярна. Нашият потребител, user1, има разрешения само да избира keycol, а информацията за разрешенията за intcol е премахната.

За да сме сигурни, че всичко е наред, нека тестваме това, като се представяме за user1 и запитваме изгледа:

EXECUTE AS USER ='user1'; ИЗБЕРЕТЕ * ОТ dbo.V1;

Получавате две грешки в разрешенията поради липса на разрешения срещу datecol и binarycol:

Съобщение 230, ниво 14, състояние 1, ред 281
Разрешението SELECT беше отказано в колоната 'datecol' на обекта 'V1', база данни 'TSQLV5', схема 'dbo'.

Съобщение 230, ниво 14, състояние 1, ред 281
Разрешението SELECT беше отказано в колоната „binarycol“ на обекта „V1“, база данни „TSQLV5“, схема „dbo“.

Опитайте да потърсите keycol и intcol:

ИЗБЕРЕТЕ keycol, intcol ОТ dbo.V1;

Този път грешката правилно казва, че няма колона, наречена intcol:

Съобщение 207, ниво 16, състояние 1, ред 279

Невалидно име на колона „intcol“.

Заявка само intcol:

ИЗБЕРЕТЕ ключа от dbo.V1;

Тази заявка се изпълнява успешно, генерирайки следния изход:

keycol-----------12

В този момент се върнете към първоначалния си потребител, като изпълните следния код:

ВРЪЩАНЕ;

Достатъчно ли е да избягвате SELECT * и да използвате изрични имена на колони?

Ако следвате практика, която казва без SELECT * в израза на вътрешната таблица на изгледа, това ще бъде ли достатъчно, за да ви предпази от проблеми? Е, да видим...

Използвайте следния код, за да пресъздадете таблицата и изгледа, само този път избройте колоните изрично във вътрешната заявка на изгледа:

ПРОСТЪПНЕТЕ ИЗГЛЕД, АКО СЪЩЕСТВУВА dbo.V1; ИЗПУСКАНЕ НА ТАБЛИЦА, АКО СЪЩЕСТВУВА dbo.T1; ИЗТЪКНЕТЕ ТАБЛИЦА dbo.T1( keycol INT NOT NULL ОГРАНИЧЕНИЕ ЗА ИДЕНТИЧНОСТ PK_T1 ПРАВИЛЕН КЛЮЧ, intcol INT NOT NULL, charcol VARCHAR(charcol VARCHAR); ВМЕСТЕ В dbo.T1(intcol, charcol) СТОЙНОСТИ (10, 'A'), (20, 'B');GO СЪЗДАДЕТЕ ИЛИ ПРОМЕНЯТЕ ИЗГЛЕЖДАНЕ dbo.V1AS SELECT keycol, intcol, charcol ОТ dbo.T1;GO

Запитване на изгледа:

ИЗБЕРЕТЕ * ОТ dbo.V1;

Получавате следния изход:

keycol intcol charcol----------- ----------- ----------1 10 A2 20 B

Отново дайте на user1 разрешения за избор на keycol и intcol:

ПРЕДОСТАВЯ ИЗБОР НА dbo.V1(keycol, intcol) НА потребител1;

След това приложете същите структурни промени, както направихте преди:

ALTER TABLE dbo.T1 ADD datecol DATE NOT NULL DEFAULT('99991231'), binarycol VARBINARY(3) NOT NULL DEFAULT(0x112233); ALTER TABLE dbo.T1 DROP COLUMN intcol;

Забележете, че SQL Server прие тези промени, въпреки че изгледът има изрична препратка към intcol. Отново, това е, защото изгледът е създаден без опцията SCHEMABINDING.

Запитване на изгледа:

ИЗБЕРЕТЕ * ОТ dbo.V1;

В този момент SQL Server генерира следната грешка:

Съобщение 207, ниво 16, състояние 1, процедура V1, ред 5 [начален ред на партида 344]
Невалидно име на колона 'intcol'.

Съобщение 4413, ниво 16, състояние 1, ред 345
Не можа да се използва изглед или функция 'dbo.V1' поради грешки при свързването.

SQL Server се опита да разреши препратката intcol в изгледа и, разбира се, беше неуспешен.

Но какво ще стане, ако първоначалният ви план беше да премахнете intcol и по-късно да го добавите обратно? Използвайте следния код, за да го добавите обратно, и след това потърсете изгледа:

ALTER TABLE dbo.T1 ДОБАВЯНЕ intcol INT NOT NULL DEFAULT(0); ИЗБЕРЕТЕ * ОТ dbo.V1;

Този код генерира следния изход:

keycol intcol charcol----------- ----------- ----------1 0 A2 0 B

Резултатът изглежда правилен.

Какво ще кажете за запитване на изгледа като user1? Нека опитаме:

ИЗПЪЛНИТЕ КАТО ПОТРЕБИТЕЛ ='user1';ИЗБЕРЕТЕ * ОТ dbo.V1;

Когато заявявате всички колони, получавате очакваната грешка поради липсата на разрешения срещу charcol:

Съобщение 230, ниво 14, състояние 1, ред 367
Разрешението SELECT беше отказано в колоната 'charcol' на обекта 'V1', база данни 'TSQLV5', схема 'dbo'.

Заявете изрично keycol и intcol:

ИЗБЕРЕТЕ keycol, intcol ОТ dbo.V1;

Получавате следния изход:

keycol intcol----------- -----------1 02 0

Изглежда, че всичко е наред, благодарение на факта, че не сте използвали SELECT * във вътрешната заявка на изгледа, въпреки че не сте обновили метаданните на изгледа. Все пак може да е добра практика да се обновят метаданните на изгледа след промяна на DDL на реферирани обекти и колони, за да сте в безопасност.

В този момент се върнете към първоначалния си потребител, като изпълните следния код:

ВРЪЩАНЕ;

СВЪРЗВАНЕ НА СХЕМА

Използвайки атрибута SCHEMABINDING view, можете да си спестите много от гореспоменатите проблеми. Един от ключовете за избягване на проблемите, които видяхте по-рано, е да не използвате SELECT * във вътрешната заявка на изгледа. Но има и проблем със структурните промени срещу зависими обекти, като изпускане на реферирани колони, които все още могат да доведат до грешки при запитване на изгледа. Използвайки атрибута на изглед SCHEMABINDING, няма да ви бъде позволено да използвате SELECT * във вътрешната заявка. Освен това SQL Server ще отхвърли опитите за прилагане на съответните DDL промени към зависими обекти и колони. В релевантно, имам предвид промени като изпускане на реферирана таблица или колона. Добавянето на колона към посочена таблица очевидно не е проблем, така че SCHEMABINDING не предотвратява такава промяна.

За да демонстрирате това, използвайте следния код, за да пресъздадете таблицата и изгледа, със SCHEMABINDING в дефиницията на изгледа:

ПРОСТЪПНЕТЕ ИЗГЛЕД, АКО СЪЩЕСТВУВА dbo.V1; ИЗПУСКАНЕ НА ТАБЛИЦА, АКО СЪЩЕСТВУВА dbo.T1; ИЗТЪКНЕТЕ ТАБЛИЦА dbo.T1( keycol INT NOT NULL ОГРАНИЧЕНИЕ ЗА ИДЕНТИЧНОСТ PK_T1 ПРАВИЛЕН КЛЮЧ, intcol INT NOT NULL, charcol VARCHAR(charcol VARCHAR); ВМЕСТЕ В dbo.T1(intcol, charcol) СТОЙНОСТИ (10, 'A'), (20, 'B');GO СЪЗДАВАЙТЕ ИЛИ ПРОМЕНЯТЕ ИЗГЛЕЖДАНЕ dbo.V1 СЪС SCHEMABINDINGAS SELECT * ОТ dbo.T1;GO

Получавате грешка:

Съобщение 1054, Ниво 15, Състояние 6, Процедура V1, Ред 5 [Пакетна начална линия 387]
Синтаксисът '*' не е разрешен в обекти, свързани със схема.

Когато използвате SCHEMABINDING, нямате право да използвате SELECT * в израза на вътрешната таблица на изгледа.

Опитайте да създадете изгледа отново, само този път с изричен списък с колони:

СЪЗДАВАЙТЕ ИЛИ ПРОМЕНЯТЕ ИЗГЛЕЖДАНЕ dbo.V1 СЪС SCHEMABINDINGAS SELECT keycol, intcol, charcol ОТ dbo.T1;GO

Този път изгледът е създаден успешно.

Предоставяне на user1 разрешения за keycol и intcol:

ПРЕДОСТАВЯ ИЗБОР НА dbo.V1(keycol, intcol) НА потребител1;

След това опитайте да приложите структурни промени към таблицата. Първо добавете няколко колони:

ALTER TABLE dbo.T1 ADD datecol DATE NOT NULL DEFAULT('99991231'), binarycol VARBINARY(3) NOT NULL DEFAULT(0x112233);

Добавянето на колони не е проблем, защото те не могат да бъдат част от съществуващи изгледи, свързани със схема, така че този код завършва успешно.

Опит за премахване на колоната intcol:

ПРОМЕНЯ ТАБЛИЦА dbo.T1 ИЗПУСКАНЕ КОЛОНА intcol;

Получавате следната грешка:

Съобщение 5074, ниво 16, състояние 1, ред 418
Обектът „V1“ зависи от колона „intcol“.

Съобщение 4922, ниво 16, състояние 9, ред 418
ALTER TABLE DROP COLUMN intcol не успя, защото един или повече обекти имат достъп до тази колона.

Изпускането или промяната на реферирани колони е забранено, когато съществуват свързани със схема обекти.

Ако все още трябва да махнете intcol, първо ще трябва да махнете обвързания със схема изглед за препращане, да приложите промяната и след това да създадете отново изгледа и преназначите разрешения, както следва:

ПРОСТЪПНЕТЕ ИЗГЛЕД, АКО СЪЩЕСТВУВА dbo.V1;GO ALTER TABLE dbo.T1 DROP COLUMN intcol;GO CREATE ИЛИ ПРОМЕНИ ИЗГЛЕД dbo.V1 СЪС SCHEMABINDINGAS SELECT keycol, charcol, datecol, binarycol ОТ dbo.T1;GO ИЗБЕРЕТЕ dbo.T1 V1(keycol, datecol, binarycol) TO user1;GO

Разбира се в този момент няма нужда да опреснявате дефиницията на изгледа, защото сте го създали наново.

След като приключите с тестването, изпълнете следния код за почистване:

ИЗПУСКАНЕ НА ИЗГЛЕД, АКО СЪЩЕСТВУВА dbo.V1; ИЗПУСКАНЕ НА ТАБЛИЦА, АКО СЪЩЕСТВУВА dbo.T1; ИЗПУСКАНЕ НА ПОТРЕБИТЕЛЯ, АКО СЪЩЕСТВУВА потребител1;

Резюме

Използването на SELECT * в израза на вътрешната таблица на изгледа е много лоша идея. След като се приложат структурни промени към реферирани обекти, можете да получите неправилни имена на колони и дори да позволите на потребителите да имат достъп до данни, до които не би трябвало да имат достъп. Важна практика е изрично да се изброят имената на колоните, на които се препраща.

Използвайки SCHEMABINDING в дефиницията на изгледа, вие сте принудени да изброите изрично имена на колони и съответните структурни промени в зависими обекти се отхвърлят от SQL Server. Следователно може да изглежда, че създаването на изгледи със SCHEMBINDING винаги е добра идея. Има обаче едно предупреждение при тази опция. Както видяхте, прилагането на структурни промени към реферирани обекти, когато се използва SCHEMBINDING, става по-дълъг и по-сложен процес. Това може да бъде особено проблем в системи, които трябва да имат много висока наличност. Представете си, че трябва да промените колона, дефинирана като VARCHAR(50) на VARCHAR(60). Това не е разрешена промяна, ако има изглед, дефиниран със SCHEMABINDING, препращащ към тази колона. Последствията от отпадането на куп референтни изгледи, които биха могли да бъдат реферирани от други изгледи и така нататък, могат да бъдат проблематични за системата. Накратко, не винаги е толкова тривиално компаниите просто да приемат политика, която казва, че SCHEMABINDING трябва да се използва във всички обекти, които го поддържат. Въпреки това приемането на политика да не се използва SELECT * във вътрешните заявки на изгледи трябва да бъде по-лесно.

Има още много неща за изследване по отношение на изгледите. Продължава следващия месец...


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 0 до 60 :Превключване към индиректни контролни точки

  2. Блокчейн:какво е това, как работи и какво означава за големи данни

  3. Първи стъпки с Shareplex на Windows на AWS, част 2

  4. Топ 18 безплатни и широко използвани бази данни NoSQL с отворен код

  5. Модел на данни за приложение за маратонско обучение