我可以使用如下查询查看二进制sql“image”BLOB列(根据WHERE子句过滤):
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
我可以使用.Net代码或带有sql驱动程序的快速脚本将[元数据],[用户代码]和[用户AL代码]中的二进制数据保存到文件中.我尝试使用7-zip进行解压缩,使用十六进制编辑器进行查看,并使用Cygwin“file”命令来检测这些BLOB文件类型.
不幸的是,我无法弄清楚如何将二进制数据解码或解压缩成可读或可用的格式.直到我可以直接使用这些字段中的数据,我必须open NAV Dev Environment and use the Object Designer to view the comma-separated OptionString properties为基于零的查找列表下拉菜单(列表中的每个项目作为整数存储在后端数据库中 – 第一项为0,第二项为1等). sql查找表中不存在字符串值,但NAV确实将它们放在表元数据blob中.
这是我完全支持我作为DBA的NAV用户而不需要NAV开发人员为我查找这些数字到名称的NAV自定义字段映射的缺失链接.然后,我可以查找这些列表值,并根据需要创建匹配的sql CASE语句或自定义查找表.
有了这篇文章,我应该能够创建高级sql视图,查询,报告和工具,而无需访问Dynamics NAV前端用户或开发人员工具.
如果您了解用于这些NAV对象元数据blob属性的二进制数据格式,请通知我.有关如何转换为可读或可用格式的任何建议都会有所帮助.
解决方法
<?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>
假设这是你想要的.
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开发人员做出某种批处理工作,定期(或按需)处理所有表’ matadata并将其保存到外部表/文件/您可以从sql访问的任何内容.