none
Создание Произвольных наборов (Query) из DataSet или DataTable RRS feed

  • Вопрос

  • Вот какая проблема.

     

    Сейчас занимаюсь переводом проекта с MS Access на SQL Server + VB .NET и встретился с такой проблемой.

     

    В MS Access есть такие приятные штуки как ЗАПРОСЫ и их можно лепить не только на таблицах, но и самих на себя (что конечно же с радостью было сделано предшествующими разработчиками).

     

    Теперь же существует необходимость сделать тоже самое но в DataSet. Только как - не могу себе даже представить, а перелапачивать эти иерархичные запросы с кучей LEFT(RIGHT) JOINов UNIONoв и т.п. просто нет времени, да и не легко это.

    Представьте что в БД Access порядка 300 таблиц (неплохо спроектированных и в общем связанных и полезных) и на порядок больше запросов логичную цепь которых можно узреть только начиная спускаться по стеку вызова.

    В итоге если даже собирать все эти подзапросы в один - он получается страницы на две формата А4. Так что это точно не выход, потому как сами понимаете такой запрос человек разгадывает как Код Да Винчи.

     

    В связи с этим и обращаюсь с вопросом о том как все так можно например на двух DataTables (DataTable1 и DataTable2) созданных и заполненных (Fill) построить в том же DataSet некий аналог Запроса (MS Access) что то типа View в SQL Server.

     

    Пост.скриптум: только не предлагайте создавать представления в SQL Serverе - я бы с радостью, но я не разрабатываю БД, я работаю с ПО и не имею полномочий на изменение или добавление объектов БД.

    10 апреля 2007 г. 20:36

Ответы

  • Жаль конечно, что пока полезных советов не последовало.

    Но все же к делу.

     

    Пока нашелся один отличный от построения "Трехэтажных" запросов выход.

    Пришлось обращаться к разработчику БД и просить его сделать набор представлений (View)

    на что тот попросил не перегружать избыточными представлениями БД, и предложил мне самому написать процедуру (StoredProcedure) которая бы делала то, что мне нужно. Так и поступил, процедурка вышла не маленькая, с ветвлением и приличным количеством параметров, однако обеспечила данными мои DataSet привязанные к элементам управления форм, нормальным способом (DataBindings & BindingContext).

     

    Итак, о  конкретной реализации (можно не читать тем, кто силен в Transact-SQL и понимает как организовать иерархичность запросов)

     

    1) Создаем хранимую процедуру:

     

    Code Snippet

    CREATE PROCEDURE dbo.sp_My_UI_DataSets 
     
     (
     /*Список параметров*/

    @Param_1 int = 0,
     @Param_2 int = 0,

    ...
     @Param_N int = 0
     /**/
     )
     
    AS

     

    2) Создаем временные таблицы для хранения данных на которых будет построен результирующий запрос

     

    Code Snippet

    CREATE TABLE #temp_Table_1 (
      [id] [int],
      [Field_1] [varchar] (50),
      [Field_2] [varchar] (50),

    ...
      [Field_N] [Data.DBType] (Size)
      )

     

    CREATE TABLE #temp_Table_2 (
      [id] [int],
      [Field_1] [varchar] (50),
      [Field_2] [varchar] (50),

    ...
      [Field_N] [Data.DBType] (Size)
      )

     

    3) Заполняем временные таблицы данными (в моем случае были просто скопированы запросы из MS Access + немного подкорректированы под Transact-SQL, почему то функции SQL-Server несколько отличаются от MS Access)

     

    Code Snippet

    INSERT INTO #temp_Table_1 SELECT SomeTable.id, SomeTable.Field_1, SomeTable_JOINED.Field_2, ... SomeTable.Field_N
     FROM SomeTable INNER JOIN SomeTable_JOINED ON SomeTable.id = SomeTable_JOINED.id 
     WHERE (SomeTable.ConditionField = @Param and so on)

     

    INSERT INTO #temp_Table_2 SELECT SomeTable.id, SomeTable.Field_1, SomeTable_JOINED.Field_2, ... SomeTable.Field_N
     FROM SomeTable INNER JOIN SomeTable_JOINED ON SomeTable.id = SomeTable_JOINED.id 
     WHERE (SomeTable.ConditionField = @Param and so on)

     

    4) Строим результарующий запрос на временных таблицах (как запрос на запросах MS Access)

     

    Code Snippet

    SELECT #temp_Table_1.id, #temp_Table_1.Field_1, #temp_Table_2.Field_4, ... #temp_Table_2.Field_N
        FROM #temp_Table_1 LEFT JOIN #temp_Table_2

     ON #temp_Table_1.id = #temp_Table_2.id
        WHERE (#temp_Table_1.Field_N Is Null))
        ORDER BY #temp_Table_1.Field_1, #temp_Table_2.Field_1, ... #temp_Table_1.Field_N 

     

    5) Выходим из процедуры и возвращаем результирующий набор данных

     

    Code Snippet
    RETURN

     

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

    Но все можно исправить.

     

    Всем спасибо.

     

    11 апреля 2007 г. 10:09