Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

SQL Server 2005 Case Sensitivity

Îåêßíçóå áðü ôï ìÝëïò antonisV. Τελευταία δημοσίευση από το μέλος Theof στις 13-03-2009, 00:03. Υπάρχουν 12 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  22-05-2008, 11:17 42133

    SQL Server 2005 Case Sensitivity

    Καλημέρα σε όλους και όλες.


    Από όσο γνωρίζω ο SQL Server 2005 έχει 3 επίπεδα στα οποία επιτρέπει να ορίσεις Case Sensitivity ή Insensitivity μέσω COLLATE:

    1. Server Instance
    2. Database
    3. Table column


    Αν έχουμε μια ήδη στημένη βάση με COLLATE:

    - Server: Latin1_General_CI_AS
    - Database: SQL_Latin1_General_CP1253_CI_AI

    και σε κάθε column του κάθε πίνακα βέβαια: COLLATION = <database default>


    πώς μπορούμε να πετύχουμε Insensitivity όσον αφορά τα database objects, ώστε να μη χρειαστεί αλλαγή σε queries που είναι γραμμένα άλλα με κεφαλαία κι άλλα με μικρά γράμματα, αλλά ταυτόχρονα να έχουμε case sensitive data, ώστε το 'VOYAGE' να διαφέρει από το 'voyage' ;


    Ο τρόπος που έχω βρει πως γίνεται είναι να κάνει κανείς SCRIPT OUT (με Generate Scripts) όλη τη βάση με όλα της τα objects (Tables, Keys, Indexes), να μεταβάλλει αυτό το Script ώστε σε όλα τα CREATE TABLE να ορίστεί σε κάθε column COLLATE που θα δίνει Case Sensitivity, να μετονομαστεί η παλιά βάση κι όταν σηκωθεί η νέα διορθωμένη μέσω του script, να μεταφερθούν τα data μέσω Import/Export Wizard από την "παλιά".

    Υπάρχει η δυνατότητα χωρίς να γίνει όλο το παραπάνω, να εκτελέσει κάνεις κάποια εντολή ή να αλλάξει κάποια ρύθμιση έτσι ώστε σε όλους τους υπάρχοντες και μελλοντικούς πίνακες τα columns να έχουν COLLATION τέτοιο ώστε να είναι Case Sensitive τα Data (έστω και σε άδεια βάση με πεσμένα τα indexes, keys, constraints κτλ);

    Ευχαριστώ εκ των προτέρων

    antonisV




  •  22-05-2008, 15:42 42161 σε απάντηση της 42133

    Απ: SQL Server 2005 Case Sensitivity

    Υποψιάζομαι ότι δεν έχεις καταλάβει καλά τί κάνει το collation. Τα δεδομένα αποθηκεύονται πάντα με το σωστό case, εξάλλου άλλος χαρακτήρας είναι το α, άλλος το A και άλλος το ά. Το collation παίζει ρόλο μόνο στις συγκρίσεις. Με τα collation που έχεις όμως ήδη χρησιμοποιείς Case Insensitive collations, οπότε τα queries σου ήδη πρέπει να παίζουν όπως τα θες.

    Τί ακριβώς συμβαίνει και θέλεις να αλλάξεις το collation?


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  22-05-2008, 18:08 42170 σε απάντηση της 42161

    Απ: SQL Server 2005 Case Sensitivity

    Καλησπέρα

    Πιθανόν δεν εξήγησα καλά αυτό που ήθελα να πω....

    Ας πούμε ότι έχουμε τον εξής πίνακα:

    MYTABLE
    ----------
    MYNAME VARCHAR(80)
    MYCODE NUMERIC(15,2)
    .......
    .......

    κι ας θεωρήσουμε primary key το MYCODE και 1 unique index στο MYNAME.

    Στην περίπτωση που η βάση είναι όπως περιέγραψα, δηλ. CASE INSENSITIVE, τότε τα 2 παρακάτω queries τρέχουν και τα 2:

    1. SELECT* FROM MYTABLE WHERE MYCODE = 5
    2. select * from mytable where mycode = 5


    Ωστόσο, αν επιχειρήσω να εισάγω στον πίνακα 2 εγγραφές, στις οποίες το MYNAME θα είναι: "ANTONIS" στην 1η και "antonis" στη 2η, o unique index στο πεδίο θα διαμαρτηρηθεί ευλόγως γιατί θα καταλάβει πως οι 2 περιπτώσεις ονόματος είναι ακριβώς το ίδιο πράγμα. Δυστυχώς στην περίπτωση που με απασχολεί χρειάζεται να θεωρούνται 2 διαφορετικά πράγματα !

    Παρόλα αυτά χρειάζομαι και τα 2 προαναφερθέντα queries να μπορούν και τα 2 να τρέξουν γιατί δυστυχώς η εφαρμογή που τα έχει embedded είναι γραμμένη από πολλούς διαφορετικούς ανθρώπους που δεν τήρησαν ένα κοινό τρόπο προγραμματισμού (όλα κεφαλαία ή όλα μικρά) και σε κάθε περίπτωση δεν υπάρχει ο χρόνος για αλλαγή λόγω και του όγκου.

    Συνεπώς σε ό,τι αφορά βάση σαν αντικείμενο, πίνακες και στήλες σαν αντικείμενα θέλω CASE INSENSITIVITY. Στα δεδομένα όμως όπως στο πιο πάνω παράδειγμα, χρειάζομαι CASE SENSITIVITY.

    Προσπάθησα και κάποια άλλη λύση εκτός από αυτήν που είχα ανφέρει στο 1ο μήνυμα. Δηλαδή δοκίμασα έναν cursor γύρω από όλους τους πίνακες, ο οποίος διάβαζε τις κολώνες που ήταν varchar και εκτελούσε εντολή (ALTER TABLE T ALTER COLUMN C COLLATE CL...), αλλά δυστυχώς ζητά να πέσουν πρώτα όλα τα primary keys και indexes. Το πάρα πολύ περίεργο είναι πως στο γραφικό (modify) μέσα στο SQL SERVER 2005 MANAGEMENT STUDIO μπορείς από τα properties του column να αλλάξεις το COLLATION χωρίς να τον ενοχλεί το primary key ή κάποιο index !!!

    Ελπίζω να ήταν πιο σαφής αυτή η περιγραφή.
    Ευχαριστώ






  •  23-05-2008, 10:16 42176 σε απάντηση της 42170

    Απ: SQL Server 2005 Case Sensitivity

    Το SQL query string εφόσον είναι συντακτικά ορθό εκτελείται ανεξάρτητα από κεφαλαία ή μικρά. To collation εφαρμόζεται πάνω στις τιμές και όχι στη σύνταξη του statement.

    Η βάση σου έχει SQL_Latin1_General_CP1253_CI_AI Case Insesensitve Accent Insensitive default χαρακτηριστικά και συνεπώς δικαιολογήμενα στο σενάριο που περιγράφεις εμφανίζει αυτή τη συμπεριφορά.'Ορισε σε επίπεδο στήλης που σε ενδιαφέρει το COLLATION να είναι case sensitive οπότε δεν θα έχεις πρόβλημα(πχ COLLATE SQL_Latin1_General_CP1253_CS_AS). To collation του πίνακα μπορεί να είναι διαφορετικό.

    Το παρακάτω query σου επιστρέφει και τις 2  εγγραγές αν θα ήθελες

    SELECT [MYNAME],[MYcode]FROM [Mytable1] where [MYNAME] COLLATE SQL_Latin1_General_CP1253_CI_AS= 'ANTONIS'

    ενώ το απλό θα σου φερει μόνο 1

    SELECT [MYNAME],[MYcode]FROM [Mytable1] where [MYNAME] = 'ANTONIS'

  •  23-05-2008, 11:08 42181 σε απάντηση της 42176

    Απ: SQL Server 2005 Case Sensitivity

    Ευχαριστώ πολύ για την απάντηση.

    Δυστυχώς όμως μάλλον δεν έγινα κατανοητός σε κάποια σημεία.

    Καταρχάς αν έχεις case sensitive database, το "SELECT * FROM table1" δεν αναγνωρίζεται, αν έχεις δημιουργήσει τον πίνακα ως "TABLE1". Συγκεκριμένα λαμβάνεις το κάτωθι error:

    Msg 208, Level 16, State 1, Line 1
    Invalid object name 'table1'.

    Αυτό εννοώ με τα διαφορετικά γραμμένα queries.

    Τώρα όσον αφορά τα 2 queries που προτείνεις, ορθά το ένα φέρνει και τις 2 εγγραφές, το άλλο τη 1. Δεν τίθεται θέμα όμως αλλαγής του οποιουδήποτε query. Η λύση στο πρόβλημα που περιέγραψα πρέπει να είναι γενική χωρίς να γίνει η οποιαδήποτε τροποποίηση query. Να μη χρειάζεται δηλαδή να γραφτεί ένα query που θα περιλαμβάνει π.χ. το COLLATE ...

    Η λύση θα ήταν να υπήρχε μια ρύθμιση, ένα flag ή property, που να δηλώνει στη βάση ότι ναι μεν η ίδια είναι CASE INSENSITIVE, ώστε να μην προκύπτει το παραπάνω error, αλλά τα data μέσα σε αυτήν να είναι CASE SENSITIVE. Το να ορίσω όπως προτείνεις "...σε επίπεδο στήλης που σε ενδιαφέρει το COLLATION να είναι case sensitive οπότε δεν θα έχεις πρόβλημα(πχ COLLATE SQL_Latin1_General_CP1253_CS_AS)..." είναι ΑΠΟΛΥΤΑ ΣΩΣΤΟ !. Το πρόβλημα είναι πώς αυτό μπορεί (αν μπορεί) να γίνει εύκολα για όλες τις στήλες όλων των πινάκων της βάσης, γιατί δυστυχώς δεν είχε γίνει εξ αρχής μια σωστή ανάλυση που να καθορίζει ποιες στήλες πρέπει να έχουν το CASE SENSITIVITY και ποιες όχι.


  •  23-05-2008, 14:40 42197 σε απάντηση της 42181

    Απ: SQL Server 2005 Case Sensitivity

    Change table collations en masse.

    To change this, I will use a query that I Adapted from Justin Mallier's blog: (http://mallier.blogspot.com/2005/11/how-to-change-collation-against-all.html) that builds a script to alter the columns:

    --I added the variables to make it more safe (Some collations may be desired
    --to stay the same. I did use like on the from so you could change them all pretty
    --easily. Also I added text and max datatype support

    declare  @fromCollation sysname,
             
    @toCollation sysname

    set      @fromCollation = 'SQL_Latin1_General_CP1_CS_AS'
    set      @toCollation = 'SQL_Latin1_General_CP1_CI_AS'

    SELECT   'ALTER TABLE ' + TABLE_NAME +
          
    '   ALTER COLUMN ' + COLUMN_NAME + ' '
    + DATA_TYPE +
          
    CASE
    WHEN CHARACTER_MAXIMUM_LENGTH = -1 then '(max)'
                WHEN 
    DATA_TYPE in ('text','ntext') then ''
               
    WHEN CHARACTER_MAXIMUM_LENGTH IS NOT NULL 
                 THEN '('+(CONVERT(VARCHAR,CHARACTER_MAXIMUM_LENGTH)+')' )
               
    ELSE isnull(CONVERT(VARCHAR,CHARACTER_MAXIMUM_LENGTH),' ')
    END
          
    +' COLLATE ' + @toCollation+ ' ' + CASE
    IS_NULLABLE
                                               WHEN 'YES' THEN 'NULL'
                                               WHEN 'No' THEN 'NOT NULL'

    END
    FROM
    INFORMATION_SCHEMA.COLUMNS
    WHERE
    DATA_TYPE IN ('varchar' ,'char','nvarchar','nchar','text','ntext')
      and COLLATION_NAME like @fromCollation

  •  23-05-2008, 17:10 42206 σε απάντηση της 42197

    Απ: SQL Server 2005 Case Sensitivity

    Αρχικά, να σημειώσω πως ο κώδικας είναι κορυφαίος !

    Καταλλήγουμε συνεπώς σε αυτό που έλεγα στο 2ο κατά σειρά μήνυμά μου πως αναγκαστικά θα γράψουμε script, το οποίο πρώτα θα ρίχνει τους indexes και τα keys, στη συνέχεια θα κάνει την αλλαγή χρησιμοποιώντας για πράδειγμα τον κώδικα που παρέθεσες και μετά θα τους ξανασηκώνει.

    Μες το ΣΚ θα προσπαθήσω να το ολοκληρώσω και θα το κάνω upload συνολικά. Μπορεί να χρειαστεί και σε κάποιον άλλο.

    Κρίμα που δεν έχει βάλει η Microsoft μια flag για όλο αυτό Sad

    Ευχαριστώ και πάλι... θα επανέλθω με τον κώδικα.
  •  23-05-2008, 17:22 42207 σε απάντηση της 42206

    Απ: SQL Server 2005 Case Sensitivity

    Θα σου πρότεινα να μην το κάνεις. Έχεις μία βάση CI, με μία εφαρμογή η οποία υποθέτει CI και οι οποίες παίζουν τώρα. Αν αλλάξεις τώρα το collation, ο δικός σου κώδικας θα παίξει και θα σκάσει η υπόλοιπη εφαρμογή. Τί προσπαθείς να κάνεις? Γιατί ξαφνικά μία εφαρμογή η οποία υποθέτει CI πρέπει τώρα να αλλάξει? Μήπως θα πρέπει να ψάξεις μία άλλη λύση? Γιατί θέλεις να αλλάξεις το collation?

    Όσο για το flag, πρέπει να καταλάβεις ότι το collation κάθε αντικειμένου χρησιμεύει ως default για τα αντικείμενα κάτω από αυτό, δεν τα προσδιορίζει. Μπορείς π.χ. να αλλάξεις το collation της βάσης, αυτό όμως δεν θα αλλάξει τα collations των πινάκων που έχουν ήδη δημιουργηθεί. Διαφορετικά θα έσκαγαν οι εφαρμογές που ήταν ήδη γραμμένες και υπέθεταν ότι το collation έχει μία συγκεκριμένη συμπεριφορά.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  25-05-2008, 10:42 42237 σε απάντηση της 42207

    Απ: SQL Server 2005 Case Sensitivity

    Καλημέρα κι ευχαριστώ για τον προβληματισμό και την προτροπή.

    Με βάση την πληροφόρηση που έχεις μέσα από τα μηνύματά μου μάλλον έχεις δίκιο. Για να ξεκαθαρίσω απλά την κατάσταση παραθέτω σύντομα το τι οδηγεί σε αυτήν την απόφαση:

    Υπάρχει 1 σουίτα με περίπου 10 εφαρμογές, όλες γραμμένες εδώ κι αρκετά χρόνια, βασισμένες σε Oracle DB. Εκεί (δεν ξέρω αν έτσι είναι γενικά στην Oracle ή στα συγκεκριμένα στησίματα), ισχύει το CASE INSENSITIVITY στα DB objects (table names, column names etc) και CASE SENSITIVITY στα data. Ένας πελάτης λοιπόν αγοράζει τη σουίτα αλλά αποφασίζει να χρησιμοποιήσει SQL SERVER 2005. Εγκαθιστά τη 1 από τις 10 εφαρμογές σε SQL Server (η οποία ήταν εξ αρχής γραμμένη να παίζει σωστά και με τα 2 RDBMS) και τις υπόλοιπες σε Oracle μέχρι κι αυτές να "γυρίσουν". Η 1 που ήδη παίζει στον MSS 2005, τυγχάνει !!!! να μην έχει πρόβλημα με τα CASE SENSITIVE data που γενικά η σουίτα χρειάζεται. Μόλις όμως οι άλλες 9 αρχίσουν να παίζουν σε SQL Server 2005, τότε θα υπάρξει μέγα θέμα ! Επίσης, όσο παρανοϊκό κι αν ακουστεί, θα πρέπει η αλλαγή να γίνει σε αρκετές βάσεις, οι οποίες δεν γνωρίζουμε αν είναι ακριβή αντίγραφα η μια της άλλης (δεν μου επιτρέπεται να επεκταθώ περεταίρω σε αυτό), οπότε χρειάζομαι αναγκαστικά ένα script το οποίο θα ρίχνει αρχικά όλα τα indexes, keys στην οποιαδήποτε βάση, θα κάνει την αλλαγή στο collation σε επίπεδο columns και θα ξανανεβάζει τα indexes, keys.

    Όπως είπα και στο ποηγούμενο μήνυμα, μόλις το ολοκληρώσω θα το αναρτήσω.
  •  25-05-2008, 21:12 42388 σε απάντηση της 42237

    Απ: SQL Server 2005 Case Sensitivity

    Λοιπόν, ο κώδικας στον οποίο κατέληξα είναι ο παρακάτω. Χρησιμοποίησα τον κώδικα που δημοσίευσε παραπάνω ο micfarmakis, καθώς και τον προτεινόμενο κώδικα στο Blog του Pinal Dave.

    Βρίσκει όλα τα indexes, όποιας μορφής, σχηματίζει τα create stmts τους, τα ρίχνει σε descending order, αλλάζει το COLLATE σε όλα τα varchar κτλ columns κάθε πίνακα και ξανασηκώνει τα indexes, keys. Στο τέλος κάνει refresh όλα τα views για να "ενσωματώσουν" κι αυτά τις αλλαγές των πινάκων.

    Ζητώ συγγνώμη για το μακροσκελές του κώδικα. Είμαι σίγουρος πως μπορεί να γραφτεί και καλύτερα σε λιγότερες γραμμές από κάποιον ποιο έμπειρο, όπως για παράδειγμα το κομμάτι κώδικα (γρ.68-98) που μπορεί να υλοποιηθεί κατευθείαν από το SELECT stmt του cursor στη γρ.47.

    Εύχομαι να βοηθήσει κι άλλους. Ευχαριστώ και πάλι όσους απάντησαν. Οποιαδήποτε διόρθωση ευπρόσδεκτη.
    antonisV


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    --
    -- Created by antonisV - 25/05/2008
    --
    DECLARE @TABLE_NAME AS VARCHAR(100)
    DECLARE @VIEW_NAME AS VARCHAR(100)
    DECLARE @COL_NAME AS VARCHAR(100)
    DECLARE @IDX_NAME AS VARCHAR(100)
    DECLARE @IS_PK AS NUMERIC(1)
    DECLARE @IS_UNQ AS NUMERIC(1)
    DECLARE @IDX_DESCR AS VARCHAR(20)
    DECLARE @IDX_UNQ_CONS AS NUMERIC(1)
    DECLARE @IDX_COL_SORT AS VARCHAR(10)

    DECLARE @IDX_CREATE_STMT AS VARCHAR(2000)
    DECLARE @IDX_DROP_STMT AS VARCHAR(2000)
    DECLARE @ALL_TBL_IDX_STMT AS VARCHAR(8000)
    DECLARE @ALTER_COLLATE_STMT AS VARCHAR(2000)

    DECLARE @fromCollation sysname,
    @toCollation sysname

    SET @fromCollation = 'SQL_Latin1_General_CP1253_CI_AI'
    SET @toCollation = 'SQL_Latin1_General_CP1253_CS_AS'


    /* Cursor for all user tables */
    DECLARE SEL_USER_TABLES CURSOR FOR
    SELECT TABLE_NAME
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE <> 'VIEW'
    ORDER BY TABLE_NAME


    /* Open Table cursor */
    OPEN SEL_USER_TABLES

    /* Get table name */
    FETCH NEXT FROM SEL_USER_TABLES INTO @TABLE_NAME

    /* Loop around tables */
    WHILE @@FETCH_STATUS = 0
    BEGIN
    SET @ALL_TBL_IDX_STMT = '' /* Initialise create stmt for all indexes of current table */

    /* Cursor for indexes of specific table ordered by descending index_id */
    DECLARE SEL_IDX_INFO CURSOR FOR
    SELECT idx.name AS IndexName,
    idx.is_primary_key As isPK,
    idx.is_unique As isUNQ,
    idx.type_desc As descr,
    idx.is_unique_constraint
    FROM sys.indexes AS idx
    INNER JOIN sys.tables AS tbl ON idx.OBJECT_ID = tbl.OBJECT_ID
    WHERE tbl.type = 'U'
    AND OBJECT_NAME(tbl.OBJECT_ID) = @TABLE_NAME
    AND idx.index_id <> 0
    ORDER BY idx.index_id DESC

    /* Open Index cursor for current table */
    OPEN SEL_IDX_INFO

    /* Get index info */
    FETCH NEXT FROM SEL_IDX_INFO INTO @IDX_NAME, @IS_PK, @IS_UNQ, @IDX_DESCR, @IDX_UNQ_CONS

    /* Loop around indexes */
    WHILE @@FETCH_STATUS = 0
    BEGIN
    /* Start forming create stmt */
    IF @IS_PK = 1
    BEGIN /* PRIMARY KEY */
    SET @IDX_CREATE_STMT = 'ALTER TABLE ['+@TABLE_NAME+'] ADD CONSTRAINT ['+@IDX_NAME+'] PRIMARY KEY CLUSTERED ( '
    SET @IDX_DROP_STMT = 'ALTER TABLE ['+@TABLE_NAME+'] DROP CONSTRAINT ['+@IDX_NAME+']'
    END
    ELSE
    BEGIN /* NON-PRIMARY-KEY IDX */
    IF @IDX_UNQ_CONS = 1
    BEGIN /* UNIQUE CONSTRAINT */
    SET @IDX_CREATE_STMT = 'ALTER TABLE ['+@TABLE_NAME+'] ADD CONSTRAINT ['+@IDX_NAME+'] UNIQUE NONCLUSTERED ( '
    SET @IDX_DROP_STMT = 'ALTER TABLE ['+@TABLE_NAME+'] DROP CONSTRAINT ['+@IDX_NAME+']'
    END
    ELSE
    BEGIN /* SIMPLE INDEX */
    SET @IDX_DROP_STMT = 'DROP INDEX ['+@IDX_NAME+'] ON ['+@TABLE_NAME+']'
    SET @IDX_CREATE_STMT = 'CREATE '
    IF @IS_UNQ = 1
    BEGIN /* Unique IDX */
    SET @IDX_CREATE_STMT = @IDX_CREATE_STMT+'UNIQUE '
    END
    IF @IDX_DESCR = 'CLUSTERED'
    BEGIN /* Clustered IDX */
    SET @IDX_CREATE_STMT = @IDX_CREATE_STMT+'CLUSTERED '
    END
    ELSE
    BEGIN /* Clustered IDX */
    SET @IDX_CREATE_STMT = @IDX_CREATE_STMT+'NONCLUSTERED '
    END
    SET @IDX_CREATE_STMT = @IDX_CREATE_STMT+'INDEX ['+@IDX_NAME+'] ON ['+@TABLE_NAME+'] ( '
    END
    END

    /* Cursor for columns of a specific index ordered by ascending index_column_id */
    DECLARE SEL_IDX_COLS CURSOR FOR
    SELECT COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName,
    CASE ic.is_descending_key
    WHEN 1 THEN 'DESC'
    ELSE 'ASC'
    END AS ColumnSort
    FROM sys.indexes AS idx
    INNER JOIN sys.index_columns AS ic ON
    (idx.OBJECT_ID = ic.OBJECT_ID AND idx.index_id = ic.index_id)
    INNER JOIN sys.tables AS tbl ON idx.OBJECT_ID = tbl.OBJECT_ID
    WHERE tbl.type = 'U'
    AND OBJECT_NAME(ic.OBJECT_ID) = @TABLE_NAME
    AND idx.name = @IDX_NAME
    ORDER BY ic.index_column_id

    /* Open cloumns cursor for current index */
    OPEN SEL_IDX_COLS
    /* Get column name and sorting */
    FETCH NEXT FROM SEL_IDX_COLS INTO @COL_NAME, @IDX_COL_SORT
    /* Loop around columns */
    WHILE @@FETCH_STATUS = 0
    BEGIN
    /* Append to IDX create stmt */
    SET @IDX_CREATE_STMT = @IDX_CREATE_STMT+'['+@COL_NAME+'] '+@IDX_COL_SORT+', '
    /* Get next column name and sorting */
    FETCH NEXT FROM SEL_IDX_COLS INTO @COL_NAME, @IDX_COL_SORT
    END
    /* Complete IDX create stmt */
    SET @IDX_CREATE_STMT = RTRIM(@IDX_CREATE_STMT)
    SET @IDX_CREATE_STMT = LEFT( @IDX_CREATE_STMT, LEN(@IDX_CREATE_STMT)-1 )+' )'
    /* Close cloumns cursor for current index */
    CLOSE SEL_IDX_COLS
    DEALLOCATE SEL_IDX_COLS

    /* Append on the left of all indexes creation stmt, the current one */
    SET @ALL_TBL_IDX_STMT = @IDX_CREATE_STMT+' '+@ALL_TBL_IDX_STMT

    /* Drop current Index */
    EXEC (@IDX_DROP_STMT)

    /* Get next index info */
    FETCH NEXT FROM SEL_IDX_INFO INTO @IDX_NAME, @IS_PK, @IS_UNQ, @IDX_DESCR, @IDX_UNQ_CONS
    END
    /* Close Index cursor for current table */
    CLOSE SEL_IDX_INFO
    DEALLOCATE SEL_IDX_INFO

    /* Cursor for altering collation on a specific table's txt columns */
    DECLARE SEL_CHANGE_COLLATE CURSOR FOR
    SELECT 'ALTER TABLE ['+TABLE_NAME+'] ALTER COLUMN ['+COLUMN_NAME+'] '+DATA_TYPE+
    CASE
    WHEN CHARACTER_MAXIMUM_LENGTH = -1 THEN '(max)'
    WHEN DATA_TYPE IN ('text','ntext') THEN ''
    WHEN CHARACTER_MAXIMUM_LENGTH IS NOT NULL THEN '('+(CONVERT(VARCHAR,CHARACTER_MAXIMUM_LENGTH)+')' )
    ELSE ISNULL(CONVERT(VARCHAR,CHARACTER_MAXIMUM_LENGTH),' ')
    END
    +' COLLATE ' + @toCollation+' '+
    CASE IS_NULLABLE
    WHEN 'YES' THEN 'NULL'
    WHEN 'No' THEN 'NOT NULL'
    END
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE DATA_TYPE IN ('varchar' ,'char','nvarchar','nchar','text','ntext')
    -- AND COLLATION_NAME LIKE @fromCollation
    AND TABLE_NAME = @TABLE_NAME

    /* Alter Collation where needed on current table */
    OPEN SEL_CHANGE_COLLATE
    FETCH NEXT FROM SEL_CHANGE_COLLATE INTO @ALTER_COLLATE_STMT
    /* Loop around columns */
    WHILE @@FETCH_STATUS = 0
    BEGIN
    /* Execute alter command */
    EXEC(@ALTER_COLLATE_STMT)
    /* Get next alter stmt */
    FETCH NEXT FROM SEL_CHANGE_COLLATE INTO @ALTER_COLLATE_STMT
    END
    CLOSE SEL_CHANGE_COLLATE
    DEALLOCATE SEL_CHANGE_COLLATE

    /* Recreate key and indexes on table */
    EXEC(@ALL_TBL_IDX_STMT)

    /* Get next table name */
    FETCH NEXT FROM SEL_USER_TABLES INTO @TABLE_NAME
    END
    /* Close table cursor */
    CLOSE SEL_USER_TABLES
    DEALLOCATE SEL_USER_TABLES


    /* Cursor for all user views */
    DECLARE SEL_USER_VIEWS CURSOR FOR
    SELECT TABLE_NAME
    FROM INFORMATION_SCHEMA.VIEWS
    ORDER BY TABLE_NAME

    /* Open view cursor */
    OPEN SEL_USER_VIEWS
    /* Get view name */
    FETCH NEXT FROM SEL_USER_VIEWS INTO @VIEW_NAME

    /* Loop around views */
    WHILE @@FETCH_STATUS = 0
    BEGIN
    /* Refresh view */
    exec sp_refreshview @VIEW_NAME
    /* Get next view name */
    FETCH NEXT FROM SEL_USER_VIEWS INTO @VIEW_NAME
    END
    /* Close view cursor */
    CLOSE SEL_USER_VIEWS
    DEALLOCATE SEL_USER_VIEWS

  •  12-02-2009, 17:48 48393 σε απάντηση της 42388

    Απ: SQL Server 2005 Case Sensitivity

    Τα scripts φαίνονται ενδιαφέροντα με μια πρώτη ματιά.

    Αν και έχει περάσει μεγάλο χρονικό διάστημα από την την καταχώριση του τελευταίου μηνύματος στο συγκεκριμένο θέμα, θα ήθελα να προσθέσω  πως απ' όσο έχω διαβάσει (στο net οπότε δεν μπορώ να επαληθεύσω την εγκυρότητα της πληροφορίας) ότι αν γίνει εγκατάσταση του SQL Server με case sensitivity τότε και η ονομασία των objects θα είναι επίσης case sensitive, ενώ στην αντίθετη περίπτωση δεν είναι case sensitive.

    Έτυχε πρόσφατα stored procedure που λειτουργούσε κανονικά, όταν μεταφέρθηκε σε άλλο server από κάποιο τεχνικό τμήμα, να μη λειτουργεί εξαιτίας του ότι κάποιες global μεταβλητές δεν αναγνωριζόντουσαν εξαιτίας του case sensitivity.

    Εγκυκλοπαιδικά

    ------------
    Theof
  •  12-03-2009, 22:00 49141 σε απάντηση της 48393

    Απ: SQL Server 2005 Case Sensitivity

    Η παρατήρησή σου πιθανόν είναι σωστή.

    Η αλήθεια είναι πως ο SQL Server έχει 3 επίπεδα για το case sensitivity όπως αναφέρθηκε και πιο πάνω( Instance, Database, Column). Το θέμα είναι για τα ονόμτα των objects όπως ας πούμε ενός πίνακα ποιο από τα 2 πρώτα ευθύνεται; Φαντάζομαι ότι το λογικό είναι να ευθύνεται το 2ο, δηλαδή αυτό της βάσης ! Ωστόσο, δεν ξέρω κατά πόσο όταν εγκαταστήσεις ένα Instance που είναι Case Sensitive, σου επιτρέπει μετά να φτιάξεις βάσεις που είναι Case Insensitive !! και το αντίστροφο φυσικά. Φαντάζομαι εκεί είναι το κλειδί του προβλήματισμού.

    Πάντως το script που είχα αναρτήσει παραπάνω δοκιμάστηκε αρκετά και μπορώ πλέον να πω πως δουλεύει αποτελεσματικά. Ένα "τρωτό" θα μπορούσε κανείς να επισημάνει: Προϋποθέτει ότι δεν υπάρχουν Foreign Keys ! Αν υπάρχουν χτυπά σε ένα ένα από αυτά, οπότε είσαι αναγκασμένος να φτιάξεις 2 scripts ακόμα, 1 που θα τα ρίχνει όλα και 1 που θα τα ξανασηκώνει φυσικά ώστε να το εκτελέσεις μετά την εκτέλεση του τροποποιητικού script.

    antonisV
  •  13-03-2009, 00:03 49143 σε απάντηση της 49141

    Απ: SQL Server 2005 Case Sensitivity

    Το πρόβλημα έχει να κάνει με το server collation setting το οποίο επιλέγεις όταν εγκαθιστάς τον Sql Server. (μίλαμε πάντα για το πρόβλημα με τα object names, όχι τα data).
    Πρέπει να δημιουργεί τις system databases με το colation που επιλέγεις στο setup.

    Κάπου είχα βρει και ένα link, στο οποίο αναφερόταν πως έπρεπε να γίνει επανεγκατάσταση, και έδινες ώς παραμέτρους τα collations που ήθελες να αλλάξεις.

    (http://yannis.spaces.live.com/Blog/cns!DB18F7F778686DA1!553.entry)
    "You can do this by running the following command from the "C:\Program Files\Microsoft SQL Server\90\Setup Bootstrap" folder. Make sure the SQL Server 2005 original CD is available:
    start /wait setup.exe /qb INSTANCENAME=MSSQLSERVER REINSTALL=SQL_Engine REBUILDDATABASE=1 SAPWD=test SQLCOLLATION=SQL_Latin1_General_CP1_CI_AI"

    http://marcellotonarelli.wordpress.com/2009/01/25/how-to-change-ms-sql-server-2005-server-collation/
    http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SQL-Server-2005/Q_23422696.html


    >Πάντως το script που είχα αναρτήσει παραπάνω δοκιμάστηκε αρκετά και μπορώ πλέον να πω πως δουλεύει αποτελεσματικά. Ένα "τρωτό" θα μπορούσε κανείς να επισημάνει: Προϋποθέτει ότι δεν υπάρχουν Foreign Keys ! Αν υπάρχουν χτυπά σε ένα ένα από αυτά, οπότε είσαι αναγκασμένος να φτιάξεις 2 >scripts ακόμα, 1 που θα τα ρίχνει όλα και 1 που θα τα ξανασηκώνει φυσικά ώστε να το εκτελέσεις μετά την εκτέλεση του τροποποιητικού script.

    Είναι θετικό που τα έχεις δοκιμάσει και μπορείς να επιβεβαιώσεις την λειτουγία τους.

    Ελπίζω αν έχει κάποιος πρόβληματα, στο μέλλον να μπορέσει να βοηθηθεί από τα links, ή/και αν βρει κάτι καλύτερο ας το εισάγει και στο thread....

    Καληνύχτα από μένα...




    ------------
    Theof
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems