Komenda SQLCMD nie może wstawiać akcentów

19

Próbuję uruchomić program sqlcmd.exe w celu skonfigurowania nowej bazy danych z wiersza polecenia. Używam SQL SERVER Express 2012 w systemie Windows 7 64 bity.

Oto polecenie, którego używam:

SQLCMD -S .\MSSQLSERVER08 -V 17 -E -i %~dp0\aqualogyDB.sql -o %~dp0\databaseCreationLog.log 

A oto fragment skryptu tworzenia pliku sql:

    CREATE DATABASE aqualogy 
    COLLATE Modern_Spanish_CI_AS
    WITH TRUSTWORTHY ON, DB_CHAINING ON;
    GO
    use aqualogy
    GO
    CREATE TABLE [dbo].[BaseLayers] (
    [Code] nchar(100) NOT NULL ,
    [Geometry] nvarchar(MAX) NOT NULL ,
    [IsActive] bit NOT NULL DEFAULT ((1)) 
    )

    EXEC sp_updateextendedproperty @name = N'MS_Description', @value = N'Capas de     cartografía base de la aplicaicón. Consideramos en Galia Móvil la cartografía(...)'
, @level0type = 'SCHEMA', @level0name = N'dbo'
, @level1type = 'TABLE', @level1name = N'BaseLayers'

Cóż, sprawdź, czy słowa zawierają akcenty; który jest opisem tabeli. Baza danych jest tworzona bez problemów. „Sortowanie” jest rozumiane przez skrypt, jak widać na załączonym zrzucie ekranu. Mimo to akcenty nie są poprawnie wyświetlane podczas sprawdzania stołu.Problem z sortowaniem

Byłbym wdzięczny za każdą pomoc. Dziękuję Ci bardzo.

[Edytuj]: Cześć wszystkim. Zmiana kodowania plików SQL za pomocą Notepad ++ działała dobrze! Bardzo dziękuję za pomoc: nauczyłem się czegoś ciekawego z tym problemem!

wprowadź opis zdjęcia tutaj

Oskytar
źródło
1
Jakie jest kodowanie pliku skryptu SQL?
Pondlife
Poszedłbym z pomysłem @ Pondlife. Chwyć edytor tekstu (np. Notepad ++), otwórz tam plik .sql, przejdź do Kodowania i sprawdź, czy nie ma pliku ANSI (lub innego nieobsługiwanego kodowania). Jeśli tak, wybierz plik do przekonwertowania na coś innego. Powiedziałbym, że UTF8 powinien to zrobić. Daj nam znać, jak poszło.
Marian

Odpowiedzi:

8

Jak wynika z komentarzy, problem nie dotyczy dokładnie tabeli ani sposobu importowania znaków specjalnych przez SQLCMD. Zwykle problematyczne importowanie jest związane z formatem samego skryptu.

Samo Management Studio oferuje opcję zapisywania z określonym kodowaniem, co powinno rozwiązać problem w przyszłości. Podczas zapisywania pliku po raz pierwszy (lub użyj opcji Zapisz jako) powinieneś kliknąć małą strzałkę obok przycisku Zapisz , aby użyć opcji Zapisz z kodowaniem .

wprowadź opis zdjęcia tutaj

Domyślnie zapisuje plik w Europie Zachodniej (1252) . Ilekroć mam jakieś znaki specjalne, używam UTF8 (choć może pasowałby jakiś inny kod restrykcyjny), ponieważ zwykle jest to najszybsza poprawka.

wprowadź opis zdjęcia tutaj

Nie jestem pewien (z obrazka), że używasz SSMS, więc upewnij się, że twój własny edytor ma opcję zapisania pliku w innym kodowaniu. Jeśli nie, konwersja pliku w inteligentnym edytorze (jak już próbowałeś w Notepad ++) zwykle działa. Chociaż może to nie działać, jeśli konwertujesz z szerokiego kodowania na węższe, a następnie z powrotem na szerokie (np. Z Unicode na ANSI iz powrotem na Unicode).

Marian
źródło
Cześć Marian. Jeszcze raz dziękuję. Użyłem funkcji „Transfer danych” z Navicat, ponieważ podoba mi się sposób, w jaki generuje skrypt SQL (szybki, niezależny od plików mdf i od tej pory zawsze działał dla mnie). Sprawdziłem niektóre parametry w funkcji „Transfer danych” w Navicat, ale nie znalazłem żadnego sposobu na zmianę kodowania pliku wyjściowego. Będę musiał wykonać dodatkową pracę przy użyciu Notepad ++, aby zmienić kodowanie, ale to nie jest wielka sprawa.
Oskytar
Dobrze nie ma problemu. Chociaż zwykle podziękowania na tej stronie są dostarczane za pomocą funkcji Upvote (strzałka w górę obok odpowiedzi), jeśli odpowiedź jest przydatna lub, jeśli całkowicie rozwiązuje problem, nawet używając Znaku jako odpowiedzi (Znacznik wyboru obok odpowiedzi ) :-). Zobacz więcej tutaj, w FAQ .
Marian
Poprawiam ostatni komentarz: Podczas wykonywania „Transferu danych” w Navicat MOŻNA wybrać kodowanie wyjścia pliku.
Oskytar,
Fajnie, więc teraz będziesz mógł ominąć krok ręcznej konwersji. To nawet lepiej.
Marian
2
Ta odpowiedź wydaje się nieprawidłowa. Miałem plik zapisany przez Notepad ++ w UTF-8. SQLCMD.exe nie przesyła poprawnie znaków. Jeśli skopiuję zawartość do SSMS, działa dobrze. Prawdziwym rozwiązaniem była odpowiedź udzielona przez swasheck, aby dodać parametr param -f 65001.
Tomas Kubes
39

Inną opcją, jeden który ja właśnie nauczyłem, pochodzi z tej sqlcmddokumentacji . Musisz ustawić stronę kodową, sqlcmdaby pasowała do kodowania pliku. W przypadku UTF-8 strona kodowa to 65001, więc chcesz:

SQLCMD -S .\MSSQLSERVER08 -V 17 -E -i %~dp0\aqualogyDB.sql -o %~dp0\databaseCreationLog.log -f 65001

swasheck
źródło
1
To właśnie uratowało mi życie, miałem zamiar zrobić skrypt PowerShell, aby odczytać plik CSV z import-csv -encoding UTF8 go dostać to poprawnie. Dzięki
Spörri
To działało dla mnie, gdy musiałem wstawić wartości tekstowe w języku irlandzkim za pomocą fadas (á, é, í, ó, ú) do kolumny
NVARCHAR
To poprawna odpowiedź
Pitchmatt
2

Tego rodzaju rzeczy są bardzo trudne, ponieważ tyle się robi bez mówienia.

Pierwszą rzeczą, którą bym zrobił, to użyć sqlcmd do wyświetlenia ciągu. Jeśli wyświetla się poprawnie w oknie cmd.exe, jest to jeden użyteczny fakt. Następnie wybrałabym wiersz convertdo varbinary, aby zobaczyć, jakie bajty faktycznie tam są. Myślę, że cartografía pojawi się jako 0x636172746f67726166c3ad61, gdzie akcentowane „i” jest reprezentowane przez bajty c3ad, które są kodowaniem UTF-8 dla tego znaku. Nie jest dobrze mieć UTF-8 w nowoczesnej hiszpańskiej kolumnie (Windows 1252). Wartość bajtu w systemie Windows 1252 dla tego znaku wynosi 237 miejsc dziesiętnych (ED szesnastkowa).

Jeśli kolumna zawiera błędnie zakodowane dane, błąd leży w sposobie wstawienia. Być może usunięcie wiodącego N ze stałych ciągów - N'string'mówi SQL Serverowi, aby wygenerował ciąg Unicode, ale zwykły 'string'oznacza, że ​​znaki używają kodowania klienta - wstawiłby współczesny hiszpański zamiast Unicode.

Jeśli kolumna zawiera poprawnie zakodowane dane, powiedziałbym, że znalazłeś błąd na ekranie GUI.

Jeśli nie możesz zmusić sqlcmd do poprawnego wstawienia danych (wiodące N lub nie), to chcesz złożyć skargę do Microsoft. Gdy to zrobisz, możliwość wyświetlenia bajtów zapisanych w kolumnie - użycie convert(colname as varbinary)- będzie miała kluczowe znaczenie dla wyjaśnienia, co się dzieje.

James K. Lowden
źródło
Cześć James, bardzo dziękuję za szczegółową odpowiedź. Zrobiłem kilka testów, a Sqlcmd.exe nie wyświetla prawidłowego ciągu. Oczywistym problemem jest sposób wstawiania danych.
Oskytar
Korzystając z Sql Profiler, debugowałem, jakie zdania zostały wysłane do SQL SERVER podczas korzystania z klienta GUI serwera SQl. INSERT INTO [ElementType] ([Code], [Name], [Description], [GeometryType], [stringId], [CapturedGeometryType]) WARTOŚCI („ESTACION”, „Estación”, „Estación”, „Multipoint”, NULL, 'Punkt'); działało FINE, więc wszystkie akcenty zostały poprawnie wstawione! To samo „wstaw zdanie”, które pojawia się w moim skrypcie SQL. Czy powinienem podać kod znakowy w pliku skryptu SQL?
Oskytar