Database
 sql >> Database >  >> RDS >> Database

Nozioni fondamentali sulle espressioni di tabella, Parte 10 – Viste, SELECT * e modifiche DDL

Nell'ambito della serie sulle espressioni delle tabelle, il mese scorso ho iniziato la copertura delle visualizzazioni. In particolare, ho iniziato la copertura degli aspetti logici delle viste e ho confrontato il loro design con quello delle tabelle derivate e dei CTE. Questo mese continuerò la copertura degli aspetti logici delle viste, concentrando la mia attenzione sulle modifiche SELECT * e DDL.

Il codice che utilizzerò in questo articolo può essere eseguito in qualsiasi database, ma nelle mie demo utilizzerò TSQLV5, lo stesso database di esempio utilizzato negli articoli precedenti. Puoi trovare lo script che crea e popola TSQLV5 qui e il suo diagramma ER qui.

Usare SELECT * nella query interna della vista è una cattiva idea

Nella sezione conclusiva dell'articolo del mese scorso ho posto una domanda come spunto di riflessione. Ho spiegato che in precedenza nella serie ho avanzato una tesi a favore dell'utilizzo di SELECT * nelle espressioni di tabella interne utilizzate con tabelle derivate e CTE. Vedi la parte 3 della serie per i dettagli se hai bisogno di rinfrescarti la memoria. Ti ho quindi chiesto di pensare se la stessa raccomandazione sarebbe ancora valida per l'espressione della tabella interna utilizzata per definire la vista. Forse il titolo di questa sezione era già uno spoiler, ma dirò proprio del pipistrello che con le visualizzazioni in realtà è una pessima idea.

Inizierò con le viste che non sono definite con l'attributo SCHEMABINDING, che impedisce modifiche DDL rilevanti agli oggetti dipendenti, quindi spiegherò come cambiano le cose quando usi questo attributo.

Passerò direttamente a un esempio poiché questo sarà il modo più semplice per presentare la mia argomentazione.

Usa il codice seguente per creare una tabella denominata dbo.T1 e una vista denominata dbo.V1 basata su una query con SELECT * sulla tabella:

USE TSQLV5;
 
DROP VIEW IF EXISTS dbo.V1;
DROP TABLE IF EXISTS dbo.T1;
GO
 
CREATE TABLE dbo.T1
(
  keycol INT NOT NULL IDENTITY
    CONSTRAINT PK_T1 PRIMARY KEY,
  intcol INT NOT NULL,
  charcol VARCHAR(10) NOT NULL
);
 
INSERT INTO dbo.T1(intcol, charcol) VALUES
  (10, 'A'),
  (20, 'B');
GO
 
CREATE OR ALTER VIEW dbo.V1
AS
  SELECT *
  FROM dbo.T1;
GO

Osserva che la tabella ha attualmente le colonne keycol, intcol e charcol.

Usa il codice seguente per interrogare la vista:

SELECT * FROM dbo.V1;

Ottieni il seguente output:

keycol      intcol      charcol
----------- ----------- ----------
1           10          A
2           20          B

Niente di troppo speciale qui.

Quando si crea una vista, SQL Server registra le informazioni sui metadati in numerosi oggetti catalogo. Registra alcune informazioni generali, che puoi interrogare tramite sys.views, la definizione della vista che puoi interrogare tramite sys.sql_modules, informazioni sulla colonna che puoi interrogare tramite sys.columns e ulteriori informazioni sono disponibili tramite altri oggetti. Ciò che è importante anche per la nostra discussione è che SQL Server ti consente di controllare le autorizzazioni di accesso rispetto alle visualizzazioni. Quello che voglio avvisarti quando usi SELECT * nell'espressione della tabella interna della vista, è cosa può succedere quando le modifiche DDL vengono applicate agli oggetti dipendenti sottostanti.

Utilizzare il codice seguente per creare un utente chiamato user1 e concedere all'utente le autorizzazioni per selezionare le colonne keycol e intcol dalla vista, ma non charcol:

DROP USER IF EXISTS user1;
 
CREATE USER user1 WITHOUT LOGIN; 
 
GRANT SELECT ON dbo.V1(keycol, intcol) TO user1;

A questo punto, esaminiamo alcuni dei metadati registrati relativi al nostro punto di vista. Utilizzare il codice seguente per restituire la voce che rappresenta la vista da sys.views:

