Rozwiązywanie problemów z błędem „Nielegalna mieszanka zestawień” w mysql


210

Podczas próby wykonania procedury wyboru w procedurze przechowywanej w MySQL pojawia się następujący błąd.

Nielegalna kombinacja zestawień (latin1_general_cs, IMPLICIT) i (latin1_general_ci, IMPLICIT) dla operacji „=”

Masz pojęcie, co może tu pójść nie tak?

Zestawienie tabeli to latin1_general_cii kolumny w klauzuli where latin1_general_cs.


2
Używam różnych baz danych przez długi czas (od 1990), a użycie sortowania i koercji przez NySQL wydaje się być „szalone”, bazy danych rozwiązują problemy narzucające „JEDEN” zestaw znaków dla bazy danych, a następnie procedury importu / eksportu w celu konwersji z / do unikalnego zestawu znaków wykorzystywanego przez bazę danych. Wybrane przez Mysql rozwiązania są niepokojące, ponieważ łączą „problemy z aplikacją” (konwersja zestawu znaków) z problemem z bazą danych (użycie sortowania). Dlaczego nie „usunąć” tych głupich i uciążliwych funkcji z bazy danych, aby stała się o wiele bardziej użyteczna i kontrolowana przez
Maurizio Pievaioli

Odpowiedzi:


216

Jest to na ogół spowodowane porównywaniem dwóch ciągów niezgodnego zestawiania lub próbą wybrania danych z różnych zestawień do połączonej kolumny.

Klauzula COLLATEpozwala określić sortowanie użyte w zapytaniu.

Na przykład poniższa WHEREklauzula zawsze podaje opublikowany błąd:

WHERE 'A' COLLATE latin1_general_ci = 'A' COLLATE latin1_general_cs

Rozwiązaniem jest określenie wspólnego sortowania dla dwóch kolumn w zapytaniu. Oto przykład, który używa COLLATEklauzuli:

SELECT * FROM table ORDER BY key COLLATE latin1_general_ci;

Inną opcją jest użycie BINARYoperatora:

BINARY str jest skrótem dla CAST (str AS BINARY).

Twoje rozwiązanie może wyglądać mniej więcej tak:

SELECT * FROM table WHERE BINARY a = BINARY b;

lub,

SELECT * FROM table ORDER BY BINARY a;

2
Dzięki. W moim przypadku wydaje się to dziwne. Kiedy uruchamiam zapytanie w obecnej formie, przeglądarka zapytań pobiera wyniki. Ale użycie procedury składowanej powoduje błąd.
user355562,

5
Binary wydawało mi się najlepszym rozwiązaniem. Może być również najlepszy dla Ciebie, jeśli nie używasz żadnych podchwytliwych filtrów.
Adam F

Mam ten sam problem - sposób, w jaki rozwiązuję ten problem, jest od samego początku odtwarzany. Próbowałem zmienić sortowanie, ale kiedy dołączam, nadal pojawia się błąd, więc spróbowałem w ten sposób. cmiiw
Bobby Z

Pamiętaj, że w MariaDB występuje błąd, COLLATE latin1_general_ci który powoduje kolejny błąd: COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1''- nawet jeśli nie masz kolumny z ZNAKIEM ZESTAWU „latin1”! Rozwiązaniem jest użycie obsady BINARY. Zobacz także to pytanie
Mel_T

154

TL; DR

Zmień ułożenie jednego (lub obu) ciągów, aby pasowały do ​​siebie, albo dodaj COLLATEklauzulę do wyrażenia.


  1. Co to w ogóle jest to „zestawienie”?

    Jak udokumentowano w Ogólnych zestawach znaków i zestawieniach :

    Zestaw znaków to zestaw symboli i kodowań. Sortowania jest zbiorem reguł porównywania znaków w zestawie znaków. Wyjaśnijmy to rozróżnienie na przykładzie fikcyjnego zestawu znaków.

    Załóżmy, że mamy alfabet z czterema literami: „ A”, „ B”, „ a”, „ b”. Każdej literze nadajemy liczbę: „ A” = 0, „ B” = 1, „ a” = 2, „ b” = 3. Litera „ A” jest symbolem, cyfra 0 oznacza kodowanieA” oraz kombinację wszystkich cztery litery i ich kodowanie to zestaw znaków .

    Załóżmy, że chcemy porównać dwie wartości ciągów „ A” i „ B”. Najprostszym sposobem na to jest sprawdzenie kodowania: 0 dla „ A” i 1 dla „ B”. Ponieważ 0 jest mniejsze niż 1, mówimy, że „ A” jest mniejsze niż „ B”. Właśnie zastosowaliśmy zestawienie do naszego zestawu znaków. Zestawienie to zestaw reguł (w tym przypadku tylko jedna reguła): „porównaj kodowanie”. To najprostsze ze wszystkich możliwych zestawień nazywamy zestawieniem binarnym .

    Ale co, jeśli chcemy powiedzieć, że małe i wielkie litery są równoważne? Wtedy mielibyśmy co najmniej dwie reguły: (1) traktuj małe litery „ a” i „ b” jako równoważne z „ A” i „ B”; (2), a następnie porównaj kodowania. Nazywamy to sortowaniem bez rozróżniania wielkości liter . Jest to trochę bardziej skomplikowane niż sortowanie binarne.

    W prawdziwym życiu większość zestawów znaków ma wiele znaków: nie tylko „ A” i „ B”, ale całe alfabety, czasem wiele alfabetów lub wschodni system pisma z tysiącami znaków, a także wiele specjalnych symboli i znaków interpunkcyjnych. Również w prawdziwym życiu większość zestawień ma wiele zasad, nie tylko dotyczących rozróżniania liter, ale także rozróżniania akcentów („akcent” jest znakiem dołączonym do znaku jak w niemieckim „ Ö”), a także dla wielu znaków odwzorowania (takie jak reguła, że ​​„ Ö” = „ OE” w jednym z dwóch niemieckich zestawień).

    Dalsze przykłady podano w części Przykłady efektu zestawienia .

  2. Okej, ale w jaki sposób MySQL decyduje, którego sortowania użyć dla danego wyrażenia?

    Jak udokumentowano w Collation of Expressions :

    W zdecydowanej większości instrukcji oczywiste jest, jakiego sortowania używa MySQL do rozwiązania operacji porównania. Na przykład w następujących przypadkach powinno być jasne, że zestawienie jest zestawieniem kolumny charset_name:

    SELECT x FROM T ORDER BY x;
    SELECT x FROM T WHERE x = x;
    SELECT DISTINCT x FROM T;

    Jednak w przypadku wielu operandów może wystąpić niejednoznaczność. Na przykład:

    SELECT x FROM T WHERE x = 'Y';

    Czy porównanie powinno wykorzystywać układanie kolumny x, czy dosłownego ciągu 'Y'? Oba xi 'Y'mają zestawienia, więc które zestawienie ma pierwszeństwo?

    Standardowy SQL rozwiązuje takie pytania, stosując zasady zwane „koercją”.

    [ deletia ]

    MySQL używa wartości koercji z następującymi regułami, aby rozwiązać niejednoznaczności:

    • Użyj porównania z najniższą wartością koercji.

    • Jeśli obie strony mają ten sam przymus, wówczas:

      • Jeśli obie strony są Unicode lub obie strony nie są Unicode, oznacza to błąd.

      • Jeśli jedna ze stron ma zestaw znaków Unicode, a druga strona ma zestaw znaków inny niż Unicode, strona z zestawem znaków Unicode wygrywa, a po stronie innej niż Unicode jest stosowana automatyczna konwersja zestawu znaków. Na przykład poniższa instrukcja nie zwraca błędu:

        SELECT CONCAT(utf8_column, latin1_column) FROM t1;

        Zwraca wynik, który ma zestaw znaków utf8i takie samo zestawienie jak utf8_column. Wartości latin1_columnsą automatycznie konwertowane na utf8przed konkatenacją.

      • W przypadku pracy z argumentów z tego samego zestawu znaków, ale to mix _binsortowania a _cilub _cssortowania The _binsłuży zestawień. Jest to podobne do tego, w jaki sposób operacje mieszające ciągi binarne i binarne oceniają operandy jako ciągi binarne, z tym wyjątkiem, że dotyczą one zestawień, a nie typów danych.

  3. Czym więc jest „nielegalna mieszanka zestawień”?

    „Nielegalna mieszanka zestawień” występuje, gdy wyrażenie porównuje dwa ciągi różnych zestawień, ale o jednakowym przymusie, a reguły przymusu nie mogą pomóc w rozwiązaniu konfliktu. Jest to sytuacja opisana pod trzecim punktem w powyższym cytacie.

    Konkretny błąd podany w pytaniu Illegal mix of collations (latin1_general_cs,IMPLICIT) and (latin1_general_ci,IMPLICIT) for operation '='mówi nam, że istniało porównanie równości między dwoma ciągami znaków innej niż Unicode o jednakowej koercyjności. Co więcej, mówi nam, że zestawienia nie zostały podane wprost w instrukcji, ale raczej sugerowane ze źródeł ciągów (takich jak metadane kolumny).

  4. To wszystko bardzo dobrze, ale jak rozwiązać takie błędy?

    Jak sugerują cytowane powyżej fragmenty ręczne, problem ten można rozwiązać na wiele sposobów, z których dwa są rozsądne i zalecane:

    • Zmień zestawienie jednego (lub obu) ciągów, aby pasowały do ​​siebie i nie było już żadnych dwuznaczności.

      To, jak można to zrobić, zależy od tego, skąd przyszedł ciąg: Wyrażenia dosłowne przyjmują sortowanie określone w collation_connectionzmiennej systemowej; wartości z tabel pobierają sortowanie określone w ich metadanych kolumnowych.

    • Wymuś, aby jeden łańcuch nie był przymusowy.

      Pominąłem następujący cytat z powyższego:

      MySQL przypisuje wartości koercji w następujący sposób:

      • Wyraźna COLLATEklauzula ma koercję równą 0. (W ogóle nie można go przymusić).

      • Łączenie dwóch łańcuchów z różnymi zestawieniami ma koercję 1.

      • Zestawienie kolumny lub zapisanego rutynowego parametru lub zmiennej lokalnej ma koercyjność 2.

      • „Stała systemowa” (ciąg zwracany przez funkcje takie jak USER()lub VERSION()) ma koercyjność 3.

      • Ułożenie literału ma koercję 4.

      • NULLlub wyrażenie, które pochodzi od NULLma koercyjność 5.

      Zatem zwykłe dodanie COLLATEklauzuli do jednego z ciągów użytych w porównaniu wymusi użycie tego zestawienia.

    Podczas gdy inni byliby strasznie złą praktyką, gdyby zostali rozmieszczeni tylko w celu rozwiązania tego błędu:

    • Zmuś jeden (lub oba) ciągi, aby miały jakąś inną wartość koercyjności, aby mieć pierwszeństwo.

      Zastosowanie CONCAT()lub CONCAT_WS()spowoduje łańcuch znaków o koercyjności 1; oraz (jeśli w przechowywanej procedurze) użycie parametrów / zmiennych lokalnych spowodowałoby łańcuchy o koercyjności 2.

    • Zmień kodowanie jednego (lub obu) ciągów, aby jeden był Unicode, a drugi nie.

      Można to zrobić poprzez transkodowanie za pomocą ; lub poprzez zmianę podstawowego zestawu znaków danych (np. modyfikację kolumny, zmianę wartości literalnych lub wysłanie ich od klienta w innym kodowaniu i zmianę / dodanie wprowadzającego zestawu znaków). Pamiętaj, że zmiana kodowania spowoduje inne problemy, jeśli niektórych pożądanych znaków nie będzie można zakodować w nowym zestawie znaków.CONVERT(expr USING transcoding_name)character_set_connectioncharacter_set_client

    • Zmień kodowanie jednego (lub obu) ciągów, tak aby były one takie same i zmień jeden ciąg, aby użyć odpowiedniego _binzestawienia.

      Metody zmiany kodowania i zestawień zostały wyszczególnione powyżej. Takie podejście byłoby mało przydatne, gdyby rzeczywiście trzeba było zastosować bardziej zaawansowane reguły zestawiania, niż te oferowane przez _binzestawienie.


