Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];

Вниз

Не понятен принцып работы Stored Procedure.   Найти похожие ветки 

 
Lucky_elf   (2004-01-24 14:32) [0]

У меня вот такая хранимая процедура:

CREATE PROCEDURE INSERT_KREDIT(
PEOPLE_SERNAME VARCHAR(30),
PEOPLE_NAME VARCHAR(20),
PEOPLE_PNAME VARCHAR(30))
RETURNS (
PEOPLE_ID INTEGER)
AS
DECLARE VARIABLE P_ID INTEGER;

BEGIN
FOR SELECT P.ID_PEOPLE
FROM T_PEOPLE P
WHERE (:PEOPLE_NAME = P.NAME)
AND (:PEOPLE_SERNAME = P.SERNAME)
AND (:PEOPLE_PNAME = P.PNAME)
INTO :PEOPLE_ID
DO
BEGIN
IF (:PEOPLE_ID IS NOT NULL) THEN SUSPEND;
END
END !!


дальше в Д7 я вставляю DBGrid связываю все как в случае c IBQuery и не какого результата, хотя процедура выполняется и дает правельный результат, проверяю я это так


CD.IBStoredProc1.ParamByName("PEOPLE_SERNAME").AsString := "ИВАНОВ";
CD.IBStoredProc1.ParamByName("PEOPLE_NAME").AsString := "И";
CD.IBStoredProc1.ParamByName("PEOPLE_PNAME").AsString := "И";
CD.IBStoredProc1.Prepare;
CD.IBStoredProc1.ExecProc;
Edit1.Text := CD.IBStoredProc1.Params[0].AsString;


в поле Edit1 выдается правельный ID - что показывает правельность работы.

Интересует вопрос, если мне надо выбрать n записей я напишу хранимую процедуру, то как мне это все отобразить в DBGrid? и может ли вообще хранимая процедура делать такое?
Вообщем надо сделать хранимую процедуру работающую как запрос через IBQuery.

Заранее спасибо.


 
Digitman   (2004-01-24 14:41) [1]

если SP реализует селективный запрос, возвращающий ни одной, одну или более записей (suspend !) , то

IBStoredProc1. Open


 
kaif   (2004-01-24 14:48) [2]

Можно вообще использовать для этой цели IBQuery.
Записать в свойство SQL такой текст:
SELECT PEOPLE_ID
FROM INSERT_KREDIT(:PEOPLE_SERNAME, :PEOPLE_NAME,:PEOPLE_PNAME)
Дальше определить параметры через ParamByName и сделать Open;


 
Lucky_elf   (2004-01-24 15:38) [3]

2Kaif
Да вообщем-то я и сам знаю, что можно через IBQuery, но просто процедура будет делать вставку данных в несколько таблиц по определенному алгоритму, но я еще не дописал ее, и поскольку никогда еще не писал, то решил для начала попробывать а вообще будет-то работать это ХП.

2Digitman
Поясни про SUSPEND - когда и куда его вставлять?
т.е. если я знаю, что у меня ХП выбирет несколько кортежей, то надо Open использовать

А вообще мне надо написать ХП для фильтрации данных, т.е. будет одна форма и один DBGrid на ней и будет фильт которые будет отфильтровыать определенные записи, для этого я так подумал больше всего подойдет XP потому как один запрос для этого у меня не получился.


 
Digitman   (2004-01-24 15:55) [4]


> если я знаю, что у меня ХП выбирет несколько кортежей, то
> надо Open использовать


именно


> Поясни про SUSPEND - когда и куда его вставлять?


именно туда, куда ты и вставил его ... все верно ты сделал


 
Lucky_elf   (2004-01-24 16:29) [5]

Да но это было сделано метдом тыка, у меня нет ничего объясняющего как писать ХП, какие там разделы и принципы, я меня есть одна готовая ХП чужая, именно по ней я и пытаюсь разобраться как и что и поэтому мне мало что понятно.

Может знаешь ресурсы по ХП и желательно по IB

Мне вообще интресно, что можно использовать в написании ХП, т.е. можно ли использовать INSERT, DELETE, UPDATE и другие возможности SQL которые используются для написания запросов?

И что еще есть для работы с ХП

