Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Новый топик    Ответить
 ODBC и Русский язык  [new]
Adylov Timur
Member

Откуда:
Сообщений: 223
Из PHP через ODBC я выполняю запрос, но запрос содержит русское слово, и запрос не выполняется. Возникают 2 вопроса:
1) Как решить эту проблему
2) Почему он не работает (правда у меня есть мнение, но хотелось бы правильного ответа)

Да пример запроса
select * from mydictianary where rusname 'запрос'

Сообщение было отредактировано: 13 окт 12, 17:16
13 окт 12, 15:48    [13313387]     Ответить | Цитировать Сообщить модератору
 Re: ODBC и Русский язык  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3124
Блог
Adylov Timur,

8-бит или Unicode?
13 окт 12, 17:15    [13313606]     Ответить | Цитировать Сообщить модератору
 Re: ODBC и Русский язык  [new]
Adylov Timur
Member

Откуда:
Сообщений: 223
servit,

Unicode
13 окт 12, 18:22    [13313724]     Ответить | Цитировать Сообщить модератору
 Re: ODBC и Русский язык  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3124
Блог
Adylov Timur,

1) проверьте, включено ли в настройках ODBC Unicode SQLTypes
2) проверьте, в той ли кодировке передаёте значение параметра

Сделал небольшой тест ($zv=Cache for Windows (x86-64) 2012.2 (Build 638U)):

1) в области "SAMPLES" в таблицу Sample.Company добавил новую строку

MissionName
Миссия выполнена!Caché+запрос+bună ziua

2) написал программу на VBScript
adVarWChar=202
adParamInput=1
adCmdText=1

strParam="Cach" & ChrW(233) & "+запрос+bun" & ChrW(259) & " ziua"

Set cn=Createobject("ADODB.Connection")

cn.ConnectionString="DRIVER={InterSystems ODBC35}; SERVER=127.0.0.1; PORT=1972; DATABASE=SAMPLES; UID=_system; PWD=SYS; Unicode SQLTypes=1;"
'или так
'cn.ConnectionString="DSN=CACHE Samples;UID=_system; PWD=SYS;"

cn.open

Set cmd=Createobject("ADODB.Command") 

with cmd
  .ActiveConnection = cn
  .CommandType = adCmdText
  .CommandText = "select Mission from Sample.Company where Name=?"

  .Parameters.Append .CreateParameter("p1", adVarWChar, adParamInput, 50, strParam)
end with


Set rs = cmd.Execute

'А можно и без параметра, но лучше так не делать
'Set rs = cn.execute("select Mission from Sample.Company where Name='"&strParam&"'")

if not rs.EOF then
  WScript.Echo rs.Fields("Mission")
End if

cn.Close

Запуск программы:
wscript.exe test.vbs

Результат:
Миссия выполнена!


Сообщение было отредактировано: 13 окт 12, 22:36
13 окт 12, 22:35    [13314643]     Ответить | Цитировать Сообщить модератору
 Re: ODBC и Русский язык  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1574
Несколько лет назад пришлось помогать коллегам с подобной проблемой. Заметки остались, привожу выжимку. В наших условиях php был под Linux'ом. Заранее предупреждаю - я не php-шник, да и подробностей за давностью уже не помню, так что вопросов постарайтесь не задавать :)

Установка локали CP1251

Надо сказать, что результирующий набор, возвращаемый Cache ODBC, всегда в кодировке CP1251 (вне зависимости от 8-битности экземпляра Cache). По крайней мере, я не знаю как это изменить (да и надо ли?). Поэтому надо установить в Linux соответствующую локаль. Например, в Ubuntu 9.10 это делается так:

sudo locale-gen ru_RU.CP1251

locale -a | grep 1251

в списке локалей появятся:

ru_RU.cp1251

В RedHat-подобных дистрибутивах (проверено в FC 8, CentOS 5.x) локаль устанавливается так:

sudo localedef --no-archive -c -f CP1251 -i ru_RU ru_RU.CP1251

Проверка наличия ru_RU.cp1251 выполняется аналогично:

locale -a | grep 1251
...

Тестирование в php
...
Если вы захотите попробовать что-нибудь русское (ну и собственно приступить к разработке :), не забывайте вставить поближе к началу кода (php) установку текущей локали CP1251:

echo setlocale(LC_ALL, 'ru_RU.CP1251', 'rus_RUS.CP1251', 'Russian_Russia.1251');
14 окт 12, 16:27    [13315844]     Ответить | Цитировать Сообщить модератору
 Re: ODBC и Русский язык  [new]
Adylov Timur
Member

Откуда:
Сообщений: 223
servit,

да работает, все хорошо, только мне нужно через PHP
пример взял отсюда

Подставляю русское слово в запрос не работает.
14 окт 12, 18:14    [13316104]     Ответить | Цитировать Сообщить модератору
 Re: ODBC и Русский язык  [new]
Акашева Марина Владимировна
Member

Откуда: Саранск
Сообщений: 1
Adylov Timur,

а в PHP нельзя это слово в досовскую кодировку перевести?

В Delphi например делала так:
s:=DosToWin('запрос'); //слово переводмится из Win в Dos


