June 2008 Blog Posts

Classic: Tree & SQL

27 June 2008 |

Если Вы завтра на экзамене получите 3,
то это будет чудо ... [пауза] ...
но чудес не бывает.
(Преподаватель в институте)

Любой разработчик знает о проблемах, которые возникают с иерархическими данными в реляционных моделях. Имеются в виду проблемы написания запросов и проблемы производительности.

До выхода 2005 SQL Server, проблемы эти решались с помощью хранения избыточных данных. С выходом 2005-ого появились CTE (Common Table Expression), которые решают проблему построения запросов. К сожалению CTE не подходит для больших объёмов данных, по причине производительности, то что не подходит было понятно с самого начала, но надежда на чудо оставалась. Вот и нам столкнувшись с проблемами производительности пришлось решать их старыми проверенными методами, благо как решать есть где посмотреть [1], [2]. А ведь совсем скоро выйдет SQ Server 2008, где есть тип данных Hierarchyid, может это поставит точку в борьбе с деревьями...

Radio: Echo Of Moscow

25 June 2008 |

Мне не нравиться кино,
там все притворяются.
(Умный человек)

Есть мнение, что программы телепередач рассчитаны на средний уровень аудитории. Это такой уровень, на котором способность размышлять, не нужна, достаточно эмоций, интуиции, побольше чувств и рефлексов, одним словом всё то, что присутствует у достаточно развитых животных. В том или ином виде, это мнение я слышал от большинства образованных людей.

Хорошо, но откуда же надо получать информацию, вообще эту задачу решает не телевидение, а СМИ в целом. И вот делая такое умозаключение я решил, что надо обратиться к тем кто себя позиционирует, как источник информации для образованных, интеллигентных людей. Решил послушать радиостанцию Эхо Москвы, воспользовавшись тем обстоятельством, что записи передач выкладываются на сайте в виде аудио подкастов. Длился этот опыт две недели, и можно с грустью констатировать, что данный источник информации как и телевидение пришлось вычеркнуть и списка заслуживающих внимания.

Вначале все было хорошо: в словах есть мысль, аргументация приводиться разумная, присутствует даже некое подобие объективного взгляда на обсуждаемые темы. Но со временем стал замечать, что там такая же дурь как и на телевидение, только менее очевидна, вместо тупой апелляции к эмоциям, здесь набор из не слишком сложных, точечных нарушений правил логики, на подобии классического "Изо лжи следует всё что угодно". С моей точки зрения Эхо Москвы оказывает даже более отрицательное влияние, чем телевидение. Потому что может создаться впечатление, что это не их выводы а твои собственные, если не смотреть на вещи критически. В итоге я не нашёл ни одной передачи, в которой бы, какие либо выводы не навязывались, и самое страшное, что прослеживается явная тенденциозность, создаётся впечатление, что основная задача ведущих, заключается в том, чтобы навязать эти выводы слушателю.

В итоге можно сказать, если вы действительно хотите получить более менее достоверную и объективную информацию, то придётся извлекать её из разных источников, и хорошо если это будут не СМИ, а просто СИ. Серебрянной пули не существует. Берегите голову не засоряйте её всякой дрянью, пусть в ней будет только качественная информация.

TableAdapter: CommandTimeout

21 June 2008 |

Для выполнение SQL команды в ADO.NET стоит timeout 15 секунд, по умолчанию. В подавляющем большинстве случае этого достаточно, но иногда возникает необходимость увеличить timeout, чтобы не возникало исключение, и если вы пользуетесь типизированными TableAdapter-ами, то у Вас возникнет вопрос, как это сделать. Удивительно, что простого и логичного способа не существует.

Решение, которое я использую выглядит следующим образом. В том же namespace, что целевые TableAdapter-ы создаю класс содержащий Extension методы:

internal static class TableAdapterHelper
{
public static int GetCommandTimeout(this Component adapter)
{
var field = adapter.GetType().GetProperty("CommandCollection",
BindingFlags.NonPublic | BindingFlags.Instance);
var commandCollection =
(SqlCommand[])field.GetValue(adapter, null);
return commandCollection[0].CommandTimeout;
}

public static void SetCommandTimeout(this Component adapter, int value)
{
var field = adapter.GetType().GetProperty("CommandCollection",
BindingFlags.NonPublic | BindingFlags.Instance);
var commandCollection =
(SqlCommand[])field.GetValue(adapter, null);

for (int i = 0; i < commandCollection.Length; i++)
{
if ((commandCollection[i] != null))
((SqlCommand)commandCollection[i]).CommandTimeout = value;
}
}
}


Затем в partial классе целевых TableAdapter-ов можно использовать методы класса расширения, к примеру вот так:

partial class DeviceTableAdapter
{
public DeviceTableAdapter(SqlConnection connection,
SqlTransaction transaction) : this()
{
this.Connection = connection;
this.Transaction = transaction;
this.SetCommandTimeout(0);
}
}

Aggregate Concatenation String

18 June 2008 |

Недавно знакомый задал такой вопрос: хочу при группировании в SQL запросе, чтобы строки складывались в одну строку через запятую, по аналогии SUM, но только для строк.

Нормальная ситуация, в жизни должна встречаться часто. Первое, что пришло в голову это использование CLR для написания UDF, или использование CTE. Приятно было узнать, что оба ответа верны, но чтобы получить полное и чёткое представление о решении этой задачи, очень рекомендую прочитать вот эту статью.

Было бы смешно, если бы не было грустно...

17 June 2008 |

Многие наверное в курсе, что в последний 1-2 года, участились иски в суд, против людей, которые где-то, что-то написали в интернете. В большинстве своём это были иски правоохранительных органов или представителей власти. Часто высказывания, которые являлись поводом для подачи иска действительно содержали, нецензурную лексику, да и суть исков тоже была ясна: "Не сметь говорить плохо про того кто сильней тебя...". Отрицательного в таком положении вещей конечно гораздо больше чем положительного, но тем не менее положительное тоже есть. Во первых истец становится известен всем сами знаете с какой стороны: с правильной. Во вторых люди начинают снижать количество нецензурных слов и жёстких выражений в своих высказываниях.

Но последняя новость на эту тему, которую я увидел, и ознакомился с предметом [1], [2]. Наводит на очень грустные мысли. Лично Я считаю, что люди подающие подобные иски должны нести суровое наказание, в здоровом обществе, если этого не происходит, то фактически это означает ограничение основных свобод для существенной части граждан. И такая, казалось бы мелочь, как невозможность высказать своё мнение о ком-то или чём-то, может привести к плохим последствиям. Вспомните из истории примеры обществ, где существовали подобные запреты,... вы бы хотели жить в каком нибудь из них?

Motivation Another View

17 June 2008 |

"А *** в **** это Вам не мотивация"
Представитель заказчика

Как правильно замечает автор статьи, много разговоров о мотивации сотрудников. Тем более становиться приятно, насколько грамотные советы приводит сам автор, одним разом отметаю ту чушь, которую писали до него... Читайте, конспектируйте, получайте удовольствие...

SQL Server Database Publishing Wizard 1.1

12 June 2008 |

Недавно узнал о бесплатной утилитке: SQL Server Database Publishing Wizard 1.1. Позволяет импортировать схему и данные в SQL скрипт, как для всей базы целиком, так и выборочно таблицы, может работать из командной строки. Особенно полезна, когда необходимо получить скрипт для заполнения таблицы данными в виде набора INSERT-ов. Утилита не наворочена в смысле функциональности, но то что делает делает хорошо и понятно. Это как один из специфических ключей в наборе инструментов слесаря... если вы слесарь, то она буде Вам полезна. Но всё должно использоваться по назначению, если Вам надо получить скрипт - разницу между данными в базах данных, то Вам сюда. Глупо забивать молотком саморезы, когда отвертка под рукой.

IT Projects: C VS C

09 June 2008 |

Опытные люди знают как происходит выполнение IT проектов в организациях. Существует некоторый шаблон, который поражает своей закономерностью и кривостью. Но видно так уж устроен мир, а именно ошибочные ментальные установки людей вовлечённых в этот процесс.

Замечательная заметка по этому поводу, которую просто приятно почитать: Клиент всегда не прав.

SQL Query: (FromId, ToId) Smart Distinct

09 June 2008 |

Часто мир теории далёк от мира практики и редко задачи из этих двух миров пересекаются. Поэтому встретить на практике задачу характерную скорее для мира теории всегда любопытно.

Есть сеть некоторых объектов, данные о сети приходят в виде таблицы формата (FromId, ToId). При этом связи могут дублироваться, то есть, встречаются варианты: (1, 2) и (2, 1) одновременно, но по семантики данных направление связи не важно, поэтому необходимо удалить такое дублирование связей. Как это сделать? Так выглядит постановка задачи в практической плоскости.

Сформулируем задачу в более обобщённом, теоретическом виде. Есть, таблица со столбцами A и B, одного типа, попарно уникальные. В таблице могут содержаться значения вида: (x, y) и (y, x), одновременно. Получить в результате SQL запроса таблицу в которой такие пары заменены одним из любых двух вариантов. Пример:

A   B                A   B  
x    y               k    i
x    z       =>    y    x
k    i                z    x
y    x
z    x

Вот достаточно академический вид. Такие задачи должны любить задавать на собеседованиях или на экзаменах в учебных заведениях. Попробуйте найти решение этой задачи самостоятельно, не смотря варианты решений приведенные ниже.