Спасибо за любые советы, хоть немного прояснили обстановку, в основу вроде бы въезжаю!


 
Desdechado   (2004-01-24 17:39) [6]

www.ibase.ru - на русском
а оригинальная документация по IB (и ХП тоже) на www.ibphoenix.com - на англ.


 
Desdechado   (2004-01-24 17:42) [7]

в ХП можно использовать все SQL-конструкции, кроме изменения метаданных
а еще есть встроенный хост-язык


 
Lucky_elf   (2004-01-24 20:35) [8]

Если я использую CD.IBStoredProc1.Open;
то вылетает ошибка :(


 
Lucky_elf   (2004-01-25 18:18) [9]

И все таки, для чего же нужен SUSPEND? это обязательная вещь, или он чисто в определенных случаях. Может кто объяснить где его ставить и ГЛАВНОЕ для ЧЕГО?


 
jack128   (2004-01-25 19:15) [10]


> И все таки, для чего же нужен SUSPEND? это обязательная
> вещь, или он чисто в определенных случаях. Может кто объяснить
> где его ставить и ГЛАВНОЕ для ЧЕГО?
suspend - команда, которая отправляет данные из прроцедуры на клиент. На этой команде выполнение процедуры прерывается до тех пор пока пользователь не сделает фетч.


 
Lucky_elf   (2004-01-25 19:46) [11]

Так проясняется! Уже лучше.
Значит, тогда следующее:
FOR SELECT ID_FILIAL
FROM T_FILIAL
WHERE :OSB = BASE_NUMBER AND :FILIAL = NUMBER
INTO :FIL_ID
DO
BEGIN
IF (:FIL_ID IS NULL) THEN
BEGIN
INSERT INTO T_FILIAL (BASE_NUMBER, NUMBER) VALUES (:OSB, :FILIAL);

SELECT ID_FILIAL
FROM T_FILIAL
WHERE :OSB = BASE_NUMBER AND :FILIAL = NUMBER
INTO :FIL_ID;
END

SUSPEND;
END


Как работает FOR - он сначала выбирает все записи удовлетворяющие условию, а затем передает управление на DO или после нахождения каждой записи удовлетворяющей условию упраление передается на DO?


 
kaif   (2004-01-26 01:14) [12]

FOR SELECT...INTO <переменные> позволяет сделать выборку, обойти набор данных в прямом порядке и при прохождении каждой строки набора что-то предпринять.


 
Lucky_elf   (2004-01-26 07:34) [13]


> FOR SELECT...INTO <переменные> позволяет сделать выборку,
> обойти набор данных в прямом порядке и при прохождении каждой
> строки набора что-то предпринять.

Жизнь с каждым днем становиться все лучше! Спасибочки огромное!

А как написать процедуру проверяющую наличие записи, если она существует, то вернуть ее ИД, если нет, то вставить и тоже вернтуть ИДентификатор.

Я написал так:
/* ИЩЕТ И ПРИ НАДОБНОСТИ ДОБАВЛЯЕТ ЧЕЛОВЕКА */
CREATE PROCEDURE FIND_ADD_PEOPLE(
PEOPLE_SERNAME VARCHAR(30),
PEOPLE_NAME VARCHAR(20),
PEOPLE_PNAME VARCHAR(30),
PEOPLE_BANKIR VARCHAR(1),
PEOPLE_INSAIDER VARCHAR(1))
RETURNS (P_ID INTEGER)
AS

BEGIN
SELECT ID_PEOPLE
FROM T_PEOPLE
WHERE (:PEOPLE_NAME = NAME)
AND (:PEOPLE_SERNAME = SERNAME)
AND (:PEOPLE_PNAME = PNAME)
INTO :P_ID;

IF (:P_ID IS NULL) THEN
BEGIN
INSERT INTO T_PEOPLE (SERNAME, NAME, PNAME, BANKER, INSAYDER)
VALUES (:PEOPLE_SERNAME, :PEOPLE_NAME, :PEOPLE_PNAME, :PEOPLE_BANKIR, :PEOPLE_INSAIDER);

/* ДОБАВИЛИ, ТОГДА НАЙДЕМ ЕГО ИДЕНТИФИКАТОР */
SELECT ID_PEOPLE
FROM T_PEOPLE
WHERE (:PEOPLE_NAME = NAME) AND (:PEOPLE_SERNAME = SERNAME) AND (:PEOPLE_PNAME = PNAME)
INTO :P_ID;
END
END !!


но не уверен в правельности кода.

Заранее спасибо. С уважением Lucky[ELF].


 
Deniz   (2004-01-26 08:03) [14]

В этом коде есть некоторые "узкие" места.
Если запрос:

SELECT ID_PEOPLE
FROM T_PEOPLE
WHERE (:PEOPLE_NAME = NAME)
AND (:PEOPLE_SERNAME = SERNAME)
AND (:PEOPLE_PNAME = PNAME)
INTO :P_ID;

вернет более 1 записи, то вызовется ошибка! Набор (NAME, SERNAME, PNAME) должен быть уникальным или же немного переработать код процедуры!
CREATE PROCEDURE FIND_ADD_PEOPLE(
PEOPLE_SERNAME VARCHAR(30),
PEOPLE_NAME VARCHAR(20),
PEOPLE_PNAME VARCHAR(30),
PEOPLE_BANKIR VARCHAR(1),
PEOPLE_INSAIDER VARCHAR(1))
RETURNS (P_ID INTEGER)
AS
BEGIN
FOR SELECT ID_PEOPLE
FROM T_PEOPLE
WHERE (:PEOPLE_NAME = NAME)
AND (:PEOPLE_SERNAME = SERNAME)
AND (:PEOPLE_PNAME = PNAME)
INTO :P_ID do suspend; /* вернет все идентификаторы */

IF (:P_ID IS NULL) THEN BEGIN
/* Если ID_PEOPLE заполняется генератором в триггере, то лучше сделать вызов генератора прямо здесь и отпадет необходимость дополнительного select */
P_ID = gen_id(GeneratorName, 1);
INSERT INTO T_PEOPLE (ID_PEOPLE, SERNAME, NAME, PNAME, BANKER, INSAYDER)
VALUES (:P_ID, :PEOPLE_SERNAME, :PEOPLE_NAME, :PEOPLE_PNAME, :PEOPLE_BANKIR, :PEOPLE_INSAIDER);
suspend; /* Возврат на клиента только что вставленного ID */
END
END !!
И в триггере должно быть прописано:
if (NEW.ID_PEOPLE IS NULL) then NEW.ID_PEOPLE = gen_id(GeneratorName, 1);
Тогда триггер будет заполнять значение только когда ID_PEOPLE пустое!


 
suric   (2004-01-26 13:45) [15]

Народ!
Скажите, пожалуйста, что означает оператор Suspend; на языке хранимых процедур INTERBASE как это сказывается на действии цикла FOR ? Например, как это показано ниже:

BEGIN
IF (:PEOPLE_ID IS NOT NULL) THEN SUSPEND;
END FOR SELECT P.ID_PEOPLE
FROM T_PEOPLE P
WHERE (:PEOPLE_NAME = P.NAME)
AND (:PEOPLE_SERNAME = P.SERNAME)
AND (:PEOPLE_PNAME = P.PNAME)
INTO :PEOPLE_ID
DO


 
Lucky_elf   (2004-01-26 18:57) [16]

Да действительно интересен тот факт
1. прекращается ли выполнение ХП на SUSPEND,
2. прекращается, но только, чтобы передать результат, после чего выполнение ХП продолжается,
3. Не прекращается вовсе

или есть 4-ый вариант


> Deniz © (26.01.04 08:03) [14]
> В этом коде есть некоторые "узкие" места.
> Если запрос:


ну а кроме этого, как на Ваш взгляд процедура работоспособна?
или нет?


 
kaif   (2004-01-27 03:49) [17]

2 Lucky_elf (26.01.04 18:57) [16]
Правильный ответ №2
прекращается, но только, чтобы передать результат, после чего выполнение ХП продолжается
Результат передается при каждом очередном Fetch.
Важно разобраться, что такое Fetch.


 
Lucky[ELF]   (2004-01-27 07:11) [18]

Блин, я теперь ваще запутался, SUSPEND или FETCH или в месте? если первое я хоть где-то в своем коде писал, то FETCH - его вообще нигде, как всю эту лабуду писать вместе?
Веточку пока кидать в орехи! Гы Гы Гы

ЗюЫю А может есть где нить нормальная статейка как писать ХП и как их вызывать из Дельфи.

Спаисбо, с уважением!


 
Deniz   (2004-01-27 07:42) [19]

Вообще сайт по IB и клоны http://www.ibase.ru там много интересного.
Ответ на вопрос: "А как написать процедуру проверяющую наличие записи, если она существует, то вернуть ее ИД, если нет, то вставить и тоже вернтуть ИДентификатор." уже получен. В приведенной процедуре Deniz © (26.01.04 08:03) [14], причем не получена информация по предположению "Набор (NAME, SERNAME, PNAME) должен быть уникальным", если это выполняется, то в результате выполнения процедуры будет возвращена только один идентификатор, но, как я понимаю (NAME, SERNAME, PNAME) это же ФИО, двойников может быть много, и соо-но процедура вернет все идентификаторы этих двойников!
Если немного прояснить работу suspend, то получится сл-щее:

for select ... from ... into ... do begin
...
end

просто перебор записей из селекта, между begin и end можно вставить любую обработку данных, в т.ч. insert/update/delete/select из других таблиц. Если нужно вернуть отработанные данные на клиента, то между begin и end нужно вставить suspend.


 
Lucky[ELF]   (2004-01-27 19:36) [20]

По поводу уникального набора, то двойники конечно могут буть, но я делаю импорт данных из отчета сделанного другой системой, а та возвращает ФИО в виде Иванов И.И. Петров П.П. etc, из чего следует, что двойников не может быть, кстати это и есть проблема, потому как в систему могут быть добавлены с клавиатуры (например кадровой службой) люди у которых будет полное ФИО, и тогда если импортировать данные, а это прийдется делать раз в месяц, то могут добавляться новые люди (Иванов И И - Иванов Иван Иванович), вот как раз может быть есть предложение как это исправить, я думал сделать сравнение по LIKE, но если будет такой вариант: в системе есть
Иванов Илья Иванович
Иванов Иван Иванович

и импортируестя Иванов И И, возникает большой косяк, прям и не знаю как это исправить.


> "А как написать процедуру проверяющую наличие записи, если
> она существует, то вернуть ее ИД, если нет, то вставить
> и тоже вернтуть ИДентификатор."


Это я с Вашей помощью уже написал, и оно даже вроде-бы работает :)

Спасибочки огромное.


 
Deniz   (2004-01-28 07:58) [21]

> Lucky[ELF] (27.01.04 19:36) [20]
> но я делаю импорт данных из отчета сделанного другой системой

Так может есть возможность "взять" данные не из отчета сделанного другой системой, а прямо из той БД?
Есть ли какое-то поле в отчете, сделанным другой системой, однозначно идентифицирующее конкретного человека?


 
Lucky[ELF]   (2004-01-28 19:58) [22]


> Так может есть возможность "взять" данные не из отчета сделанного
> другой системой, а прямо из той БД?
> Есть ли какое-то поле в отчете, сделанным другой системой,
> однозначно идентифицирующее конкретного человека?


Да, наверное так бы лучше и сделать, но я сотрудник ревизионной службы и у меня нет доступа к файла БД, где и как они храняться я только предполагаю (Unix сервер), копаться мне в них никто не даст - организация очень серьезная, там такого не прощают, но отчеты мне доступны, а все дело в том, что там есть масса отчетов, но блин все они не подходят для итогов, т.е. есть определенная форма установленная ИНСТРУКЦИЕЙ, моя задача каждый месяц пополнять эту форму, - на самом деле формы четыре, щас они ведутся в Excel"e, меня это страшно напрягает :(. Кроме того после пополнения некоторые из форм надо проверить с бумажными документами, после чего формировать ведомости и реестры, ну вообщем дело напряжное.
Из базы взять конечно хорошо бы, но на вид она старше чем я, ее клиенты работают на 386/486 и под DOS"ом.

