barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)

суббота, 1 октября 2011 г.

MySQL: #1005 - Can't create table (errno: 150) при попытке создания внешнего ключа

Проблема:
При попытке создать внешний ключ в таблице MySQL командой ALTER TABLE появляется ошибка "#1005 - Can't create table ...#sql-c84_... (errno: 150)".
Причина:
Причин может быть несколько: несовпадение типов поля, являющегося первичным ключом, и поля-внешнего ключа, или же поле, на которое ссылается внешний ключ вообще не является первичным ключом. Для того, чтобы увидеть текст ошибки, нужно выполнить SHOW ENGINE INNODB STATUS, где посмотреть в блок "LATEST FOREIGN KEY ERROR".

суббота, 24 сентября 2011 г.

Установка кодировки JDBC-ODBC

Установка настройки соединения для JDBC-ODBC моста осуществляется через Properties при создании соединения:
java.util.Properties connInfo = new java.util.Properties();
connInfo.put("charSet", "Cp1251");
connInfo.put("user", login);
connInfo.put("password", pass);
conn = DriverManager.getConnection(URL,connInfo);
Установленная таким образом кодировка повлияет на все символьные данные, получаемые / передаваемые с помощью этого соединения (в частности на то, какую кодировку будет использовать метод ResultSet.getString() при формировании строки).

Java - преобразование строки из одной кодировки в другую

Пример: преобразование строки oldString в кодировке UTF-8 в строку newString в кодировке cp1251:

String newString = new String(oldString.getBytes("UTF-8"), "Cp1251");

пятница, 23 сентября 2011 г.

Transbase ODBC Driver и ошибка при извлечении NUMERIC данных с помощью JDBC-ODBC моста методом getObject

Проблема: 
При попытке извлечь данные из ячейки столбца, имеющего тип "NUMERIC" с помощью метода getObject объекта ResultSet (или просто при попытке просмотра данных в таблице БД Transbase с помощью вкладки "Services" в Netbeans, который видимо тоже при извлечении данных пользуется методом ResultSet.getObject) вылетает исключение вида:

java.sql.SQLException: [Transaction][ODBC Transbase Driver][TEST_DB] unknown: FieldId=5 ???

В логах ODBC-драйвера трансбэйза та же ошибка, однако причина её всё равно не очевидна:


[ODBC Transbase Driver][E:\utmp\seibt\tbodbc3x\trunk\api\sqlcolattribute.c][SQLColAttribute][419]unknown: FieldId=5 ???
[ODBC Transbase Driver][E:\utmp\seibt\tbodbc3x\trunk\api\sqlcolattribute.c][SQLColAttribute][431]Stmt=$0075F200 / Col=27 / FieldId=5 [SQL_DESC_???] <- 0 (len:0 / max: 0)

Решение:
Если тип столбца - "NUMERIC", для извлечения данных использовать метод getFloat вместо универсального getObject (в примере ниже resMD - объект типа ResultSetMetaData, полученный вызовом sourceDataRS.getMetaData(), а sourceDataRS - собственно ResultSet, из которого получаются данные):

 if(resMD.getColumnType(i)==Types.NUMERIC)
row[i] = sourceDataRS.getFloat(i);
else
row[i] = sourceDataRS.getObject(i);

четверг, 22 сентября 2011 г.

cmd: копирование папки с подпапками

Команда copy такого делать не умеет, однако есть команда xcopy, позволяющая копировать содержимое папки со всеми поддиректориями с помощью ключа /E:

xcopy /E "C:\source_dir" "F:\dest_dir\"


Перехват вывода программы в переменную в bat-скрипте

В линуксе такая банальная задача решается элементарно (MYVAR=`COMMAND`, т.е. просто заключением команды в обратные кавычки). В Win я пока не нашел более простого способа чем этот (спасибо http://axisful.me/cactus/cmd/get-cmd-output-in-var):

for /F "tokens=*" %%i in ('COMMAND') do set MYVAR=%%i

воскресенье, 18 сентября 2011 г.

OLE DB provider "MSDASQL" for linked server returned message "[MySQL][ODBC 5.1 Driver][mysqld-5.5.8-log]Commands out of sync; you can't run this command now"

Проблема:
При попытке выполнить массовую вставку данных в таблицу MySQL в БД, подключенной к MS SQL Server 2008 по ODBC (например, конструкцией INSERT INTO ... SELECT ... ), возникает ошибка:
OLE DB provider "MSDASQL" for linked server "MY_LINKED_SERVER" returned message "[MySQL][ODBC 5.1 Driver][mysqld-5.5.8-log]Commands out of sync; you can't run this command now"
Решение:
Отключить опцию  "Don't cache results of forward-only cursors" в настройках System DSN ODBC-источника данных MySQL (или убрать "OPTION=1048576" из строки подключения к связанному серверу, если подключение производится не через System DSN).