Est-ce que SQL Server SQL Latin1 General CP1 CI AS peut être converti en Latin1 General CI AS?

nous avons une base de données ancienne avec quelques colonnes (anciennes) utilisant "SQL_Latin1_General_CP1_CI_AS" et des modifications plus récentes ont utilisé "Latin1_General_CI_AS".

il s'agit d'une douleur que les jointures ont besoin de L'énoncé COLLATE supplémentaire pour fonctionner.

je voudrais tout mettre sur"Latin1_General_CI_AS". De ce que je peux en déduire, ce sont des collations plus ou moins identiques et je ne perdrai pas de données au cours de ce processus...

est ce que quelqu'un sait si c'est le cas?

18
demandé sur Kram 2011-06-09 21:34:40

4 réponses

il y a plus d'information sur ce forum MSDN:

http://social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/196b4586-1338-434d-ba8c-49fa3c9bdeeb/

qui dit:

vous devriez voir peu de différence si la collation est SQL_Latin1_General_CP1_CI_AS ou Latin1_General_CI_AS, mais les deux ont des instances où ils sont plus rapides ou plus lents que l'autre.

Latin1_General_CI_AS: - Latin1-General, insensible à la casse, accent- sensible, insensible au kanatype, insensible à la largeur

SQL_Latin1_General_CP1_CI_AS: - Latin1-général, insensible à la casse, sensible à l'accent, insensible au kanatype, insensible à la largeur pour Unicode Données, ordre de tri du serveur SQL 52 sur la page de Code 1252 pour les données non Unicode

donc à mon avis vous ne devriez pas voir une différence, surtout si vos données sont seulement a-z0-9

11
répondu dunos 2014-08-04 12:22:12

Voici une réponse plus complète:

https://www.olcot.co.uk/revised-difference-between-collation-sql_latin1_general_cp1_ci_as-and-latin1_general_ci_as/

la principale différence entre ces collations réside dans la façon dont elles appliquent les règles d'extension des caractères. Certains caractères latins peuvent être élargis en plusieurs caractères. Les collations SQL_xxxx peuvent ignorer ces extensions de caractères en travaillant avec du texte non unicode, mais les appliquer pour unicode texte. Résultat: les jointures, les tris et les comparaisons peuvent donner des résultats différents lorsqu'on utilise une collation par rapport à l'autre.

Exemple:

Latin1_General_CI_AS ces deux déclarations retour le même ensemble d'enregistrements, comme ß est étendu à ss.

SELECT * FROM MyTable3 WHERE Comments = 'strasse'
SELECT * FROM MyTable3 WHERE Comments = 'straße'

en utilisant SQL_Latin1_General_CP1_CI_AS les énoncés ci-dessus renvoient des enregistrements différents, puisque le ß est traité comme un caractère différent de celles de ss.

22
répondu Zarepheth 2018-08-01 14:35:44

