Prise en charge d'Unicode pour Invoke-Sqlcmd dans PowerShell

Le module PowerShell sqlps fournit un support principal pour l'access à SQL Server depuis PowerShell et son applet de command Invoke-Sqlcmd est son principal outil d'exécution de requêtes littérales ou de files de script SQL (analogue à l'utilitaire sqlcmd non PowerShell). J'ai récemment essayé quelques expériences pour confirmer que Invoke-Sqlcmd gère Unicode et a eu des résultats surprenants.

J'ai commencé avec ce simple file de script (nommé unicode.sql):

CREATE TABLE #customers ( [IdCust] int, [FirstName] nvarchar(25), [SurName] nvarchar(25) ); INSERT INTO #customers VALUES (4, N'Hans', N'Grüßner') SELECT * FROM #customers; DROP TABLE #customers; 

Notez que le nom de famille a des caractères Unicode typiques que l'on pourrait find dans un nom allemand, par exemple.


Résultats

SQL Server Management Studio: restitue correctement la sortie en grid ou en text, par ex.

 IdCust FirstName Surname ----------- ------------------------- ------------------------- 4 Hans Grüßner 

Utilitaire sqlcmd: Rend correctement si exécuté à partir d'un shell DOS ou d'un PowerShell, par exemple

 C:\> sqlcmd -S .\SQLEXPRESS -i unicode.sql IdCust FirstName Surname ----------- ------------------------- ------------------------- 4 Hans Grüßner 

PowerShell Invoke-Sqlcmd: Rendus incorrectement (que ce soit en tant que text comme indiqué ci-dessous ou transmis dans Out-Gridview):

 PS> Invoke-Sqlcmd -Server .\sqlexpress -InputFile unicode.sql IdCust FirstName Surname ------ --------- ------- 4 Hans Gr??ner 

La documentation MSDN pour Invoke-Sqlcmd mentionne Unicode seulement en passant, comparant ses commutateurs de command line à ceux de sqlcmd, montrant que si ce dernier a une option -u pour sortir Unicode (qui n'était même pas nécessaire dans mon expérience ci-dessus), Invoke -Sqlcmd n'a pas de paramètre équivalent.

Je n'ai rien trouvé du tout concernant ce point à travers une search approfondie sur le Web, mais je garde toujours l'espoir que c'est en quelque sorte une erreur de l'user de ma part. Est-il possible de conserver datatables d'input lors de la récupération avec Invoke-Sqlcmd dans PowerShell?

Mise à jour J'ai testé invoke-sqlcmd sur une autre machine et cela fonctionne, donc peut-être que le rest ne s'applique pas …

Mise à jour 2 Seulement semble avoir un problème avec -inputfile lors de l'exécution via le paramètre -Query invoke-sqlcmd fonctionne très bien.

De ce que je peux dire cela a quelque chose à voir avec ADO.NET DataTable lors de la conversion d'une string. Cela fonctionne correctement lorsque vous utilisez un ExecuteScaler ou ExecuteReader. Bien sûr, cela ne corrige pas invoke-sqlcmd, mais explique pourquoi:

 $server = "$env:computername\sql1" $database = "tempdb" $query = @" CREATE TABLE #customers ( [SurName] nvarchar(25) ); INSERT INTO #customers VALUES (N'Grüßner') SELECT * FROM #customers; "@ $connection=new-object System.Data.SqlClient.SQLConnection $connection.ConnectionSsortingng="Server={0};Database={1};Integrated Security=True" -f $server,$database $command=new-object system.Data.SqlClient.SqlCommand($query,$connection) $connection.Open() $command.ExecuteScalar() $connection.Close() 

Mise à jour 3 L'enencoding du file semble être la key. En regardant [System.IO.File] :: ReadAllText, le document MSDN indique qu'il ne détectera que l'enencoding UTF-8 ou UTF-32. http://msdn.microsoft.com/en-us/library/ms143369(v=vs.90).aspx

Si je sauvegarde le file .sql avec UTF-8, l'utilisation du paramètre -inputfile fonctionne. Vous pouvez choisir UTF-8 lors de l'logging du file .sql dans SSMS, mais voici un code Powershell pour vérifier et modifier l'enencoding également. Vous devrez récupérer Get-FileEncoding.ps1 depuis http://poshcode.org/2075

 . .\Get-FileEncoding.ps1 Get-FileEncoding -Path E:\bin\unicode.sql $query = get-content E:\bin\unicode.sql $query= $query -join "`n" $query | Out-File -FilePath e:\bin\unicode.sql -Encoding UTF8 -force Get-FileEncoding -Path E:\bin\unicode.sql