Решение, которое работает в максимально общем виде выглядит так:

;WITH
NTbl(Id, A, B) AS
(
 
SELECT ROW_NUMBER() OVER (ORDER BY Tbl.A, Tbl.B) AS Id, Tbl.A, Tbl.B
 
FROM Tbl
)
SELECT NTbl.A, NTbl.B FROM NTbl,
(
 
SELECT DISTINCT MAX(Id) AS Id FROM
 
(
        
SELECT DISTINCT Id, A, B FROM NTbl
   
UNION
        
SELECT DISTINCT Id, NTbl.B AS A, NTbl.A AS B FROM NTbl
 
) AS Temp
  GROUP BY Temp.A, Temp.B
) AS DTblId WHERE DTblId.Id = NTbl.Id

Элегантное решение, достойное академической задачи. WITH здесь используется только для сокращения записи, логика работы минимально использует особенности Transact-SQL поэтому это решение подходит не только для SQL Server, но и для других СУБД.

С теоретической точки зрения задача решена, но с практической данное решение может оказаться не очень подходящим, в плане производительности. Существует другое решение в двух вариантах в зависимости от типа столбцов:
-- Если тип A, B поддерживает MAX
SELECT DISTINCT MAX(Tbl.A) AS A, MIN(Tbl.B) AS B
FROM Tbl

GROUP BY CAST( CONVERT(int, HashBytes('MD5', Tbl.A)) AS bigint) +
          
CONVERT(int, HashBytes('MD5', Tbl.B))

-- Если тип A, B не поддерживает MAX (к примеру uniqueidentifier) то...
SELECT DISTINCT
CAST( MAX(CAST(Tbl.A AS nchar(36))) AS uniqueidentifier) AS A,

CAST( MIN(CAST(Tbl.B AS nchar(36))) AS uniqueidentifier) AS B
FROM Tbl

GROUP BY CAST( CONVERT(int, HashBytes('MD5', Tbl.A)) AS bigint) +
          
CONVERT(int, HashBytes('MD5', Tbl.B))

Подход рабочий, но вот реализация имеет недостатки. К примеру результат будет ошибочный, если сумма Хешей двух разный значений a и b будет совпадать. В более общем виде проблема заключается в поиске функции вида: F(x, y) такой что, F(x, y) = F(y, x) и где результирующие значение уникально для различных пар (x, y), при этом x и y могут быть разных типов (строки, гуиды, числа...).

Move: Fallen Art

06 June 2008 |

Правильные книги, фильмы, мультфильмы и вообще искусство, отличается от не правильного тем, что заставляет задуматься о важных вещах. Исскуство должно делать человека лучше.

BringToFront & SendToBack In WPF

06 June 2008 |

Большинство своих действий человек делает по привычки не задумываясь о том как он их делает. Когда привычные действия не срабатывают это вызывает эмоции, недоумение/гнев, в зависимости от ситуации.

Работая с WPF столкнулся с такой неожиданной вещью: нет привычных методов BringToFront и SendToBack. Просто нет и всё, поленились разработчики их явно добавить. Понятия Z-Order и Z-Index есть, а методов нет.

Конечно, это не show stopper, в интернете много примеров реализации этих методов [1], [2]. Но все они какие то не основательные, нет ощущения, что решив раз не придётся возвращаться к проблеме снова.

Порядком UIElement-ов можно управлять в контейнере Panel и его наследниках, к примеру: Canvas, DockPanel, Grid. Хочеться, чтобы во время разработки при необходимости у элемента можно было вызвать метод BringToFront или SendToBack. Применив Extension, которые появились в .NET 3.5, можно легко локализовать реализацию методов. Учитывая всё выше сказанное получил вот такую реализацию: Исходный Код.

А нам всё равно или OOXML in ISO

02 June 2008 |

Все уже знают, что формат OOXML стандартизован ISO. Многие догадываются почему после того как стандарт не был принят в первый раз, он всё таки был принят со второго раза. Ситуация, когда организация по стандартизации принимает два формата преследующих одни и те же цели, выглядит мягко говоря не логично, говоря прямо это противоречит понятию стандартизация.

Ну мы, не первый день за мужем. И в этом свете интересно посмотреть, а какие страны как голосовали. Это поважней и поинтересней чем евро-виденье. Посмотреть можно здесь. К примеру страны BRIC, все, кроме России, голосовали против. Еще из интересного, то что Канада голосовала против, а Белоруссия за.

Россия при голосовании воздержалась, любопытно почему: нам всё равно..., мы не видим разницы, и вообще где мы..., учитывая то что до этого Россия голосовала за. Любопытно было бы узнать комментарии официальных лиц, по этому вопросу.