Кроме всего этого подразумевается, что разработанная мною база (если разработаю) будет содержать массу другой полезной информации: план счетов - он огромный, отдел кадров - его сотрудники, должности, образования etc, хозяйственная часть ...

Если это все заработает, то самое плохое будет, то что использовать это легально нельзя, :(,

Вот такие пирожки с котятами ...


 
Deniz   (2004-01-29 09:23) [23]

Да уж, обрисовал ситуацию :)
Видать придется из отчетов брать :(
Повторю вопрос: "Есть ли какое-то поле в отчете, сделанным другой системой, однозначно идентифицирующее конкретного человека?"
Если нет, то тогда как человек визуально определяет hwo-is-hwo?
Например видит он в отчете следующее:
Иванов И. И. 01.01.2004 10000,00
Иванов И. И. 10.01.2004 20000,00
и где здесь Иванов Илья Иванович, а где Иванов Иван Иванович?


 
Lucky[ELF]   (2004-01-29 18:57) [24]


> Повторю вопрос: "Есть ли какое-то поле в отчете, сделанным
> другой системой, однозначно идентифицирующее конкретного
> человека?"

к сожалению такого поля нет :(, в отчете о человеке есть только ФИО с не полным именем и отчеством (Иванова И.И.)

В принцепе с другой стороны не все так плохо, раз уж во все системе будет все в одном виде (Иванов И.И.), то в принципе неразбирихи не будет, к тому же ФИО в этой системе не главное, в остовном все отчеты строятся на основании "составного уникального идентификатора (счет)", а ФИО только для справки, ну и еще для некоторых вещей :)

А вообще я и сам не знаю, что из этого получиться, но есть один огромный плюс - может хоть с IB разберусь и в базах навыки повышу.


 
Deniz   (2004-01-30 07:14) [25]

Вот потихоньку процесс идет.
"составного уникального идентификатора (счет)" что это?
И, кстати, можешь привести пример этого отчета? Строк 5-10.


 
Lucky[ELF]   (2004-01-30 19:20) [26]


> Вот потихоньку процесс идет.
> "составного уникального идентификатора (счет)" что это?
> И, кстати, можешь привести пример этого отчета? Строк 5-10.


Да процесс идет, медленно, но идет :), и это радует.