SELECT SCHEMA_NAME(schema_id) AS schemaname, name, object_id, type_desc
FROM sys.views
WHERE object_id = OBJECT_ID(N'dbo.V1');

Questo codice genera il seguente output:

schemaname  name  object_id   type_desc
----------- ----- ----------- ----------
dbo         V1    130099504   VIEW

Utilizzare il codice seguente per ottenere la definizione della vista da sys.modules:

SELECT definition 
FROM sys.sql_modules
WHERE object_id = OBJECT_ID(N'dbo.V1');

Un'altra opzione è usare la funzione OBJECT_DEFINITION in questo modo:

SELECT OBJECT_DEFINITION(OBJECT_ID(N'dbo.V1'));

Ottieni il seguente output:

CREATE   VIEW dbo.V1
AS
  SELECT *
  FROM dbo.T1;

Usa il codice seguente per interrogare le definizioni delle colonne della vista da sys.columns:

SELECT name AS column_name, column_id, TYPE_NAME(system_type_id) AS data_type
FROM sys.columns
WHERE object_id = OBJECT_ID(N'dbo.V1');

Come previsto, ottieni informazioni sulle tre colonne della vista keycol, intcol e charcol:

column_name  column_id   data_type
------------ ----------- ----------
keycol       1           int
intcol       2           int
charcol      3           varchar

Osserva gli ID colonna (posizioni ordinali) associati alle colonne.

È possibile ottenere informazioni simili interrogando la visualizzazione dello schema di informazioni standard INFORMATION_SCHEMA.COLUMNS, in questo modo:

SELECT COLUMN_NAME, ORDINAL_POSITION, DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'dbo'
  AND TABLE_NAME = N'V1';

Per ottenere le informazioni sulle dipendenze della vista (oggetti a cui fa riferimento), puoi interrogare sys.dm_sql_referenced_entities, in questo modo:

SELECT
  OBJECT_NAME(referenced_id) AS referenced_object,
  referenced_minor_id,
  COL_NAME(referenced_id, referenced_minor_id) AS column_name
FROM sys.dm_sql_referenced_entities(N'dbo.V1', N'OBJECT');

Troverai la dipendenza dalla tabella T1 e dalle sue tre colonne:

referenced_object  referenced_minor_id column_name
------------------ ------------------- -----------
T1                 0                   NULL
T1                 1                   keycol
T1                 2                   intcol
T1                 3                   charcol

Come probabilmente puoi immaginare, il valore reference_minor_id per le colonne è l'ID colonna che hai visto in precedenza.

Se vuoi ottenere i permessi di user1 rispetto a V1, puoi interrogare sys.database_permissions, in questo modo:

SELECT 
  OBJECT_NAME(major_id) AS referenced_object,
  minor_id,
  COL_NAME(major_id, minor_id) AS column_name, 
  permission_name
FROM sys.database_permissions
WHERE major_id = OBJECT_ID(N'dbo.V1')
  AND grantee_principal_id = USER_ID(N'user1');

Questo codice genera il seguente output, affermando che effettivamente l'utente1 ha i permessi di selezione solo contro keycol e intcol, ma non contro charcol:

referenced_object  minor_id    column_name  permission_name
------------------ ----------- ------------ ----------------
V1                 1           keycol       SELECT
V1                 2           intcol       SELECT

Anche in questo caso, il valore minor_id è l'ID della colonna che hai visto in precedenza. Il nostro utente, utente1, dispone delle autorizzazioni per le colonne i cui ID sono 1 e 2.

Quindi, esegui il codice seguente per impersonare utente1 e provare a eseguire query su tutte le colonne di V1:

EXECUTE AS USER = N'user1';
 
SELECT * FROM dbo.V1;

Come ti aspetteresti, ricevi un errore di autorizzazione a causa della mancanza di autorizzazione per interrogare charcol:

Msg 230, livello 14, stato 1, riga 141
L'autorizzazione SELECT è stata negata sulla colonna 'charcol' dell'oggetto 'V1', database 'TSQLV5', schema 'dbo'.

Prova a interrogare solo keycol e intcol:

SELECT keycol, intcol FROM dbo.V1;

Questa volta la query viene eseguita correttamente, generando il seguente output:

keycol      intcol
----------- -----------
1           10
2           20

Nessuna sorpresa finora.

Esegui il codice seguente per ripristinare l'utente originale:

REVERT;

Applichiamo ora alcune modifiche strutturali alla tabella sottostante dbo.T1. Esegui il codice seguente per aggiungere prima due colonne denominate datecol e binarycol, quindi per eliminare la colonna 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 non ha rifiutato le modifiche strutturali alle colonne a cui fa riferimento la vista poiché la vista non è stata creata con l'attributo SCHEMABINDING. Ora, per la cattura. A questo punto, SQL Server non ha ancora aggiornato le informazioni sui metadati della vista nei diversi oggetti del catalogo.

Usa il codice seguente per interrogare la vista, sempre con il tuo utente originale (non ancora utente1):

SELECT * FROM dbo.V1;

Ottieni il seguente output:

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

Si noti che intcol restituisce effettivamente il contenuto di charcol e charcol restituisce il contenuto di datecol. Ricorda, non c'è più intcol nella tabella ma c'è datecol. Inoltre, non viene restituita la nuova colonna binarycol.

Per cercare di capire cosa sta succedendo, usa il codice seguente per interrogare i metadati della colonna della vista:

SELECT name AS column_name, column_id, TYPE_NAME(system_type_id) AS data_type
FROM sys.columns
WHERE object_id = OBJECT_ID(N'dbo.V1');

Questo codice genera il seguente output:

column_name  column_id   data_type
------------ ----------- ----------
keycol       1           int
intcol       2           int
charcol      3           varchar

Come puoi vedere, i metadati della vista non vengono ancora aggiornati. Puoi vedere intcol come ID colonna 2 e charcol come ID colonna 3. In pratica, intcol non esiste più, charcol dovrebbe essere la colonna 2 e datecol dovrebbe essere la colonna 3.

Verifichiamo se sono state apportate modifiche alle informazioni sui permessi:

SELECT 
  OBJECT_NAME(major_id) AS referenced_object,
  minor_id,
  COL_NAME(major_id, minor_id) AS column_name, 
  permission_name
FROM sys.database_permissions
WHERE major_id = OBJECT_ID(N'dbo.V1')
  AND grantee_principal_id = USER_ID(N'user1');

Ottieni il seguente output:

referenced_object  minor_id    column_name  permission_name
------------------ ----------- ------------ ----------------
V1                 1           keycol       SELECT
V1                 2           intcol       SELECT

Le informazioni sulle autorizzazioni mostrano che l'utente1 dispone delle autorizzazioni per le colonne 1 e 2 nella vista. Tuttavia, anche se i metadati ritengono che la colonna 2 sia chiamata intcol, in pratica è mappata su charcol in T1. È pericoloso poiché l'utente1 non dovrebbe avere accesso a charcol. E se nella vita reale questa colonna contenesse informazioni sensibili come le password.

Impersoniamo di nuovo utente1 e interroghiamo tutte le colonne della vista:

EXECUTE AS USER = 'user1';
 
SELECT * FROM dbo.V1;

Viene visualizzato un errore di autorizzazione che dice che non hai accesso a charcol:

Msg 230, livello 14, stato 1, riga 211
L'autorizzazione SELECT è stata negata nella colonna 'charcol' dell'oggetto 'V1', database 'TSQLV5', schema 'dbo'.

Tuttavia, guarda cosa succede quando chiedi esplicitamente keycol e intcol:

SELECT keycol, intcol FROM dbo.V1;

Ottieni il seguente output:

keycol      intcol
----------- ----------
1           A
2           B

Questa query riesce, solo che restituisce il contenuto di charcol in intcol. Il nostro utente, utente1, non dovrebbe avere accesso a queste informazioni. Ops!

A questo punto, torna all'utente originale eseguendo il codice seguente:

REVERT;

Aggiorna modulo SQL

Puoi vedere chiaramente che l'uso di SELECT * nell'espressione della tabella interna della vista è una cattiva idea. Ma non è solo questo. In genere, è una buona idea aggiornare i metadati della vista dopo ogni modifica DDL agli oggetti e alle colonne di riferimento. Puoi farlo usando sp_refreshview o il più generale sp_refreshmodule, in questo modo:

EXEC sys.sp_refreshsqlmodule N'dbo.V1';

Interroga nuovamente la vista, ora che i suoi metadati sono stati aggiornati:

SELECT * FROM dbo.V1;

Questa volta ottieni l'output previsto:

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

La colonna charcol è denominata correttamente e mostra i dati corretti; non vedi intcol e vedi le nuove colonne datecol e binarycol.

Interroga i metadati della colonna della vista:

SELECT name AS column_name, column_id, TYPE_NAME(system_type_id) AS data_type
FROM sys.columns
WHERE object_id = OBJECT_ID(N'dbo.V1');

L'output ora mostra le informazioni corrette sui metadati della colonna:

column_name  column_id   data_type
------------ ----------- ----------
keycol       1           int
charcol      2           varchar
datecol      3           date
binarycol    4           varbinary

Interroga le autorizzazioni dell'utente1 rispetto alla vista:

SELECT 
  OBJECT_NAME(major_id) AS referenced_object,
  minor_id,
  COL_NAME(major_id, minor_id) AS column_name, 
  permission_name
FROM sys.database_permissions
WHERE major_id = OBJECT_ID(N'dbo.V1')
  AND grantee_principal_id = USER_ID(N'user1');

Ottieni il seguente output:

referenced_object  minor_id    column_name  permission_name
------------------ ----------- ------------ ----------------
V1                 1           keycol       SELECT

Le informazioni sull'autorizzazione ora sono corrette. Il nostro utente, utente1, ha i permessi solo per selezionare keycol e le informazioni sui permessi per intcol sono state rimosse.

Per essere sicuri che tutto sia a posto, proviamo questo impersonando utente1 e interrogando la vista:

EXECUTE AS USER = 'user1';
 
SELECT * FROM dbo.V1;

Ottieni due errori di autorizzazione a causa della mancanza di autorizzazioni contro datecol e binarycol:

Msg 230, Level 14, State 1, Line 281
L'autorizzazione SELECT è stata negata nella colonna 'datecol' dell'oggetto 'V1', database 'TSQLV5', schema 'dbo'.

Msg 230, Level 14, State 1, Line 281
L'autorizzazione SELECT è stata negata sulla colonna 'binarycol' dell'oggetto 'V1', database 'TSQLV5', schema 'dbo'.

Prova a interrogare keycol e intcol:

SELECT keycol, intcol FROM dbo.V1;

Questa volta l'errore dice correttamente che non esiste una colonna chiamata intcol:

Msg 207, Livello 16, Stato 1, Linea 279

Nome colonna 'intcol' non valido.

Interroga solo intcol:

SELECT keycol FROM dbo.V1;

Questa query viene eseguita correttamente, generando il seguente output:

keycol
-----------
1
2

A questo punto ripristina l'utente originale eseguendo il codice seguente:

REVERT;

È sufficiente evitare SELECT * e utilizzare nomi di colonna espliciti?

Se segui una pratica che dice no SELECT * nell'espressione della tabella interna della vista, questo sarebbe sufficiente per tenerti fuori dai guai? Bene, vediamo...

Usa il codice seguente per ricreare la tabella e la vista, solo che questa volta elenca le colonne in modo esplicito nella query interna della vista:

DROP VIEW IF EXISTS dbo.V1;
DROP TABLE IF EXISTS dbo.T1;
GO
 
CREATE TABLE dbo.T1
(
  keycol INT NOT NULL IDENTITY
    CONSTRAINT PK_T1 PRIMARY KEY,
  intcol INT NOT NULL,
  charcol VARCHAR(10) NOT NULL
);
 
INSERT INTO dbo.T1(intcol, charcol) VALUES
  (10, 'A'),
  (20, 'B');
GO
 
CREATE OR ALTER VIEW dbo.V1
AS
  SELECT keycol, intcol, charcol
  FROM dbo.T1;
GO

Interroga la vista:

SELECT * FROM dbo.V1;

Ottieni il seguente output:

keycol      intcol      charcol
----------- ----------- ----------
1           10          A
2           20          B

Ancora una volta, concedi all'utente1 le autorizzazioni per selezionare keycol e intcol:

GRANT SELECT ON dbo.V1(keycol, intcol) TO user1;

Quindi, applica le stesse modifiche strutturali come hai fatto prima:

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;

