Home Page
Articoli
Tips & Tricks
News
Forum
Archivio Forum
Blogs
Sondaggi
Rss
Video
Utenti
Chi Siamo
Contattaci
Username:
Password:
Login
Registrati ora!
Recupera Password
Home Page
Stanze Forum
SQL Server 2000/2005/2008, Express, Access, MySQL, Oracle
Problema con una view in SQL Server 2000
venerdì 28 ottobre 2005 - 16.33
Elenco Threads
Stanze Forum
Aggiungi ai Preferiti
Cerca nel forum
fornonad
Profilo
| Newbie
40
messaggi | Data Invio:
ven 28 ott 2005 - 16:33
Ho esattamente un record fatto in questo modo:
NOME DATA NUM_DOMANDA PUNTI RIF_RISPOSTA DATA_COMPILAZIONE
UTENTE1 10/10/2005 44 1 138|139 10/10/2005 13.02.25
In RIF_RISPOSTA ho le due risposte selezionate nella compilazione
Vorrei ottenere una view in cui ho le due risposte separate, e quindi:
NOME DATA NUM_DOMANDA PUNTI RIF_RISPOSTA DATA_COMPILAZIONE
UTENTE1 10/10/2005 44 1 138 10/10/2005 13.02.25
UTENTE1 10/10/2005 44 1 139 10/10/2005 13.02.25
è possibile farlo in una view? mi tocca creare una tabella con un cursore?
io uso SQL Server 2000
grazie dell'aiuto
lbenaglia
Profilo
| Guru
5.625
messaggi | Data Invio:
ven 28 ott 2005 - 17:01
>Ho esattamente un record fatto in questo modo:
>è possibile farlo in una view? mi tocca creare una tabella con
> un cursore?
Questo è quello che succede quando non si rispetta nemmeno la prima forma normale nella progettazione di un database... :-(
La 1NF dice: "In una tabella ogni colonna deve contenere una informazione atomica e non devono esistere gruppi di colonne ripetute".
Prima di abbozzare una risposta, mi sai dire la colonna Rif_Risposta quanti valori può contenere separati da una pipe "|"?
2, 3, 1 milione? LOL
>grazie dell'aiuto
Prego.
Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
fornonad
Profilo
| Newbie
40
messaggi | Data Invio:
ven 28 ott 2005 - 17:05
penso che al massimo possa contenere 5 valori differenti
ciao ciao adry
lbenaglia
Profilo
| Guru
5.625
messaggi | Data Invio:
mar 1 nov 2005 - 19:04
>penso che al massimo possa contenere 5 valori differenti
Ciao adry,
se utilizzassi SQL Server 2005 potresti avvalerti dell'operatore APPLY che valuta la tabella di destra per ogni riga della tabella di sinistra. Questa funzionalità è utile quando la tabella di destra è costituita da una funzione table-valued parametrica che recupera gli argomenti dalle colonne della tabella di sinistra.
Nell'esempio che ti sto per proporre ho definito la funzione table-valued ufn_Split che restituisce un resultset di una colonna con le risposte in base al separatore specificato.
Utilizzando l'operatore CROSS APPLY effettuo una JOIN tra la tabella base e la funzione:
USE tempdb;
GO
/* Definisco la tabella dbo.Foo */
CREATE TABLE dbo.Foo(
NOME varchar(10) NOT NULL,
DATA smalldatetime NOT NULL,
NUM_DOMANDA tinyint NOT NULL,
PUNTI tinyint NOT NULL,
RIF_RISPOSTA varchar(20) NOT NULL,
DATA_COMPILAZIONE smalldatetime NOT NULL
);
GO
/* La valorizzo */
INSERT dbo.Foo VALUES('UTENTE1', '20051010', 44, 1, '138|139', '20051010 13:02:25');
INSERT dbo.Foo VALUES('UTENTE2', '20051011', 55, 2, '140', '20051011 13:02:25');
INSERT dbo.Foo VALUES('UTENTE3', '20051012', 66, 3, '141|142|143', '20051012 13:02:25');
INSERT dbo.Foo VALUES('UTENTE4', '20051013', 77, 4, '144|145|146|147|148', '20051013 13:02:25');
GO
/* Definisco la Multistatement table-valued function dbo.ufn_Split */
CREATE FUNCTION dbo.ufn_Split(
@Expression varchar(20),
@Delimiter char
)
RETURNS @Table TABLE(
Items tinyint NOT NULL
)
AS
BEGIN
DECLARE @Start int
DECLARE @End int
DECLARE @Item tinyint
SET @Start = 1
WHILE(@Start <= LEN(@Expression))
BEGIN
SET @End = CHARINDEX(@Delimiter, @Expression, @Start)
IF @End = 0 SET @End = DATALENGTH(@Expression) + 1
SET @Item = CAST(SUBSTRING(@Expression, @Start, @End - @Start) AS tinyint)
INSERT @Table VALUES(@Item)
SET @Start = @End + DATALENGTH(@Delimiter)
END
RETURN
END;
GO
/* Definisco la vista dbo.vw_NormalizeData */
CREATE VIEW dbo.vw_NormalizeData
AS
SELECT
F.NOME
, F.DATA
, F.NUM_DOMANDA
, F.PUNTI
, S.Items AS RIF_RISPOSTA
, F.DATA_COMPILAZIONE
FROM dbo.Foo AS F CROSS APPLY dbo.ufn_Split(F.RIF_RISPOSTA, '|') AS S;
GO
/* Query */
SELECT *
FROM dbo.vw_NormalizeData;
GO
/* Output:
NOME DATA NUM_DOMANDA PUNTI RIF_RISPOSTA DATA_COMPILAZIONE
---------- ----------------------- ----------- ----- ------------ -----------------------
UTENTE1 2005-10-10 00:00:00 44 1 138 2005-10-10 13:02:00
UTENTE1 2005-10-10 00:00:00 44 1 139 2005-10-10 13:02:00
UTENTE2 2005-10-11 00:00:00 55 2 140 2005-10-11 13:02:00
UTENTE3 2005-10-12 00:00:00 66 3 141 2005-10-12 13:02:00
UTENTE3 2005-10-12 00:00:00 66 3 142 2005-10-12 13:02:00
UTENTE3 2005-10-12 00:00:00 66 3 143 2005-10-12 13:02:00
UTENTE4 2005-10-13 00:00:00 77 4 144 2005-10-13 13:02:00
UTENTE4 2005-10-13 00:00:00 77 4 145 2005-10-13 13:02:00
UTENTE4 2005-10-13 00:00:00 77 4 146 2005-10-13 13:02:00
UTENTE4 2005-10-13 00:00:00 77 4 147 2005-10-13 13:02:00
UTENTE4 2005-10-13 00:00:00 77 4 148 2005-10-13 13:02:00
(11 row(s) affected)
*/
/* Pulizia */
DROP VIEW dbo.vw_NormalizeData;
DROP FUNCTION dbo.ufn_Split;
DROP TABLE dbo.Foo;
Purtroppo SQL Server 2000 non dispone dell'operatore APPLY quindi non è possibile adottare una soluzione del genere. Sinceramente non mi vengono in mente soluzioni set oriented, quindi credo che la strada del cusore possa essere
fornonad
Profilo
| Newbie
40
messaggi | Data Invio:
mer 2 nov 2005 - 07:19
Ti ringrazio della risposta, purtroppo ora ho modificato la base dati lasciando la possibilità di inserire una solo possibile valore e non più valori separati da |. Comunque sarà un errore che non commetterò più.
Grazie dell'interessamento
ciao ciao adry
lbenaglia
Profilo
| Guru
5.625
messaggi | Data Invio:
mer 2 nov 2005 - 12:08
>Ti ringrazio della risposta, purtroppo ora ho modificato la base
>dati lasciando la possibilità di inserire una solo possibile
>valore e non più valori separati da |. Comunque sarà un errore
> che non commetterò più.
Ciao adry,
hai fatto sicuramente la scelta migliore.
Partire da una basi dati normalizzata, ti eviterà in futuro di incontrare problemi analoghi a quello descritto.
>Grazie dell'interessamento
Di niente.
Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
Torna su
Stanze Forum
Elenco Threads
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?
Dopo esserti registrato potrai chiedere
aiuto sul nostro
Forum
oppure aiutare gli altri
Consulta le
Stanze
disponibili.
Registrati ora !