barbitoff programmer`s blog

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

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

Подключение MySQL к MS SQL Server 2008 по ODBC

Процесс подлючения MySQL по ODBC в качестве Linked Server к MS SQL Server аналогичен тому, который я уже описывал (http://barbitoff.blogspot.com/2011/09/odbc-linked-server-ms-sql-2008.html), правда с несколькими замечаниями:
1) Для оптимизации производительности и повышения стабильности при создании System DSN нужно зайти в Details, и там установить галочки (сам различные варианты настроек не сравнивал, воспользовавшись рекомендациями отсюда http://www.ideaexcursion.com/2009/02/25/howto-setup-sql-server-linked-server-to-mysql/):
  • Connection->Allow Big Result Sets
  • Connection -> Use Compression 
  • Cursors/Results ->  Force use of forward-only cursors
Опцию "Cursors/Results -> Dont't cache results of forward-only cursors" устанавливать не следует, т.к. это приведет к ошибкам при массовых INSERT`ах (см. http://barbitoff.blogspot.com/2011/09/ole-db-provider-msdasql-for-linked.html).
2) Перед созданием Linked Server в MS SQL Server Management Studio зайти в Server Objects -> Linked Servers -> Providers -> Кликнуть правой кнопкой мыши по MSDASQL и зайти в Properties, где установить следующие галочки:
  • Nested queries
  • Level zero only
  • Allow inprocess
  • Supports ‘Like’ Operator
Такая настройка провайдера MSDASQL  отразиться на всех серверах, подключенных по ODBC, что конечно не совсем удобно. Однако без этих параметров запросы к MySQL выполняться не будут. Кстати, такая настройка провайдера подходит и для ODBC-подкючения к Transbase.

Именование таблиц связанного сервера при выполнения SQL-запросов будет следующее: LINKED_SERVER_NAME...TABLE_NAME, т.е. между именем связанного сервера и именем таблицы ставится три точки, например:

SELECT TOP 10 * FROM MYSQL_SERVER...BRANDS



вторник, 13 сентября 2011 г.

Подключение ODBC Linked Server к MS SQL 2008

Чтобы подключить к MS SQL Server связанный сервер (linked server) по ODBC (при отсутствии необходимого OLE-провайдера это - единственный остающийся вариант) нужно:

1) Добавить System DSN (Data Source Name):

Панель управления -> Администрирование -> Источники данных (ODBC) -> Системный DSN -> Добавить, где выбираем нужный ODBC-драйвер и настраиваем параметры соединения с БД

2) На SQL-сервере выполнить запрос:

EXEC sp_addlinkedserver @server='MY_LINKED_SERVER_NAME', @srvproduct='SOMETHING_U_WANT', @provider='MSDASQL', @datasrc='SYSTEM_DSN_NAME'
Также можно выполнить подключение сервера и без использования System DSN, а с помощью Connection String, как, можно прочитать тут: http://msdn.microsoft.com/en-us/library/ms190479.aspx

Используя ODBC, можно, в частности, прицепиться к MySQL-серверу (скачав ODBC-драйвер тут: http://www.mysql.com/products/connector/, тонкости настройки подключения я описал тут: http://barbitoff.blogspot.com/2011/09/mysql-ms-sql-server-2008-odbc.html).

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

XPath: определение возраста

if($birthDate='') 
	then '' 
	else year-from-date(xs:date(local-date()))-year-from-date($birthDate)
		-(if(month-from-date($birthDate) > month-from-date(xs:date(local-date())))
			then 1
			else (if(month-from-date($birthDate) < month-from-date(xs:date(local-date())))
					then 0
					else (if(day-from-date($birthDate) > day-from-date(xs:date(local-date())))
							then 1
							else 0
						)
				)
			)
Возможно, можно как-то сделать это проще, но я пока способа не нашел. Вычитание дат дает результат типа xs:dayTimeDuration вместо xs:yearMonthDuration, из которого было бы удобно извлечь число лет. А вот по числу дней число лет определить очень сложно из-за високосных годов.

вторник, 6 сентября 2011 г.

XPath: проверка, что между указанной датой и текущей прошло меньше определенного количества лет

$dateToCheck + xs:yearMonthDuration('P120Y0M') > xs:date(local-date())- проверяет, что с даты $dateToCheck (типа xs:date) до текущей локальной даты прошло не более 120 лет. Если   $dateToCheck - строка, то нужно сделать xs:date($dateToCheck). 

Регулярное выражение для проверки e-mail

^[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,})$
Допускает email-адреса:
  • abc@abc.com
  • abc.abc@abc.com
  • abc.abc@abc.abc.com
  • abc-abc_abc-1999@abc-abc.abc-abc.abc-abc99.com
Некорректные адреса, подходящие с точки зрения этого шаблона (надо будет поправить):
  •  -abc@abc.com
  • _abc@abc.com
  • abc@-abc.com
  • abc@abc---.com 

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

java.lang.ClassCastException: org.apache.xerces.parsers.XIncludeAwareParserConfiguration cannot be cast to org.apache.xerces.xni.parser.XMLParserConfiguration

Проблема:
при попытке деплоя веб-сервиса на tomcat вываливается исключение типа: "com.sun.xml.ws.transport.http.servlet.WSServletException: WSSERVLET11: failed to parse runtime descriptor: java.lang.ClassCastException: org.apache.xerces.parsers.XIncludeAwareParserConfiguration cannot be cast to org.apache.xerces.xni.parser.XMLParserConfiguration".
Причина:
версия библиотеки Xerces API, используемая tomcat`ом, отличается от той, с которой собран war-ник.
Решение:
  • Удалить из war-ника библиотеку xerces-impl.jar вообще, если она не используется в коде веб-сервиса
  • Используя механизм endorsed-direcory, заставить сервер использовать необходимую версию   Xerces API (как это сделать, описано тут: http://barbitoff.blogspot.com/2011/09/axb-20-api-is-being-loaded-from.html)  

JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI needs 2.1 API

Проблема: 
при попытке деплоя веб-сервиса на tomcat вываливается исключение типа:
JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI (from jar:file:/C:/++tomcat/webapps/testWS/WEB-INF/lib/jaxb-impl.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.1 API. Use the endorsed directory mechanism to place jaxb-api.jar in the bootstrap classloader. (See http://java.sun.com/j2se/1.5.0/docs/guide/standards/)
Причина: 
версия библиотеки JAXB, используемая tomcat`ом, отличается от той, с которой собран war-ник (в данном случае, томкат использует 2.0, а веб-сервис использует 2.1).

Решение:
Вариант 1: Обновить JDK, используемый сервером, до версии, которая использует более новую JAXB.
Вариант 2: использовать endorsed-механизм:
  1. В какую-то диреторию положить необходимую для веб-сервиса версию библиотеки jaxb-api.jar
  2. Далее либо установить переменную окружения JAVA_ENDORSED_DIRS с путем к этой директории, либо залезть в catalina.bat (или sh), запускающий tomcat, и поменять в нём 
-Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%"
 на 
-Djava.endorsed.dirs="/path/to/my/endorsed/dir"

Jar-ники из этой директории будут переопределять те, которые используются jdk`ем по-умолчанию.