4
Zauważ, że „niedozwolona mieszanka zestawień” może również powstać, gdy nie ma dwuznaczności, co do zastosowania zestawienia, ale ciąg, który ma zostać wymuszony, musi zostać transkodowany do kodowania, w którym niektóre jego znaki nie mogą być reprezentowane. Omówiłem tę sprawę w poprzedniej odpowiedzi .
eggyal

5
Świetna odpowiedź. Ten powinien być wyżej, ponieważ zagłębia się w to, co programiści powinni naprawdę wiedzieć; nie tylko jak to naprawić, ale naprawdę rozumiem, dlaczego rzeczy dzieją się tak, jak są;
zaznacz

Dzięki stary, nauczyłeś mnie dzisiaj czegoś.
briankip

66

Dodanie mojego 2c do dyskusji dla przyszłych pracowników Google.

Badałem podobny problem, w którym podczas używania funkcji niestandardowych, które otrzymały parametr varchar, wystąpił następujący błąd :

Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and 
(utf8_general_ci,IMPLICIT) for operation '='

Za pomocą następującego zapytania:

mysql> show variables like "collation_database";
    +--------------------+-----------------+
    | Variable_name      | Value           |
    +--------------------+-----------------+
    | collation_database | utf8_general_ci |
    +--------------------+-----------------+

