Post by AlessandroDPost by MaurizioAprendo query molto estese potrai notare che all'atto dell'apertura della
query il testo viene compattato (tipico esempio i CASE WHEN che sono
messi uno dietro l'altro perdendo ogni forma di indentazione).
Mai successo, ne quando usavo il Query Analyzer di SQL 2000, ne ora con
SSMS di SQL 2005.
Certo è che non ho mai avuto viste tanto grosse da superare gli 8kb di
sorgente, quindi non so se esistono bachi dell'editor in questo senso.
============================================================================================
Premessa:
Lavoro direttamente con SQL Server Management Studiodi SQL Server 2005. Dopo
aver aperto il nodo del database che mi interessa apro ancora il sottonodo
relativo alle Views e da li eseguo "New View" o "Modify". All'apertura della
finestra relativa alla vista vado poi a gestire la query.
Di seguito riporto una query di esempio che può servire a farti capire quali
sono i problemi di indentazione. Come vedi la struttura della SELECT è ben
strutturata, facile da modificare; ora prova a creare una nuova vista
incolla la query sottostante e vedi il risultato. Il testo viene
riorganizzato e l'indentazione si perde. Immagina di avere una query ben
più articolata di questa e ti rendi conto che diventa molto poco agevole
lavorare con il query designer. E' quindi opportuno mantenere la definizione
della query altrove e generare la view partendo da tale definizione.
(diciamo che vorrei usare una stored per questo scopo)
SELECT
CASE
WHEN Campo1=0 THEN 'Zero'
WHEN Campo1=1 THEN 'Uno'
WHEN Campo1=6 THEN 'Sei'
WHEN Campo1>0 AND Campo2 <5 THEN 'Stabile'
END AS STP_Stato,
CASE
WHEN Campo2=0 THEN 'ZeroZero'
WHEN Campo2=1 THEN 'UnoUno'
WHEN Campo2=5 THEN 'SeiSei'
WHEN Campo2>0 AND Campo2 <5 THEN 'StabileStabile'
END AS STP_Stato_2
FROM Tabellax
Considerato che (dopo un bel dibattito :-D) ho capito che non è possibile
utilizzare direttamente il CREATE VIEW all'interno della stored resta
soltanto la strada dell'exec(@query).
Per memorizzare la query all'interno di una variabile (ammettiamo sia una
variabile di tipo varchar(max)) gli apici delle stringhe vanno raddoppiati
perchè la definizione della query diventa essa stessa una stringa da passare
all'exec. Di seguito allego la stored che serve allo scopo:
CREATE PROCEDURE PROVAZ
AS
BEGIN
DECLARE @query varchar(max)
set @query='CREATE VIEW dbo.VIEWZ AS
SELECT
CASE
WHEN Campo1=0 THEN ''Zero''
WHEN Campo1=1 THEN ''Uno''
WHEN Campo1=6 THEN ''Sei''
WHEN Campo1>0 AND Campo2 <5 THEN ''Stabile''
END AS STP_Stato,
CASE
WHEN Campo2=0 THEN ''ZeroZero''
WHEN Campo2=1 THEN ''UnoUno''
WHEN Campo2=6 THEN ''SeiSei''
WHEN Campo2>0 AND Campo2 <5 THEN ''StabileStabile''
END AS STP_Stato_2
FROM Tabellax'
exec @query
END
Come vedi è stato necessario aggiungere un ulteriore apice di apertura ed
uno di terminazione per ogni costante stringa contenuta nella query. Questo
genera una difformità dal testo originale della query. Se avessi la
necessità di provare la query (ad esempio per verificarla dopo una modifica
con un semplice copia-incolla nel query designer delle view) dovrei togliere
nuovamente tutti i doppi apici perchè in caso contrario otterrei degli
errori di sintassi.
Per risolvere questo ulteriore problema utilizzo SET QUOTED_IDENTIFIER OFF
in modo da poter delimitare la sola stringa della SELECT con i doppi apici
lasciando inalterata la query nel suo formato originale anche per quanto
riguarda gli apici singoli
La stored finale e funzionante diventa allora la seguente:
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[PROVAZ]
AS
BEGIN
declare @query varchar(max)
if object_id('dbo.VIEWZ') is not null
BEGIN
DROP VIEW dbo.VIEWZ
END
set @query="CREATE VIEW dbo.VIEWZ AS
SELECT
CASE
WHEN Campo1=0 THEN 'Zero'
WHEN Campo1=1 THEN 'Uno'
WHEN Campo1=6 THEN 'Sei'
WHEN Campo1>0 AND Campo2 <5 THEN 'Stabile'
END AS STP_Stato,
CASE
WHEN Campo2=0 THEN 'ZeroZero'
WHEN Campo2=1 THEN 'UnoUno'
WHEN Campo2=6 THEN 'SeiSei'
WHEN Campo2>0 AND Campo2 <5 THEN 'StabileStabile'
END AS STP_Stato_2
FROM Tabellax"
exec (@query)
END
Credo che avrei potuto utilizzare anche ALTER VIEW in sostituzione del DROP
e del successivo CREATE.
============================================================================================
Post by AlessandroDIn ogni caso anche se vuoi insistere con la creazione di viste passando
per una stored procedure che accetta un parametro varchar(max), e tenerti
da qualche parte i sorgenti delle viste, non hai nessun problema di
duplicazione di apici vari, visto che in ogni caso l'unica cosa che devi
fare è leggere il sorgente e richiamare la sp passando nel suo parametro
proprio l'intero sorgente.
Se la chiamata della sp la fai in modo corretto, quindi senza produrre a
tua volta un'altra sringa sql con dentro la chiamata alla sp e nidificato
all'interno della stringa anche tutto il sorgente della vista, ma passando
attraverso ADO o ADO.NET e facendo uso degli oggetti
command e parameter, vedrai che non avrai problemi (per essere più chiari
L'invocazione della stored viene eseguita da SSMS, la generazione della
query è a carico del DBA, non devo richiamarla da nessun applicativo. Si
tratta di stored ad uso interno per mantenere la definizione di alcune view
particolarmente impegnative.
Un grazie a tutti coloro che mi hanno risposto perchè il problema è stato
risolto con l'ausilio delle vostre risposte. La chiave sta nel fatto che
varchar(max) accetta più di 8000 caratteri.
Ciao a tutti
Maurizio
Post by AlessandroDPost by MaurizioNell'esempio che ho riportato e che riporto di seguito cè solo il create
view, non ci sono istruzioni prima ne dopo a meno che le righe relative
alla definizione stessa della stored non siano considerate istruzioni.
La definizione della stored procedure è a tutti gli effetti un batch, dove
appunto il primo comando è il CREATE/ALTER della stored procedure, di
conseguenza non può esserci in qualunque altro punto anche uno create view.
il parametro relativo al comando exec, parametro il cui contenuto non
c'entra nulla, semanticamente parlando, con il batch corrente.
Che poi in fase di esecuzione la chiamata ad exec produca l'esecuzione di
un altro batch il cui corpo è dato dalla definizione della vista è un
altro discorso, che fra l'altro ti permette appunto di ottenere quello che
vuoi, anche se io ancora non ne capisco il motivo.
Post by MaurizioIn altri termini vorrei riuscire ad usare l'istruzione CREATE VIEW
all'interno di una stored procedure considerando che non posso usare
Puoi farmi un esempio funzionante? Io non ci sono riuscito.
Come ti ha già indicato Lorenzo puoi usare un parametro di ingresso di
CREATE PROCEDURE [dbo].[PROVA]
@sql varchar(max)
AS
return
go
exec dbo.PROVA 'CREATE VIEW dbo.VISTAX AS SELECT * FROM dbo.Anagrafiche'
una bella stringa lunga fino a 4GB...
Post by MaurizioPer quanto riguarda la creazione e la modifiche delle viste non uso
wizard, uso i comandi "New view" e "Modify" direttamente sulla vista.
Aprendo query molto estese potrai notare che all'atto dell'apertura della
query il testo viene compattato (tipico esempio i CASE WHEN che sono
messi uno dietro l'altro perdendo ogni forma di indentazione).
Mai successo, ne quando usavo il Query Analyzer di SQL 2000, ne ora con
SSMS di SQL 2005.
Certo è che non ho mai avuto viste tanto grosse da superare gli 8kb di
sorgente, quindi non so se esistono bachi dell'editor in questo senso.
Post by MaurizioIndentazione a parte il problema vero riguarda solo ed esclusivamente
l'utilizzo del comando CREATE VIEW all'interno di una stored senza usare
il comando exec. Da quello che fin qui ho visto sembra che non sia
possibile.
Inutile che insisti, stai cercando di fare una cosa che è documentata come
non fattibile... :-)
In ogni caso anche se vuoi insistere con la creazione di viste passando
per una stored procedure che accetta un parametro varchar(max), e tenerti
da qualche parte i sorgenti delle viste, non hai nessun problema di
duplicazione di apici vari, visto che in ogni caso l'unica cosa che devi
fare è leggere il sorgente e richiamare la sp passando nel suo parametro
proprio l'intero sorgente.
Se la chiamata della sp la fai in modo corretto, quindi senza produrre a
tua volta un'altra sringa sql con dentro la chiamata alla sp e nidificato
all'interno della stringa anche tutto il sorgente della vista, ma passando
attraverso ADO o ADO.NET e facendo uso degli oggetti
command e parameter, vedrai che non avrai problemi (per essere più chiari
"exec dbo.PROVA 'CREATE VIEW dbo.VISTAX AS SELECT * FROM dbo.Anagrafiche'"
e poi cercare di eseguirla in qualche modo dopo aver stabilito una
connessione verso SQL Server).
--
Ciao, Alessandro
/*
Alessandro Dereani - MVP SQL Server - http://mvp.support.microsoft.com
*/