Osservare che SQL Server ha accettato queste modifiche, anche se la vista ha un riferimento esplicito a intcol. Anche in questo caso, perché la vista è stata creata senza l'opzione SCHEMABINDING.

Interroga la vista:

SELECT * FROM dbo.V1;

A questo punto SQL Server genera il seguente errore:

Msg 207, Livello 16, Stato 1, Procedura V1, Riga 5 [Batch Start Line 344]
Nome colonna 'intcol' non valido.

Msg 4413, livello 16, stato 1, riga 345
Impossibile utilizzare la visualizzazione o la funzione 'dbo.V1' a causa di errori di associazione.

SQL Server ha tentato di risolvere il riferimento intcol nella vista e ovviamente non ha avuto successo.

Ma cosa accadrebbe se il tuo piano originale fosse quello di eliminare intcol e in seguito aggiungerlo di nuovo? Usa il codice seguente per aggiungerlo di nuovo, quindi interroga la vista:

ALTER TABLE dbo.T1
  ADD intcol INT NOT NULL DEFAULT(0);
 
SELECT * FROM dbo.V1;

Questo codice genera il seguente output:

keycol      intcol      charcol
----------- ----------- ----------
1           0           A
2           0           B

Il risultato sembra corretto.

Che ne dici di interrogare la vista come utente1? Proviamolo:

EXECUTE AS USER = 'user1';

SELECT * FROM dbo.V1;

Quando esegui query su tutte le colonne, ottieni l'errore previsto a causa della mancanza di autorizzazioni contro charcol:

Msg 230, livello 14, stato 1, riga 367
L'autorizzazione SELECT è stata negata sulla colonna 'charcol' dell'oggetto 'V1', database 'TSQLV5', schema 'dbo'.

Interroga keycol e intcol in modo esplicito:

SELECT keycol, intcol FROM dbo.V1;

Ottieni il seguente output:

keycol      intcol
----------- -----------
1           0
2           0

Sembra che tutto sia in ordine grazie al fatto che non hai utilizzato SELECT * nella query interna della vista, anche se non hai aggiornato i metadati della vista. Tuttavia, potrebbe essere una buona pratica aggiornare i metadati della vista dopo le modifiche DDL agli oggetti e alle colonne di riferimento per essere al sicuro.

A questo punto, torna al tuo utente originale eseguendo il codice seguente:

REVERT;

SCHEMABINDING

Utilizzando l'attributo di visualizzazione SCHEMABINDING puoi risparmiarti molti dei suddetti problemi. Una delle chiavi per evitare i problemi che hai visto in precedenza è non utilizzare SELECT * nella query interna della vista. Ma c'è anche il problema delle modifiche strutturali rispetto agli oggetti dipendenti, come l'eliminazione di colonne referenziate, che potrebbero comunque causare errori durante l'interrogazione della vista. Utilizzando l'attributo di visualizzazione SCHEMABINDING, non ti sarà consentito utilizzare SELECT * nella query interna. Inoltre, SQL Server rifiuterà i tentativi di applicare le modifiche DDL rilevanti agli oggetti dipendenti e alle colonne. Per quanto riguarda, intendo modifiche come l'eliminazione di una tabella o colonna di riferimento. L'aggiunta di una colonna a una tabella di riferimento non è ovviamente un problema, quindi SCHEMABINDING non impedisce tale modifica.

Per dimostrarlo, usa il codice seguente per ricreare la tabella e la vista, con SCHEMABINDING nella definizione della vista:

DROP VIEW IF EXISTS dbo.V1;
DROP TABLE IF EXISTS dbo.T1;
GO
 
CREATE TABLE dbo.T1
(
  keycol INT NOT NULL IDENTITY
    CONSTRAINT PK_T1 PRIMARY KEY,
  intcol INT NOT NULL,
  charcol VARCHAR(10) NOT NULL
);
 
INSERT INTO dbo.T1(intcol, charcol) VALUES
  (10, 'A'),
  (20, 'B');
GO
 
CREATE OR ALTER VIEW dbo.V1
  WITH SCHEMABINDING
AS
  SELECT *
  FROM dbo.T1;
GO

Viene visualizzato un errore:

Msg 1054, livello 15, stato 6, procedura V1, riga 5 [Batch Start Line 387]
La sintassi '*' non è consentita negli oggetti associati allo schema.

Quando si utilizza SCHEMABINDING, non è consentito utilizzare SELECT * nell'espressione della tabella interna della vista.

Prova a creare di nuovo la vista, solo questa volta con un elenco di colonne esplicito:

CREATE OR ALTER VIEW dbo.V1
  WITH SCHEMABINDING
AS
  SELECT keycol, intcol, charcol
  FROM dbo.T1;
GO

Questa volta la vista è stata creata correttamente.

Concedi autorizzazioni utente1 su keycol e intcol:

GRANT SELECT ON dbo.V1(keycol, intcol) TO user1;

Quindi, prova ad applicare le modifiche strutturali alla tabella. Innanzitutto, aggiungi un paio di colonne:

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

L'aggiunta di colonne non è un problema perché non possono far parte di viste associate a schema esistenti, quindi questo codice viene completato correttamente.

Tentativo di eliminare la colonna intcol:

ALTER TABLE dbo.T1
  DROP COLUMN intcol;

Viene visualizzato il seguente errore:

Msg 5074, livello 16, stato 1, riga 418
L'oggetto 'V1' dipende dalla colonna 'intcol'.

Msg 4922, livello 16, stato 9, riga 418
ALTER TABLE DROP COLUMN intcol non riuscito perché uno o più oggetti accedono a questa colonna.

L'eliminazione o la modifica delle colonne di riferimento non è consentita quando esistono oggetti associati allo schema.

Se devi ancora eliminare intcol, dovrai prima eliminare la vista di riferimento associata allo schema, applicare la modifica, quindi ricreare la vista e riassegnare le autorizzazioni, in questo modo:

DROP VIEW IF EXISTS dbo.V1;
GO
 
ALTER TABLE dbo.T1 DROP COLUMN intcol;
GO
 
CREATE OR ALTER VIEW dbo.V1
  WITH SCHEMABINDING
AS
  SELECT keycol, charcol, datecol, binarycol
  FROM dbo.T1;
GO
 
GRANT SELECT ON dbo.V1(keycol, datecol, binarycol) TO user1;
GO

Ovviamente a questo punto non c'è bisogno di aggiornare la definizione della vista, perché l'hai creata di nuovo.

Ora che hai terminato il test, esegui il codice seguente per la pulizia:

DROP VIEW IF EXISTS dbo.V1;
DROP TABLE IF EXISTS dbo.T1;
DROP USER IF EXISTS user1;

Riepilogo

L'uso di SELECT * nell'espressione della tabella interna della vista è una pessima idea. Dopo aver applicato le modifiche strutturali agli oggetti referenziati, potresti ottenere nomi di colonna errati e persino consentire agli utenti di accedere a dati a cui non dovrebbero avere accesso. È una pratica importante elencare in modo esplicito i nomi delle colonne a cui si fa riferimento.

Utilizzando SCHEMABINDING nella definizione della vista sei costretto a elencare in modo esplicito i nomi delle colonne e le modifiche strutturali rilevanti agli oggetti dipendenti vengono rifiutate da SQL Server. Pertanto, potrebbe sembrare che creare viste con SCHEMBINDING sia sempre una buona idea. Tuttavia, c'è un avvertimento con questa opzione. Come hai visto, l'applicazione di modifiche strutturali agli oggetti di riferimento quando si utilizza SCHEMBINDING diventa un processo più lungo ed elaborato. Può essere particolarmente un problema nei sistemi che devono avere una disponibilità molto elevata. Immagina di dover modificare una colonna definita come VARCHAR(50) in VARCHAR(60). Non è una modifica consentita se è presente una vista definita con SCHEMABINDING che fa riferimento a questa colonna. Le implicazioni dell'eliminazione di un gruppo di viste di riferimento, a cui potrebbero fare riferimento altre viste e così via, potrebbero essere problematiche per il sistema. In breve, non è sempre così banale per le aziende adottare semplicemente una politica che dice che SCHEMABINDING dovrebbe essere utilizzato in tutti gli oggetti che lo supportano. Tuttavia, l'adozione di una politica per non utilizzare SELECT * nelle query interne delle viste dovrebbe essere più semplice.

C'è molto altro da esplorare per quanto riguarda le visualizzazioni. Continua il mese prossimo...