si vous allez changer la compilation d'une base de données, alors il y a certainement des choses que vous devriez savoir pour que vous puissiez planifier en conséquence:

  • en ce qui concerne le potentiel de perte de données:

    • NVARCHAR champs sont tous Unicode, qui est un jeu de caractères unique, donc il ne peut y avoir aucune perte de données de ces champs (ce qui couvre également les champs XML qui sont également stockées en tant que UTF-16 Little Endian). Champs de méta-données qui stockent l'objet / colonne / index / les noms etc sont tous NVARCHAR donc pas besoin de s'inquiéter à propos de ceux-ci.
    • VARCHAR champs ayant des Collations différentes mais la même page de Code entre les différentes Collations ne sera pas un problème puisque la Page de Code est le jeu de caractères.
    • VARCHAR champs ayant des Collations différentes et se déplaçant vers une Page de Code différente (en changeant les Collations) avoir une perte de données si l'un des caractères utilisés n'est pas représenté dans la nouvelle Page de Code. CEPENDANT, ce est seulement un problème lors de la modification physique de la compilation d'un champ particulier (décrit ci-dessous) et ne se produirait pas lors de la modification de la compilation par défaut d'une base de données.
  • les variables locales et les caractères littéraux des chaînes de caractères obtiennent leur Compilation à partir de la base de données par défaut. Changer la valeur par défaut de la base de données modifiera la compilation utilisée à la fois pour les variables locales et les littérales de chaîne. Mais changer la Collation par défaut de la base de données ne change pas la Collation utilisée pour chaîne de champs dans les tables dans la Base de données. C'est ce qui provoque la situation où vous obtenez implicite conversions question qui pourrait invalider les indices (décrit dans le blog lié à @Zarepheth réponse).

    si vous voulez modifier la Collation par défaut de votre base de données, alors tout champ de chaîne filtré par une variable locale ou une chaîne littérale doit avoir sa Collation modifiée pour correspondre à la Collation par défaut de la base de données. Vous utilisez ce qui suit pour ce faire:

    ALTER TABLE [{table_name}]
       ALTER COLUMN [{column_name}]
       {same_datatype}
       {same_NULL_or_NOT NULL_setting}
       COLLATE {name_of_Database_default_Collation};
    

    après cela, s'il y a des index sur n'importe lequel des champs de chaîne qui viennent d'avoir leur Collation changée, alors vous devez reconstruire ces index.

  • modifier la compilation par défaut de la base de données modifiera la compilation de certaines métadonnées spécifiques à la base de données, comme name champ dans les deux sys.objects,sys.columns,sys.indexes, etc. Le filtrage de ces vues système contre des variables locales ou des littérales de chaîne ne sera pas ce sera un problème puisque la collecte changera des deux côtés. Mais, si vous rejoignez n'importe laquelle des vues système locales aux tables temporaires sur les champs de chaîne, et la Collation de niveau de base de données entre la base de données locale et tempdb ne correspond pas, alors vous obtiendrez le "Classement" incompatibilité d'erreur. Ceci est discuté ci-dessous avec le remède.

  • une différence entre ces deux Collations est dans la façon dont ils trient certains caractères pour VARCHAR données (cela n'affecte pas NVARCHAR données). Le non-EBCDIC SQL_ Collations utilisez ce qu'on appelle "String Sort" pour VARCHAR données, alors que toutes les autres Collations, et même NVARCHAR données pour le non-EBCDIC SQL_ Collations, utilisez ce qu'on appelle "le tri des mots". La différence est que dans "Word Sort", le tiret - et de l'apostrophe ' (et peut-être quelques autres personnages?) ont un poids très faible et sont essentiellement ignorés à moins qu'il n'y ait pas d'autres différences dans les chaînes. Pour voir ce comportement en action, lancez le suivantes:

    DECLARE @Test TABLE (Col1 VARCHAR(10) NOT NULL);
    INSERT INTO @Test VALUES ('aa');
    INSERT INTO @Test VALUES ('ac');
    INSERT INTO @Test VALUES ('ah');
    INSERT INTO @Test VALUES ('am');
    INSERT INTO @Test VALUES ('aka');
    INSERT INTO @Test VALUES ('akc');
    INSERT INTO @Test VALUES ('ar');
    INSERT INTO @Test VALUES ('a-f');
    INSERT INTO @Test VALUES ('a_e');
    INSERT INTO @Test VALUES ('a''kb');
    
    SELECT * FROM @Test ORDER BY [Col1] COLLATE SQL_Latin1_General_CP1_CI_AS;
    -- "String Sort" puts all punctuation ahead of letters
    
    SELECT * FROM @Test ORDER BY [Col1] COLLATE Latin1_General_100_CI_AS;
    -- "Word Sort" mostly ignores dash and apostrophe
    

    Renvoie:

    String Sort
    -----------
    a'kb
    a-f
    a_e
    aa
    ac
    ah
    aka
    akc
    am
    ar
    

    et:

    Word Sort
    ---------
    a_e
    aa
    ac
    a-f
    ah
    aka
    a'kb
    akc
    am
    ar
    

    alors que vous allez "perdre" le comportement de "String Sort", Je ne suis pas sûr que j'appellerais ça une "fonctionnalité". C'est un comportement qui a été jugé indésirable (comme le prouve le fait qu'il n'a été avancé dans aucune des collations Windows). Cependant, il une différence de comportement entre les deux collations (encore une fois, juste pour les non-EBCDIC VARCHAR données), et vous pouvez avoir le code et/ou les attentes du client basé sur le comportement de "tri de chaîne". cela nécessite de tester votre code et éventuellement de faire des recherches pour voir si ce changement de comportement pourrait avoir un impact négatif sur les utilisateurs.

  • une Autre différence entre SQL_Latin1_General_CP1_CI_AS et Latin1_General_100_CI_AS est la capacité à faire ExpansionsVARCHAR données (NVARCHAR données peuvent déjà le faire pour la plupart des SQL_ Collations), comme la manipulation æ comme si c' étaient ae:

    IF ('æ' COLLATE SQL_Latin1_General_CP1_CI_AS =
        'ae' COLLATE SQL_Latin1_General_CP1_CI_AS)
    BEGIN
      PRINT 'SQL_Latin1_General_CP1_CI_AS';
    END;
    
    IF ('æ' COLLATE Latin1_General_100_CI_AS =
        'ae' COLLATE Latin1_General_100_CI_AS)
    BEGIN
      PRINT 'Latin1_General_100_CI_AS';
    END;
    

    Renvoie:

    Latin1_General_100_CI_AS
    

    La seule chose qui vous "perdre" est ici être capable de faire ces expansions. En général, c'est un autre avantage de passer à une Collation Windows. Cependant, tout comme avec le mouvement "String Sort" à "Word Sort", la même prudence s'applique: c'est une différence de comportement définie entre les deux collations (encore une fois, juste pour VARCHAR données), et vous pourriez avoir de code et/ou le client attentes fondées sur avoir ces mappages. cela nécessite de tester votre code et éventuellement de faire des recherches pour voir si ce changement de comportement pourrait avoir un impact négatif sur les utilisateurs.

    (d'abord noté dans @Zarepheth's réponse et développé ici)

  • la Collation au niveau du serveur est utilisée pour définir la Collation des bases de données système, qui inclut [model]. [model] base de données est utilisé comme un modèle pour créer de nouvelles bases de données, qui comprend [tempdb] à chaque démarrage du serveur. Ainsi, si la collation par défaut de la base de données ne correspond pas à la Collation par défaut de l'instance et vous rejoignez les tables locales aux tables temporaires sur les champs string, puis vous obtiendrez L'erreur Collation-mismatch. Heureusement, il existe un moyen assez facile de corriger les différences de collation entre la base de données qui est "actuelle" quand CREATE #TempTable est exécuté et [tempdb]. Lors de la création d' tables temporaires, déclarez une collation en utilisant le COLLATE clause et spécifier une compilation de DATABASE_DEFAULT:

    CREATE TABLE #Temp (Col1 NVARCHAR(40) COLLATE DATABASE_DEFAULT);
    

    ceci n'est pas nécessaire pour les variables de table car elles obtiennent leur Compilation par défaut à partir de la base de données "courante". Cependant, si vous avez à la fois des variables de table et des tables temporaires et que vous les Rejoignez sur des champs de chaîne, alors vous devrez utiliser COLLATE DATABASE_DEFAULT comme indiqué ci-dessus.

  • la compilation au niveau du serveur contrôle aussi les noms des variables locales., CURSOR noms variables, et GOTO étiquettes. Si aucun de ces seraient touchées par le changement spécifique traitée dans cette Question, il est au moins quelque chose d'être conscient de.

  • Il est préférable d'utiliser la version la plus récente du classement désiré, si plusieurs versions sont disponibles. À partir de SQL Server 2005, une série de collations" 90 "a été introduite, et SQL Server 2008 a introduit une série de collations" 100". Vous pouvez trouver ces classements en utilisant les requêtes suivantes:

    SELECT * FROM sys.fn_helpcollations() WHERE [name] LIKE N'%[_]90[_]%'; -- 476
    
    SELECT * FROM sys.fn_helpcollations() WHERE [name] LIKE N'%[_]100[_]%'; -- 2686
    
  • aussi, alors que la question pose des Collations non sensibles à la casse, il faut noter que si quelqu'un d'autre cherche à faire un changement similaire mais utilise des Collations sensibles à la casse, alors une autre différence entre les Collations SQL Server et Windows Collations, VARCHAR uniquement les données, auquel cas sortes première. Ce qui veut dire, si vous avez les deux A et a, le SQL_ les Classements seront trier A avant a, alors que le non -SQL_ les Classements (et l' SQL_ les Classements en traitant avec NVARCHAR données) va trier a avant A.

13
répondu Solomon Rutzky 2017-11-16 18:57:28
SELECT * FROM ::fn_helpcollations()
WHERE name IN (
'SQL_Latin1_General_CP1_CI_AS',
'Latin1_General_CI_AS'
)

...donner...

Latin1_General_CI_AS: Latin1-général, insensible à la casse, sensible à l'accent, insensible au kanatype, insensible à la largeur

SQL_Latin1_General_CP1_CI_AS: Latin1-général, insensible à la casse, sensible à l'accent, insensible au kanatype, insensible à la largeur pour les Données Unicode, SQL Server Ordre de Tri 52 sur la Page de Code 1252 pour les Données non-Unicode

donc à partir de là, j'en déduirais que la page de code utilisée est la même (Latin1-General => 1252), de sorte que vous devrait ne rencontrez aucune perte de données - si quelque chose devait changer après la conversion, ce pourrait être l'ordre de tri-ce qui est probablement sans importance.

6
répondu Will A 2011-06-09 18:12:50