------T--------------------T-------------------------------------------------T-------------------------T---------------- T------T-----------T----------T-------------T--------------T--------------------¬
¦ N ¦ ФИО XXXXXXXX ¦ XXXXXXX XXXXXXXXXX XXXXXXXX ¦ X XXXXXXXX XXXXX ¦ XXXX XXXXXX ¦XX XX.¦XXXX XXXXX.¦ XXX-XX ¦ Подпись ¦ XXXXX ¦ XXXXXXXXXX ¦
¦ п/п ¦ XXXXXX +----------T----------T----------------T----------+ XXXXXX, XXXX X ¦ XXXXX XXXXX ¦XX XXX¦XX XXXXXXXX¦ XXXXXXX. ¦ ¦ XXXXXXXXXXX ¦ ¦
¦ ¦ ¦ Дата ¦XXXX (XXX)¦ Сумма XXXXXXX ¦ XXXXXXX ¦ XXXXX XXXXXXXX ¦ XXXXX ¦XX XXX¦XX XXXXXXX.¦XXXX XXXX.¦ ¦ ¦ ¦
¦ ¦ ¦ X XXXXXX.¦ X XXXXXX ¦ XXXXX XXXXXXX. ¦ XXXXXXXX ¦ ¦ ¦ ¦ ¦ XXXXXXX. ¦ ¦ ¦ ¦
+-----+--------------------+----------+----------+----------------+----------+-------------------------+---------------- +------+-----------+----------+-------------+--------------+--------------------+
¦ 1¦XXXXXXXXXXXX X.X. ¦26.11.2003¦ 60 ¦ 30,000.00¦ ¦***** *** * **** ** *****¦ 04.12.2003¦ 19.0 ¦ 03.12.2008¦ 0 ¦ ¦ 2 XXX ¦XXXXXXX X.X. ¦
¦ ¦ ¦112 ¦ 19.0 ¦ 2 XXX ¦ ¦***** 04.12.2003 ****¦ 30,000.00¦ 19.0 ¦ 03.12.2008¦ ¦ ¦ ¦XXXXXXXXXXX X.X. ¦
+-----+--------------------+----------+----------+----------------+----------+-------------------------+---------------- +------+-----------+----------+-------------+--------------+--------------------+
¦ 2¦XXXXXXX X.X. ¦26.11.2003¦ 60 ¦ 100,000.00¦ ¦***** *** * **** ** *****¦ 03.12.2003¦ 19.0 ¦ 02.12.2008¦ 0 ¦ ¦ 2 XXX ¦XXXXXXXXXX X.X. ¦
¦ ¦ ¦112 ¦ 19.0 ¦ 2 XXX ¦ ¦***** 03.12.2003 ****¦ 100,000.00¦ 19.0 ¦ 02.12.2008¦ ¦ ¦ ¦XXXXXX X.X. ¦
+-----+--------------------+----------+----------+----------------+----------+-------------------------+---------------- +------+-----------+----------+-------------+--------------+--------------------+
¦ 3¦XXXXXXXXX X.X. ¦26.11.2003¦ 60 ¦ 80,000.00¦ ¦***** *** * **** ** *****¦ 03.12.2003¦ 19.0 ¦ 02.12.2008¦ 0 ¦ ¦ 2 XXX ¦XXXXXXXXX X.X. ¦
¦ ¦ ¦112 ¦ 19.0 ¦ 2 XXX ¦ ¦***** 03.12.2003 ****¦ 80,000.00¦ 19.0 ¦ 02.12.2008¦ ¦ ¦ ¦XXXXXXXXXX X.X. ¦
+-----+--------------------+----------+----------+----------------+----------+-------------------------+---------------- +------+-----------+----------+-------------+--------------+--------------------+
¦ 4¦XXXXXXXX X.X. ¦03.12.2003¦ 60 ¦ 62,000.00¦ ¦***** *** * **** ** *****¦ 03.12.2003¦ 19.0 ¦ 02.12.2008¦ 0 ¦ ¦ 2 XXX ¦XXXXXXXXXX X.X. ¦
¦ ¦ ¦113 ¦ 19.0 ¦ 2 XXX ¦ ¦***** 03.12.2003 ****¦ 62,000.00¦ 19.0 ¦ 02.12.2008¦ ¦ ¦ ¦XXXXXXXXXX X.X. ¦
+-----+--------------------+----------+----------+----------------+----------+-------------------------+---------------- +------+-----------+----------+-------------+--------------+--------------------+
¦ 5¦XXXXXXXXXX X.X. ¦26.11.2003¦ 60 ¦ 20,000.00¦ ¦***** *** * **** ** *****¦ 03.12.2003¦ 19.0 ¦ 02.12.2008¦ 0 ¦ ¦ 2 XXX ¦XXXXXXXXXX X.X. ¦
¦ ¦ ¦20000 ¦ 19.0 ¦ 2 XXX ¦ ¦***** 03.12.2003 ****¦ 20,000.00¦ 19.0 ¦ 02.12.2008¦ ¦ ¦ ¦XXXXX X.X. ¦
+-----+--------------------+----------+----------+----------------+----------+-------------------------+---------------- +------+-----------+----------+-------------+--------------+--------------------+


По определенным причинам мне пришлось заменить содержащуюся инфу на ХХХ и числа я заменил на ***, - извините :(, но это не потому, что мне жалко этого отчета, а потому, что НЕЛЬЗЯ этого показывать, мало что. Так что извиняйте, но понять, на что похож отчет можно.

Уникальный ИД он такой: ***** *** * **** ** *****, всмысле формата, пробелы можно убрать.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2004.02.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.032 c
14-80180
Solom
2004-01-31 20:22
2004.02.25
компилятор не видит TTabStrings


3-79564
Санек
2004-01-29 16:46
2004.02.25
Научить TAB ходить по гриду


7-80334
DDS
2003-12-08 00:02
2004.02.25
Как отловить нажатие средней клавиши мыша?


7-80316
SlyFox
2003-12-05 08:17
2004.02.25
Запись CD (нужна VCL)!!!


3-79621
Newb
2004-02-01 00:46
2004.02.25
DBGrid как изменить значение ячейки при изменении другой





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский