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?
4 réponses
il y a plus d'information sur ce forum MSDN:
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
Voici une réponse plus complète:
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
.
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 tousNVARCHAR
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 deuxsys.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 ettempdb
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 pasNVARCHAR
données). Le non-EBCDICSQL_
Collations utilisez ce qu'on appelle "String Sort" pourVARCHAR
données, alors que toutes les autres Collations, et mêmeNVARCHAR
données pour le non-EBCDICSQL_
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
etLatin1_General_100_CI_AS
est la capacité à faire ExpansionsVARCHAR
données (NVARCHAR
données peuvent déjà le faire pour la plupart desSQL_
Collations), comme la manipulationæ
comme si c' étaientae
: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" quandCREATE #TempTable
est exécuté et[tempdb]
. Lors de la création d' tables temporaires, déclarez une collation en utilisant leCOLLATE
clause et spécifier une compilation deDATABASE_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, etGOTO
é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 deuxA
eta
, leSQL_
les Classements seront trierA
avanta
, alors que le non -SQL_
les Classements (et l'SQL_
les Classements en traitant avecNVARCHAR
données) va triera
avantA
.
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.