2014-01-19 6 views
3

Я хотел был бы иметь возможность прочитать Dynamics NAV 2013 Table Metadata непосредственно из базы данных SQL Server без requiring the NAV Development Environment.Чтение метаданных таблицы Dynamics NAV с SQL

можно просматривать бинарные SQL «образ» BLOB столбцы с запросом, как в следующем (фильтр по мере необходимости с ИНЕКЕ):

SELECT 
    o.[Name], 
    m.[Object Type], 
    m.[Metadata], -- XML Metadata 
    m.[User Code], -- C# Metadata 
    m.[User AL Code] -- C/AL Metadata 
FROM [Navision].[dbo].[Object Metadata] AS m 
JOIN [Navision].[dbo].[Object] AS o 
ON m.[Object ID] = o.[ID] 
AND o.[Company Name] = 'YourCompanyName' 
AND o.[Type] = 0 -- 0 is NAV Table Object Type 

можно сохранить двоичные данные из [Метаданные], [Пользовательский код] и [Пользовательский код AL] отключены в файлах, используя код .Net или быстрый скрипт с драйвером SQL. Я попытался использовать 7-zip для распаковки, шестнадцатеричный редактор для просмотра и команду «файл» Cygwin для обнаружения этих типов файлов BLOB.

К сожалению, я не могу понять, как декодировать или распаковывать двоичные данные в читаемом или пригодном для использования формате. Пока я не буду использовать данные в этих полях напрямую, я должен указать open NAV Dev Environment and use the Object Designer to view the comma-separated OptionString properties для раскрывающегося меню списка нулевого поиска (каждый элемент в списке сохраняется в базе данных в виде целого числа - 0 для первого элемента, 1 для второго , и т.д). Строковые значения отсутствуют в таблице поиска SQL, но NAV помещает их в кадры таблицы метаданных таблицы.

Это недостающее звено для меня, чтобы полностью поддерживать пользователей NAV в качестве администратора баз данных без необходимости разработки NAV-приложений для сопоставления этих имен для сопоставлений полей NAV для имени. Затем я могу найти эти значения в списке и создать соответствующие SQL-запросы CASE или настраиваемые таблицы поиска по мере необходимости.

Как только у меня есть этот кусок, я должен иметь возможность создавать расширенные SQL-запросы, запросы, отчеты и инструменты без необходимости доступа к внешнему пользователю или инструментам разработчика Dynamics NAV.

Пожалуйста, дайте мне знать, если у вас есть знание формата двоичных данных, используемых для этих свойств BLOB метаданных объекта NAV. Любые советы о том, как преобразовать в удобочитаемый или пригодный для использования формат, будут полезны.

ответ

2

Мне удалось получить ответ на формат этих бинарных полей метаданных от автора deV.ch - man vs. code, Dynamics NAV & C# .NET blog. Основываясь на обратном проектировании devch, мы определили, что первые четыре байта (32 бита) этих полей используются NAV для хранения «магического номера», который определяет тип пользовательского типа NAV.

В случае этих полей метаданных магическое число NAB Compressed Blob-типа составляет 0x02457d5b (hex). Чтобы использовать стандартный .Net DeflateStream для декомпрессии, просто выбросьте эти первые четыре байта магического числа, а затем обработайте остальную часть потока с помощью DeflateStream, как обычно.

Мне удалось успешно протестировать этот процесс.Net, теперь я планирую протестировать с помощью Python или некоторых других инструментов, не относящихся к Microsoft, для того, чтобы убедиться, что реализация спускания соответствует отраслевому стандарту. Еще раз спасибо devch за статью, которая привела к этому решению: Accessing Compressed Blobs from outside NAV (NAV2013) (Revisited).

Обновление: проверено на Python zlib, и оно работает! Алгоритм Deflate, совместимый со стандартами, используется после удаления пользовательского магического числа типа NAV Blob. Вот некоторые примеры кода (Python):

# Example Using Python 3.x 
import zlib, sys, struct 

# NAV custom Blob-Type identifier (first 4 bytes) 
magic = struct.unpack('>I',sys.stdin.buffer.read(4))[0] 
print('magic number = %#010x' % magic, file=sys.stderr) 
# Remaining binary data is standard DEFLATE without header 
input = sys.stdin.buffer.read() 
output = zlib.decompress(input,-15) 
sys.stdout.buffer.write(output) 

использовать что-то вроде следующего для теста:

python -u test.py <Input_Meta.blob> Output_Meta.txt 

Конечно, .Net DeflateStream работает после удаления первых четырех байтов, а также. Этот пример просто показывает, что вы не ограничены использованием языков .Net.

+1

Замечательно! Microsoft снова удивляет. Почему, черт возьми, добавьте 4 глупых байта? –

+1

@MakSim Я предполагаю, что это префикс типа, чтобы они могли хранить материал в другом формате, если они этого захотят. –

+0

@VincentVancalbergh Нет такой функции в Nav, хотя –

3

Из этой таблицы можно извлечь из таблицы metadata, и, как я вижу, она хранится как обычный текст, но в двоичном поле. Его можно сохранить в файл с помощью простого MemoryStream (в Nav это называется OutSteram). Поэтому для таблицы 3 я получаю следующие XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<MetaTable xmlns="urn:schemas-microsoft-com:dynamics:NAV:MetaObjects" ID="3" CaptionML="ENU=Payment Terms;RUS=Условия платежа" DataPerCompany="1" Name="Payment Terms" LookupFormID="4" DataCaptionFields="1,5"> 
    <Fields> 
     <Field ID="1" Datatype="Code" DataLength="10" Enabled="1" FieldClass="Normal" Name="Code" CaptionML="ENU=Code;RUS=Код" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="1" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/> 
     <Field ID="2" Datatype="DateFormula" Enabled="1" FieldClass="Normal" Name="Due Date Calculation" CaptionML="ENU=Due Date Calculation;RUS=Расчет срока оплаты" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/> 
     <Field ID="3" Datatype="DateFormula" Enabled="1" FieldClass="Normal" Name="Discount Date Calculation" CaptionML="ENU=Discount Date Calculation;RUS=Расчет даты скидки" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/> 
     <Field ID="4" Datatype="Decimal" Enabled="1" FieldClass="Normal" Name="Discount %" CaptionML="ENU=Discount %;RUS=Скидка (%)" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" MinValue="0" MaxValue="100" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/> 
     <Field ID="5" Datatype="Text" DataLength="50" Enabled="1" FieldClass="Normal" Name="Description" CaptionML="ENU=Description;RUS=Описание" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/> 
     <Field ID="6" Datatype="Boolean" Enabled="1" FieldClass="Normal" Name="Calc. Pmt. Disc. on Cr. Memos" CaptionML="ENU=Calc. Pmt. Disc. on Cr. Memos;RUS=Расчет скидки оплаты по кредит-нотам" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/> 
    </Fields> 
    <Keys> 
     <Key Enabled="1" Key="Field1" MaintainSQLIndex="1" MaintainSIFTIndex="1" Clustered="1"/> 
    </Keys> 
    <FieldGroups> 
     <FieldGroup GroupID="1" GroupName="DropDown" GroupFields="Field1,Field5,Field2"/> 
    </FieldGroups> 
</MetaTable> 

Предположим, что это то, что вы хотите.

код писать его в файл в Nav будет выглядеть следующим образом:

ObjectMetadata:Record(Object Metadata) 
Code:BigText 
File:File  
CodeStream:InStream  
FileStream:OutStream   

ObjectMetadata.INIT; 

IF ObjectMetadata.GET(1,3) THEN 
BEGIN 
    ObjectMetadata.CALCFIELDS(Metadata); 
    File.CREATE('C:\temp\Code.txt'); 
    File.CREATEOUTSTREAM(FileStream); 

    clear(codestream); 
    ObjectMetadata."Metadata".CREATEINSTREAM(CodeStream); 
    Code.READ(CodeStream); 
    Code.WRITE(FileStream); 

    file.close(); 
END; 

Теперь у вас есть варианты: попытаться сделать то же самое в SQL/.Net (я не увлечена с ним), или вы можете попросите своего разработчика Nav сделать какое-то пакетное задание, которое будет периодически (или по требованию) обрабатывать матадаты всех таблиц и сохранять их во внешней таблице/файле/независимо от того, что вы можете получить от SQL.

+0

Спасибо за ответ Мак, хотя я бы предпочел возможность доступа к метаданным NAV непосредственно из SQL/.Net, полезно иметь образец кода, который могут использовать мои разработчики NAV для предоставления этих метаданных для меня. –

1

Почему бы не использовать веб-сервисы и не получить нужные данные, не делая ничего интересного?

Пользователи могут затем использовать PowerPivot для Excel и создавать свои собственные отчеты.

Вы также можете использовать надстройку Excel для NAV и просто экспортировать данные, чтобы перенести непосредственно из NAV, а затем обновить из Excel.

+0

Создание веб-сервиса звучит очень причудливо. Существует ли веб-служба, встроенная в NAV, которая обеспечивает легкий доступ к данным? Просьба представить простой пример того, как использовать эту возможность веб-службы для упрощения доступа к данным со стороны пользователей NAV. У вас есть ссылка или пример для надстройки Excel для NAV? Я не слышал об этом - это компонент, предоставленный Microsoft? –

+1

Веб-службы встроены в NAV. Если вы введете '' Web Services'' в панель поиска в Центре ролей, вы можете опубликовать страницу, Codeunit или Query и сделать ее доступной через SOAP или ODATA. http://saurav-nav.blogspot.co.uk/2013/11/nav-rtc-introduction-to-web-services.html – Steve

Смежные вопросы