и:
function DosToWin(St: string): string;
var
Ch: PChar;
begin
Ch := StrAlloc(Length(St) + 1);
OemToAnsi(PChar(St), Ch);
Result := Ch;
StrDispose(Ch)
end;

И наоборот :
function WinToDos(St: string): string;
var
Ch: PChar;
begin
Ch := StrAlloc(Length(St) + 1);
AnsiToOem(PChar(St), Ch);
Result := Ch;
StrDispose(Ch)
end;
15 окт 12, 12:01    [13318956]     Ответить | Цитировать Сообщить модератору
 Re: ODBC и Русский язык  [new]
Alexey Maslov
Member

Откуда: СПб
Сообщений: 1574
Adylov Timur,

вы правы, второе место, где надо указать правильную кодировку - заголовок страницы:

<META content="text/html; charset=windows-1251" http-equiv="Content-Type">

о первом месте написал выше. Спасибо, что напомнили!
15 окт 12, 12:15    [13319032]     Ответить | Цитировать Сообщить модератору
 Re: ODBC и Русский язык  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3124
Блог
Adylov Timur
servit,

да работает, все хорошо, только мне нужно через PHP
Данные те же:
<?php

$strParam="Cach&#233;+запрос+bun&#259; ziua";

$cn=new COM("ADODB.Connection", NULL, CP_UTF8);
$cn->open("DRIVER={InterSystems ODBC35}; SERVER=127.0.0.1; PORT=1972; DATABASE=SAMPLES; UID=_system; PWD=SYS;");

$rs=$cn->execute("SELECT Mission FROM Sample.Company WHERE Name='$strParam'");
while (!$rs->EOF) { 
  echo mb_convert_encoding($rs->Fields(0)->value,"CP866"), PHP_EOL;
  $rs->MoveNext(); 
} 
$rs->Close();
$cn->Close();
?>

Запуск программы:
php.exe test.php

Результат:
Миссия выполнена!

Если у Вас только русские символы в БД, то проблем быть не должно и с интерфейсами odbc_xxx, PDO.
Иначе придётся вручную кодировать строки, так как UTF-8 в них не используется, даже несмотря на наличие "Unicode SQLTypes=1".

Перекодировку строк можно себе немного облегчить, написав на сервере хранимую процедуру:
/// This sample persistent class represents a company.<br>
Class Sample.Company Extends 
(%Persistent%Populate%XML.Adaptor)
{
...
ClassMethod PHP2UTF8(str As %String(MAXLEN=32000)) As %String(MAXLEN=64000) [ SqlProc ]
{
  
q $zcvt($zcvt(str,"O","CP1251"),"I","UTF8")
}

}
Тогда код с использованием стандартных средств PHP примет вид:
<?php

$strParam="Cach&#233;+запрос+bun&#259; ziua";

if ($cn=odbc_connect("DRIVER={InterSystems ODBC35}; SERVER=127.0.0.1; PORT=1972; DATABASE=SAMPLES; UID=_system; PWD=SYS;","","")){

  if($rs=odbc_do($cn, "SELECT Mission FROM Sample.Company where Name=Sample.Company_PHP2UTF8('$strParam')")) {

    $row = odbc_fetch_array($rs);
    echo mb_convert_encoding($row["Mission"],"CP866","CP1251"), PHP_EOL;

    odbc_free_result($rs);
  }

  odbc_close($cn);
}
?>

Результат будет тот же, что и выше.

PS: полноценную работу с UTF-8 обеща(ют/ли) в PHP 6.

PPS:
$strParam="Cach&#233;+запрос+bun&#259; ziua";
следует читать как
$strParam="Caché+запрос+bună ziua";


Сообщение было отредактировано: 16 окт 12, 13:01
16 окт 12, 12:54    [13325910]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: ODBC и Русский язык  [new]
VenumGodzilla
Member

Откуда:
Сообщений: 3
Adylov Timur, скажи пожалуйста если не трудно, как с нуля подключиться к Cache ODBC
24 апр 19, 16:15    [21870749]     Ответить | Цитировать Сообщить модератору
 Re: ODBC и Русский язык  [new]
kalin
Member

Откуда:
Сообщений: 316
Adylov Timur
Из PHP через ODBC я выполняю запрос, но запрос содержит русское слово, и запрос не выполняется. Возникают 2 вопроса:
1) Как решить эту проблему
2) Почему он не работает (правда у меня есть мнение, но хотелось бы правильного ответа)

Да пример запроса
select * from mydictianary where rusname 'запрос'

Данную проблему для себя решал нетривиально.
СУБД Cache кодировке Windows 1251, внешнее приложение на питон в utf8, данные получает из через sql запрос.
Проблема заключалась еще в том, что параметры запроса попадали в базу в правильной кодировке, а возвращались данные в питон в неправильной и соответственно ничего не выбиралось. При попытке получить данные через объект, поля приходили в виде вопросиков. Все решилось созданием доп. полей, где данные полей формировались в виде UTF8 строк.
2 май 19, 22:51    [21877129]     Ответить | Цитировать Сообщить модератору
Все форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M Ответить