none
Non ammette duplicati (senza indice ) / Stringhe Lunghezza 0 RRS feed

  • Domanda


  • Immagino gia che non è possibile fare altrimenti,
    ma comunque tento di trovare una risposta alternativa.

    In questa tabella   ( SQLServer2008R2 )

    -- Inizio Script xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    CREATE TABLE [dbo].[Tab]
    (
     [Id] [int] IDENTITY(1,1) NOT NULL,
     [C2] [varchar](50) NOT NULL,
     [C3] [nchar](10) NULL,
     
     CONSTRAINT [PK_Tab] PRIMARY KEY CLUSTERED
     
    ([Id] ASC)
    WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

    ) ON [PRIMARY]
    GO

    INSERT [dbo].[Tab]
    ([C2], [C3])
    VALUES
    (N'a', N'a         '),
    (N'', N'e         '),  -- Ho inserito una stringa di lunghezza 0 in C2
    (N'g', NULL)

    -- Fine xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    _____ 1° Domanda ________________________________________________
    Voglio che il campo C2 non abbia valori duplicati.

    Per arrivare a questo risultato genero un indice
    UNIQUE ( Univoco ) sul campo interessato.

    Ma in effetti l'indice NON mi serve,   in quanto ho gia la PRIMARY KEY

    Vorrei sostituire l'indice con qualcosa di più  "leggero"

    è possibile fare questa cosa ?   e come ?

    _____ 2° Domanda ________________________________________________
    ho impostato il campi C2  a "Non ammette NULL"

    ma posso ancora inserire stringhe di lunghezza 0

    che mi danno fastidio ( anche se non sbagliate )
    perche poi nella applicazione si confonde molto facilmente
    la stringa di lunghezza 0 con il NULL

    Per ovviare al problema io solitamente faccio dei vincoli del tipo:
    ____ (len([C2])>(0)) _________


    Esiste un modo piu semplice per arrivare allo stesso risultato  ????

    ________________________________________________________________

    Grazie












    • Modificato Mancini, domenica 24 giugno 2012 19:38
    domenica 24 giugno 2012 19:06

Risposte

  • salve,

    >Voglio che il campo C2 non abbia valori duplicati.
    >Per arrivare a questo risultato genero un indice 
    >UNIQUE ( Univoco ) sul campo interessato.
    >Ma in effetti l'indice NON mi serve,   in quanto ho gia la PRIMARY KEY
    >Vorrei sostituire l'indice con qualcosa di più  "leggero"
    >è possibile fare questa cosa ?   e come ?

    un CONSTRAINT UNIQUE sarebbe semanticamente piu' corretto, a prescindere che in molti dbms (SQL Server compreso) questo si appoggi poi su un indice univoco...

    per quanto riguarda l'affermazione 

    >Ma in effetti l'indice NON mi serve,   in quanto ho gia la PRIMARY KEY

    non ha molto senso, in quanto la pk e' sull'attributo [Id]  non su [C2]...

    >ho impostato il campi C2  a "Non ammette NULL"
    >ma posso ancora inserire stringhe di lunghezza 0
    >che mi danno fastidio ( anche se non sbagliate
    >perche poi nella applicazione si confonde molto facilmente
    >la stringa di lunghezza 0 con il NULL
    >Per ovviare al problema io solitamente faccio dei vincoli del tipo:
    > (len([C2])>(0)) 

    il fatto che possano essere confuse lato client e' tennicamente irrilevante lato database... se una stringa vuota e' inamissibile, devi provvedere l'apposito CHECK CONSTRAINT che protegga la base dati... se invece il valore e' ammissibile, allora "non puo' darti fastidio lato client", ma va solo gestito :)

    e ovviamente "tralasciamo" il discorso filosofico sulla affermazione di uguaglianza tra '' e NULL, che semanticamente ovviamente e' falsa :)

    saluti


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/

    • Contrassegnato come risposta Mancini, mercoledì 27 giugno 2012 03:59
    martedì 26 giugno 2012 14:53
    Moderatore

Tutte le risposte

  • salve,

    >Voglio che il campo C2 non abbia valori duplicati.
    >Per arrivare a questo risultato genero un indice 
    >UNIQUE ( Univoco ) sul campo interessato.
    >Ma in effetti l'indice NON mi serve,   in quanto ho gia la PRIMARY KEY
    >Vorrei sostituire l'indice con qualcosa di più  "leggero"
    >è possibile fare questa cosa ?   e come ?

    un CONSTRAINT UNIQUE sarebbe semanticamente piu' corretto, a prescindere che in molti dbms (SQL Server compreso) questo si appoggi poi su un indice univoco...

    per quanto riguarda l'affermazione 

    >Ma in effetti l'indice NON mi serve,   in quanto ho gia la PRIMARY KEY

    non ha molto senso, in quanto la pk e' sull'attributo [Id]  non su [C2]...

    >ho impostato il campi C2  a "Non ammette NULL"
    >ma posso ancora inserire stringhe di lunghezza 0
    >che mi danno fastidio ( anche se non sbagliate
    >perche poi nella applicazione si confonde molto facilmente
    >la stringa di lunghezza 0 con il NULL
    >Per ovviare al problema io solitamente faccio dei vincoli del tipo:
    > (len([C2])>(0)) 

    il fatto che possano essere confuse lato client e' tennicamente irrilevante lato database... se una stringa vuota e' inamissibile, devi provvedere l'apposito CHECK CONSTRAINT che protegga la base dati... se invece il valore e' ammissibile, allora "non puo' darti fastidio lato client", ma va solo gestito :)

    e ovviamente "tralasciamo" il discorso filosofico sulla affermazione di uguaglianza tra '' e NULL, che semanticamente ovviamente e' falsa :)

    saluti


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/

    • Contrassegnato come risposta Mancini, mercoledì 27 giugno 2012 03:59
    martedì 26 giugno 2012 14:53
    Moderatore

  • Se ho capito bene ( ma non ne sono sicuro )
    tu faresti una chiave Univoca sul campo C2
    ( ma che comunque in SQLServer  mi genera un indice )

    poi faresti ub vincolo per verificare che non si tratti di stringa a lunghezza 0
    con il suo  CHECK CONSTRAINT

    Il codice sarebbe quindi questo:

    -- Inizio Script xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    CREATE TABLE [dbo].[Tab]
    (
     [Id] [int] IDENTITY(1,1) NOT NULL,
     [C2] [varchar](50) NOT NULL,
     [C3] [nchar](10) NULL,

    -- Questa e la Primary Key 
       CONSTRAINT [PK_Tab] PRIMARY KEY CLUSTERED
       ([Id] ASC)
       WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY],

    -- Questa è una Chiave univoca sul campo C2  ( che comunque si appoggia a un indice )
       CONSTRAINT [Ch_Uni] UNIQUE NONCLUSTERED
       ([C2] ASC)
       WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    GO
    -- La tabella è finita

    -- Adesso aggiungo un vincolo per scartare le stringhe di lunghezza 0
    ALTER TABLE [dbo].[Tab]  WITH CHECK ADD  CONSTRAINT [CK_Tab] CHECK  ((len([C2])>(0)))
    GO
    ALTER TABLE [dbo].[Tab] CHECK CONSTRAINT [CK_Tab]
    GO

    -- Fibe Script xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    Grazie


    • Modificato Mancini, martedì 26 giugno 2012 21:28
    martedì 26 giugno 2012 20:52
  • salve,

    si :)

    sempre che quel check constraint abbia un senso effettivo...

    saluti


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/

    martedì 26 giugno 2012 23:48
    Moderatore
  •   Si  ha un senso effettivo

               Grazie per la risposta

    mercoledì 27 giugno 2012 03:59