SSIS - fichier Plat toujours ANSI jamais codé en UTF-8
assez simple package SSIS:
- OLE DB Source pour obtenir des données via une vue, (toutes les colonnes de chaîne dans la table db nvarchar ou nchar).
- colonne dérivée pour formater la date existante et l'ajouter à l'ensemble de données, (type de données DT_WSTR).
- tâche de multidiffusion pour diviser l'ensemble de données entre:
- commande OLE DB pour mettre à jour les lignes en tant que "traité".
- destination du fichier plat - dont le gestionnaire de connexion est positionné à la page de Code 65001 UTF-8 et Unicode ne sont pas contrôlés. Toutes les colonnes de chaînes de caractères correspondent à DT_WSTR.
chaque fois que j'exécute ce paquet, j'ouvre le fichier flat dans le bloc-notes++ son ANSI, jamais UTF-8. Si je coche L'option Unicode, le fichier est UCS-2 Little Endian.
est - ce que je fais quelque chose de mal-comment puis-je obtenir que le fichier plat soit encodé en UTF-8?
Merci
4 réponses
Dans La Source -> Avance De L'Éditeur -> Propriétés Du Composant -> Définir la Page de Code par défaut à 65001 Always usedefaultcodepage to True
Puis-Source->Avance De L'Éditeur -> Entrée Et De Sortie Des Propriétés Vérifiez chaque colonne dans les colonnes externes et les colonnes de sortie et réglez CodePage à 65001 dans la mesure du possible.
c'est tout.
D'ailleurs Excel ne peut pas définir les données à L'intérieur du fichier comme étant UTF - 8. Excel n'est qu'un gestionnaire de fichiers. Vous pouvez créer des fichiers csv en utilisant aussi le bloc-notes. comme tant que vous remplissez le fichier csv avec UTF-8 Vous devriez être bien.
ajouter des explications aux réponses ...
paramétrage de la page de code à 65001 (mais ne cochez pas la case Unicode sur la source du fichier), devrait générer un fichier UTF-8. (Oui, les types de données internes devraient aussi être nvarchar, etc.).
mais le fichier qui est produit à partir de SSIS n'a pas d'en-tête BOM (Byte Order Marker), donc certains programmes supposeront qu'il est toujours ASCII, pas UTF-8. J'ai vu cela confirmé par les employés de MS sur MSDN, ainsi que confirmée par des essais.
la solution d'ajout de fichier est un moyen de contourner cela - en créant un fichier vierge avec le bon BOM, puis en ajoutant des données de SSIS, l'en-tête de BOM reste en place. Si vous dites à SSIS d'écraser le fichier, il perd aussi le BOM.
Merci pour les conseils ici, il m'a aidé à comprendre le détail ci-dessus.
j'ai récemment travaillé sur un problème où nous rencontrons une situation telle que:
vous travaillez sur une solution utilisant les Services D'intégration de SQL Server (Visual Studio 2005). Vous tirez des données de votre base de données et essayer de placer les résultats dans un fichier plat (.CSV) au format UTF-8. La solution exporte parfaitement les données et conserve les caractères spéciaux dans le fichier parce que vous avez utilisé 65001 comme page de code.
cependant, le fichier texte quand vous l'Ouvrez ou essayez de le charger dans un autre processus, il est dit que le fichier est ANSI au lieu de UTF-8. Si vous ouvrez le fichier dans le bloc-notes et faites une sauvegarde et changez L'encodage en UTF-8 et alors votre processus externe fonctionne mais c'est un travail manuel fastidieux.
ce que j'ai trouvé que lorsque vous spécifiez la propriété page de Code du gestionnaire de connexion de fichiers Flat, il génère un fichier UTF-8. Cependant, il génère une version du fichier UTF-8 qui manque quelque chose que nous appelons Byte Order Marque.
donc si vous avez un fichier CSV contenant le caractère AA, le BOM pour UTF8 sera 0xef, 0xbb et 0xbf. Même si le fichier n'a pas de BOM, il est toujours UTF8.
malheureusement, dans certains anciens systèmes, les applications cherchent le BOM pour déterminer le type du fichier. Il semble que votre processus fasse de même.
pour contourner le problème, vous pouvez utiliser le code suivant dans la tâche script qui peut être exécutée après l'exportation processus.
using System.IO;
using System.Text;
using System.Threading;
using System.Globalization;
enter code here
static void Main(string[] args)
{
string pattern = "*.csv";
string[] files = Directory.GetFiles(@".\", pattern, SearchOption.AllDirectories);
FileCodePageConverter converter = new FileCodePageConverter();
converter.SetCulture("en-US");
foreach (string file in files)
{
converter.Convert(file, file, "Windows-1252"); // Convert from code page Windows-1250 to UTF-8
}
}
class FileCodePageConverter
{
public void Convert(string path, string path2, string codepage)
{
byte[] buffer = File.ReadAllBytes(path);
if (buffer[0] != 0xef && buffer[0] != 0xbb)
{
byte[] buffer2 = Encoding.Convert(Encoding.GetEncoding(codepage), Encoding.UTF8, buffer);
byte[] utf8 = new byte[] { 0xef, 0xbb, 0xbf };
FileStream fs = File.Create(path2);
fs.Write(utf8, 0, utf8.Length);
fs.Write(buffer2, 0, buffer2.Length);
fs.Close();
}
}
public void SetCulture(string name)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(name);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(name);
}
}
lorsque vous lancerez le paquet, vous constaterez que tous les CSVs du dossier désigné seront convertis dans un format UTF8 qui contient le symbole d'ordre des octets.
de cette façon, votre processus externe pourra fonctionner avec les fichiers CSV exportés.
si vous cherchez uniquement un dossier particulier...envoyez cette variable à la tâche script et utilisez une valeur inférieure..
string sPath;
sPath=Dts.Variables["User::v_ExtractPath"].Value.ToString();
string pattern = "*.txt";
string[] files = Directory.GetFiles(sPath);
j'espère que cela aide!!
OK-semble avoir trouvé une solution de rechange acceptable sur SQL Server Forums. Essentiellement, j'ai dû créer deux fichiers de template UTF-8, utiliser une tâche de fichier pour les copier à ma destination, puis s'assurer que j'ai ajouté des données plutôt que de réécrire.