Byłem w stanie powiedzieć, że DB używa utf8_general_ci , podczas gdy tabele zostały zdefiniowane za pomocą utf8_unicode_ci :

mysql> show table status;
    +--------------+-----------------+
    | Name         | Collation       |
    +--------------+-----------------+
    | my_view      | NULL            |
    | my_table     | utf8_unicode_ci |
    ...

Zauważ, że widoki mają sortowanie NULL . Wygląda na to, że widoki i funkcje mają definicje sortowania, nawet jeśli to zapytanie pokazuje wartość null dla jednego widoku. Stosowane sortowanie to sortowanie DB, które zostało zdefiniowane podczas tworzenia widoku / funkcji.

Smutnym rozwiązaniem było zarówno zmiana sortowania db, jak i odtworzenie widoków / funkcji, aby zmusić je do użycia bieżącego sortowania.

  • Zmiana sortowania bazy danych:

    ALTER DATABASE mydb DEFAULT COLLATE utf8_unicode_ci;
  • Zmiana sortowania tabeli:

    ALTER TABLE mydb CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Mam nadzieję, że to komuś pomoże.


12
Sortowanie można również ustawić na poziomie kolumny. Możesz to zobaczyć za pomocą:show full columns from my_table;
Jonathan Tran

Dziękuję Ci. Właśnie upuściłem schemat i odtworzyłem go z poprawnym domyślnym zestawieniem, a wszystko zaimportowałem ponownie.
JRun

1
@JonathanTran Dziękujemy! Miałem zestaw znaków i zestawianie na wszystkich tabelach, bazie danych i połączeniu, ale nadal występował błąd! Zestawienie nie zostało ustawione na kolumnie! Naprawiłem to za pomocąalter table <TABLE> modify column <COL> varchar(255) collate utf8_general_ci;
Chloe

2
Sidenote dla przyszłych pracowników Google: nawet jeśli baza danych, tabele i pola mają takie same zestawienie, musisz również upewnić się, że twoje połączenie używa tego samego zestawienia. Wszystko ma »utf8mb4_unicode_ci«, ale SHOW session variables like '%collation%';mówi ci, że »collation_connection« to »utf8mb4_general_ci«? Następnie biegnij SET collation_connection = utf8mb4_unicode_ciwcześniej.
pixelbrackets

Dziękuję Ci! Zajęło mi to trochę, aby to wyśledzić. Tabele muszą być nie tylko tym samym zestawieniem, ale DB również!
moto

15

Czasami konwertowanie zestawów znaków może być niebezpieczne, szczególnie w bazach danych z dużą ilością danych. Myślę, że najlepszą opcją jest użycie operatora „binarnego”:

e.g : WHERE binary table1.column1 = binary table2.column1

10

Miałem podobny problem, próbowałem użyć procedury FIND_IN_SET ze zmienną łańcuchową .

SET @my_var = 'string1,string2';
SELECT * from my_table WHERE FIND_IN_SET(column_name,@my_var);

i otrzymywał błąd

Kod błędu: 1267. Nielegalna mieszanka zestawień (utf8_unicode_ci, IMPLICIT) i (utf8_general_ci, IMPLICIT) dla operacji „find_in_set”

Krótka odpowiedź:

Nie trzeba zmieniać żadnych zmiennych collation_YYYY, wystarczy dodać poprawne sortowanie obok deklaracji zmiennych , tj

SET @my_var = 'string1,string2' COLLATE utf8_unicode_ci;
SELECT * from my_table WHERE FIND_IN_SET(column_name,@my_var);

Długa odpowiedź:

Najpierw sprawdziłem zmienne sortowania:

mysql> SHOW VARIABLES LIKE 'collation%';
    +----------------------+-----------------+
    | Variable_name        | Value           |
    +----------------------+-----------------+
    | collation_connection | utf8_general_ci |
    +----------------------+-----------------+
    | collation_database   | utf8_general_ci |
    +----------------------+-----------------+
    | collation_server     | utf8_general_ci |
    +----------------------+-----------------+

Następnie sprawdziłem zestawienie tabel:

mysql> SHOW CREATE TABLE my_table;

CREATE TABLE `my_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `column_name` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=125 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Oznacza to, że moja zmienna została skonfigurowana z domyślnym zestawieniem utf8_general_ci, podczas gdy moja tabela została skonfigurowana jako utf8_unicode_ci .

Dodając polecenie COLLATE obok deklaracji zmiennej, sortowanie zmiennych pasowało do sortowania skonfigurowanego dla tabeli.



2

Rozwiązanie w przypadku literałów.

Korzystam z integracji danych Pentaho i nie mogę określić składni sql. Użycie bardzo prostego wyszukiwania DB dało błąd „Nielegalna mieszanka zestawień (cp850_general_ci, COERCIBLE) i (latin1_swedish_ci, COERCIBLE) dla operacji„ = ”„

Wygenerowany kod to „WYBIERZ DATA_DATA JAKO najnowsza_DATA_DATA OD hr_cc_normalised_data_date_v GDZIE PSEUDO_KEY =?”

Krótko mówiąc, przegląd był do widoku i kiedy wydałem

mysql> show full columns from hr_cc_normalised_data_date_v;
+------------+------------+-------------------+------+-----+
| Field      | Type       | Collation         | Null | Key |
+------------+------------+-------------------+------+-----+
| PSEUDO_KEY | varchar(1) | cp850_general_ci  | NO   |     |
| DATA_DATE  | varchar(8) | latin1_general_cs | YES  |     |
+------------+------------+-------------------+------+-----+

co wyjaśnia, skąd pochodzi „cp850_general_ci”.

Widok został po prostu utworzony za pomocą „SELECT” X ”, ......” Według literałów takich jak ten powinien dziedziczyć ich zestaw znaków i zestawienie z ustawień serwera, które zostały poprawnie zdefiniowane jako „latin1” i „latin1_general_cs”, ponieważ najwyraźniej tak się nie stało. Wymusiłem to w tworzeniu widoku

CREATE OR REPLACE VIEW hr_cc_normalised_data_date_v AS
SELECT convert('X' using latin1) COLLATE latin1_general_cs        AS PSEUDO_KEY
    ,  DATA_DATE
FROM HR_COSTCENTRE_NORMALISED_mV
LIMIT 1;

teraz pokazuje latin1_general_cs dla obu kolumn i błąd zniknął. :)


1

MySQL naprawdę nie lubi miksowania zestawień, chyba że może zmusić je do tego samego (co oczywiście nie jest możliwe w twoim przypadku). Czy nie można po prostu zmusić do użycia tego samego zestawienia za pomocą klauzuli COLLATE ? (lub prostszy BINARYskrót, jeśli dotyczy ...).


Czy jest to unikalne dla MySQL? Jak inne systemy radzą sobie z mieszaniem niekompatybilnych zestawień o pozornie równym priorytecie?
eggyal

Twój link jest nieprawidłowy.
Benubird,

1

Jeśli kolumny, z którymi masz problem, to „skróty”, rozważ następujące kwestie ...

Jeśli „skrót” jest łańcuchem binarnym, naprawdę powinieneś użyć BINARY(...)typu danych.

Jeśli „skrót” jest łańcuchem szesnastkowym, nie potrzebujesz utf8 i powinieneś tego unikać ze względu na sprawdzanie znaków itp. Na przykład, MySQL MD5(...)daje 32-bajtowy ciąg znaków o stałej długości. SHA1(...)daje 40-bajtowy ciąg szesnastkowy. Można to zapisać wCHAR(32) CHARACTER SET ascii (lub 40 dla sha1).

Lub jeszcze lepiej zapisz się UNHEX(MD5(...))w BINARY(16). To zmniejsza o połowę rozmiar kolumny. (Sprawia to jednak, że raczej nie można go wydrukować.) SELECT HEX(hash) ...Jeśli chcesz, aby był czytelny.

Porównanie dwóch BINARYkolumn nie ma problemów z sortowaniem.


1

Bardzo interesujące ... Przygotuj się. Spojrzałem na wszystkie rozwiązania „dodaj zestawienie” i dla mnie są to poprawki pomocy zespołu. W rzeczywistości projekt bazy danych był „zły”. Tak, dodaje się standardowe zmiany i nowe rzeczy, bla bla, ale to nie zmienia faktu, że projekt bazy danych jest zły. Odmawiam pójścia drogą dodawania „sortowania” do wszystkich instrukcji SQL, aby moje zapytanie działało. Jedynym rozwiązaniem, które działa dla mnie i praktycznie wyeliminuje potrzebę poprawiania mojego kodu w przyszłości, jest przeprojektowanie bazy danych / tabel, tak aby pasowały do ​​zestawu znaków, z którym będę żył i który obejmę na dłuższą metę. W takim przypadku wybieram zestaw znaków „ utf8mb4 ”.

Tak więc rozwiązaniem tutaj, gdy pojawia się ten „nielegalny” komunikat o błędzie, jest przeprojektowanie bazy danych i tabel. To jest o wiele łatwiejsze i szybsze niż się wydaje. Eksportowanie danych i ponowne importowanie ich z pliku CSV może nawet nie być wymagane. Zmień zestaw znaków w bazie danych i upewnij się, że wszystkie zestawy znaków w tabelach są zgodne.

Użyj tych poleceń, aby poprowadzić Cię:

SHOW VARIABLES LIKE "collation_database";
SHOW TABLE STATUS;

Teraz, jeśli lubisz dodawać „zestawiać” tu i tam i wzbogacać swój kod o siły, które wypełniają „nadpisania”, zgadnij.



0

Kolejnym źródłem problemu z zestawieniami jest mysql.proctabela. Sprawdź zestawienia procedur i funkcji przechowywania:

SELECT
  p.db, p.db_collation, p.type, COUNT(*) cnt
FROM mysql.proc p
GROUP BY p.db, p.db_collation, p.type;

Zwróć także uwagę na kolumny mysql.proc.collation_connectioni mysql.proc.character_set_client.



-1

użyłem ALTER DATABASE mydb DEFAULT COLLATE utf8_unicode_ci; , ale nie działałem.

W tym zapytaniu:

Select * from table1, table2 where table1.field = date_format(table2.field,'%H');

Ta praca dla mnie:

Select * from table1, table2 where concat(table1.field) = date_format(table2.field,'%H');

Tak, tylko concat.


Sprawdź zestawienie swoich tabel i ich kolumn (pokaż status tabeli; i pokaż pełne kolumny z tabeli1;). Korzystanie z alter database nie działałoby, jeśli tabele zostały już utworzone z niewłaściwym zestawieniem.
Ariel T

ALTER DATABASE mydb DEFAULT COLLATE ... działało dla mnie, więc głosujcie. Może miałem przewagę, ponieważ mogłem upuścić i ponownie utworzyć bazę danych i załadować z kopii zapasowych.
tobixen

-2

Ten kod musi być umieszczony wewnątrz Uruchom zapytanie / zapytania SQL w bazie danych

OKNO SQL QUERY

ALTER TABLE `table_name` CHANGE `column_name` `column_name`   VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL;

Zastąp nazwę tabeli i nazwę kolumny odpowiednią nazwą.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.