从 4D 数据库生成 DDL
Generate DDL from 4D database
我继承了一个 4D 数据库,我需要从中提取所有数据以导入到另一个关系数据库。 4D 数据库 ODBC 驱动程序似乎有很多怪癖,无法将其用作 SQL 服务器链接服务器。如果有人需要,我可以提供血淋淋的细节,但足以说明;看起来不太可能。
我尝试的另一种可能性是使用 MS SQL 服务器导入数据向导。当然,这是幕后的 SSIS,它需要 32 位 ODBC 驱动程序。这得到了一部分,但它无法尝试创建目标 tables,因为它不理解什么是 CLOB 数据类型。
所以我的推理是,如果我可以从 4D 数据库中现有的 table 结构构建 DDL,我可以使用数据导入向导导入数据,如果我创建 table首先。
关于我可以使用哪些工具来执行此操作的任何想法?
谢谢。
博芬,
"inherited a 4D database" 是否意味着它是 运行ning 或您有数据文件和结构但无法打开它?
如果它是 运行ning 并且您可以访问用户环境,那么简单的事情就是使用 4D 的导出功能。如果您无权访问用户环境,则 ODBC 的唯一选择是它是否设计为允许 ODBC,或者开发人员是否提供了一些导出功能。
如果您不能 运行 它,您将无法直接访问数据文件。 4D 使用专有的数据结构,并且随着版本的不同而变化。默认情况下它未加密,因此您实际上可以 read/scavage 数据,但不能只构建 DDL 并从中提取数据。 ODBC 是 运行ning 应用程序和其他一些来源之间的连接。
最好的办法是联系开发人员并寻求帮助。如果那不是一个选项,那就得到 运行ning 的东西。如果它真的很旧,您可以联系 4D 获取存档版本的副本。根据它的版本和构建方式(编译、解释、引擎),您的选择会有所不同。
[编辑] 开发人员可以通过 SQL 指定可用的架构,出于安全或可用性原因,我们经常限制公开的内容。听起来这里可能就是这种情况——它可以解释为什么你看不到整个结构。
这也可以用原生 4D 结构来完成。我可以通过 field/table 通过 table 限制在用户模式下在字段上可见的 4D 结构的数量。通常这是为了减少系统对用户的混淆,但它也是一种加强数据安全的方法。因此,我可以允许您下载所有 'data',但不允许您下载使数据库正常工作的内部元素。
如果您能够导出您想要的数据,这听起来很不错,即使它很慢。
唉,4D ODBC 驱动程序是一个(咳咳)容器,里面装满了如此强大的肥料,none 可以忍受它的气味...
没有简单的答案,但如果你在这里做到了,你就已经处在一个糟糕的地方所以我会分享一些有用的东西。
您可以使用免费软件 ODBC Query Tool,它可以通过用户或系统 DSN 与 64 位驱动程序连接到 ODBC。那么你 运行 这个查询:
SELECT table_id, table_name,column_name, data_type, data_length, nullable, column_id FROM _user_columns ORDER BY table_id, column_id limit ALL
注意:ODBC 查询工具默认获取前 200 行页面。您需要滚动到结果集的底部。
我还尝试了 JetBrains 和 Razor 的 DataGripSQL。两者都不适用于 4D ODBC DSN。
现在您有了这个结果集,将其导出到 Excel 并保存电子表格。我发现文本文件输出没有用。它们导出为可读文本,而不是 CSV 或制表符分隔。
然后我使用 Microsoft SQL 服务器导入数据向导(即 SSIS)将该数据导入 table 然后我可以操作。我的目标是 SQL 服务器,因此执行此步骤对我来说很有意义,但是如果您导入到另一个目标数据库,则可以根据您现在拥有的任何您认为最好的工具的数据创建 table 定义.
一旦我在 table 中有了这个,我就使用这个 T-SQL 脚本来生成 DDL:
use scratch;
-- Reference for data types: https://github.com/PhenX/4d-dumper/blob/master/dump.php
declare @TableName varchar(255) = '';
declare C1 CURSOR for
select distinct table_name
from
[dbo].[4DMetadata]
order by 1;
open C1;
fetch next from C1 into @TableName;
declare @SQL nvarchar(max) = '';
declare @ColumnDefinition nvarchar(max) = '';
declare @Results table(columnDefinition nvarchar(max));
while @@FETCH_STATUS = 0
begin
set @SQL = 'CREATE TABLE [' + @TableName + '] (';
declare C2 CURSOR for
select
'[' +
column_name +
'] ' +
case data_type
when 1 then 'BIT'
when 3 then 'INT'
when 4 then 'BIGINT'
when 5 then 'BIGINT'
when 6 then 'REAL'
when 7 then 'FLOAT'
when 8 then 'DATE'
when 9 then 'DATETIME'
when 10 then
case
when data_length > 0 then 'NVARCHAR(' + cast(data_length / 2 as nvarchar(5)) + ')'
else 'NVARCHAR(MAX)'
end
when 12 then 'VARBINARY(MAX)'
when 13 then 'NVARCHAR(50)'
when 14 then 'VARBINARY(MAX)'
when 18 then 'VARBINARY(MAX)'
else 'BLURFL' -- Put some garbage to prevent this from creating a table!
end +
case nullable
when 0 then ' NOT NULL'
when 1 then ' NULL'
end +
', '
from
[dbo].[4DMetadata]
where
table_name = @TableName
order by column_id;
open C2;
fetch next from C2 into @ColumnDefinition;
while @@FETCH_STATUS = 0
begin
set @SQL = @SQL + @ColumnDefinition;
fetch next from C2 into @ColumnDefinition;
end
-- Set the last comma to be a closing parenthesis and statement terminating semi-colon
set @SQL = SUBSTRING(@SQL, 1, LEN(@SQL) - 1) + ');';
close C2;
deallocate C2;
-- Add the result
insert into @Results (columnDefinition) values (@SQL);
fetch next from C1 into @TableName;
end
close C1;
deallocate C1;
select * from @Results;
我使用生成的 DDL 来创建数据库 table 定义。
不幸的是,SSIS 不能与 4D 数据库 ODBC 驱动程序一起使用。它不断抛出身份验证错误。但是您可以使用您自己的定制工具加载此数据库,该工具适用于 4D 的 ODBC 怪异。
我有自己的工具(遗憾的是我不能分享它)可以将 XML 导出的数据直接加载到数据库中。所以我完成了。
祝你好运。
我继承了一个 4D 数据库,我需要从中提取所有数据以导入到另一个关系数据库。 4D 数据库 ODBC 驱动程序似乎有很多怪癖,无法将其用作 SQL 服务器链接服务器。如果有人需要,我可以提供血淋淋的细节,但足以说明;看起来不太可能。
我尝试的另一种可能性是使用 MS SQL 服务器导入数据向导。当然,这是幕后的 SSIS,它需要 32 位 ODBC 驱动程序。这得到了一部分,但它无法尝试创建目标 tables,因为它不理解什么是 CLOB 数据类型。
所以我的推理是,如果我可以从 4D 数据库中现有的 table 结构构建 DDL,我可以使用数据导入向导导入数据,如果我创建 table首先。
关于我可以使用哪些工具来执行此操作的任何想法?
谢谢。
博芬, "inherited a 4D database" 是否意味着它是 运行ning 或您有数据文件和结构但无法打开它?
如果它是 运行ning 并且您可以访问用户环境,那么简单的事情就是使用 4D 的导出功能。如果您无权访问用户环境,则 ODBC 的唯一选择是它是否设计为允许 ODBC,或者开发人员是否提供了一些导出功能。
如果您不能 运行 它,您将无法直接访问数据文件。 4D 使用专有的数据结构,并且随着版本的不同而变化。默认情况下它未加密,因此您实际上可以 read/scavage 数据,但不能只构建 DDL 并从中提取数据。 ODBC 是 运行ning 应用程序和其他一些来源之间的连接。
最好的办法是联系开发人员并寻求帮助。如果那不是一个选项,那就得到 运行ning 的东西。如果它真的很旧,您可以联系 4D 获取存档版本的副本。根据它的版本和构建方式(编译、解释、引擎),您的选择会有所不同。
[编辑] 开发人员可以通过 SQL 指定可用的架构,出于安全或可用性原因,我们经常限制公开的内容。听起来这里可能就是这种情况——它可以解释为什么你看不到整个结构。
这也可以用原生 4D 结构来完成。我可以通过 field/table 通过 table 限制在用户模式下在字段上可见的 4D 结构的数量。通常这是为了减少系统对用户的混淆,但它也是一种加强数据安全的方法。因此,我可以允许您下载所有 'data',但不允许您下载使数据库正常工作的内部元素。
如果您能够导出您想要的数据,这听起来很不错,即使它很慢。
唉,4D ODBC 驱动程序是一个(咳咳)容器,里面装满了如此强大的肥料,none 可以忍受它的气味...
没有简单的答案,但如果你在这里做到了,你就已经处在一个糟糕的地方所以我会分享一些有用的东西。
您可以使用免费软件 ODBC Query Tool,它可以通过用户或系统 DSN 与 64 位驱动程序连接到 ODBC。那么你 运行 这个查询:
SELECT table_id, table_name,column_name, data_type, data_length, nullable, column_id FROM _user_columns ORDER BY table_id, column_id limit ALL
注意:ODBC 查询工具默认获取前 200 行页面。您需要滚动到结果集的底部。
我还尝试了 JetBrains 和 Razor 的 DataGripSQL。两者都不适用于 4D ODBC DSN。
现在您有了这个结果集,将其导出到 Excel 并保存电子表格。我发现文本文件输出没有用。它们导出为可读文本,而不是 CSV 或制表符分隔。
然后我使用 Microsoft SQL 服务器导入数据向导(即 SSIS)将该数据导入 table 然后我可以操作。我的目标是 SQL 服务器,因此执行此步骤对我来说很有意义,但是如果您导入到另一个目标数据库,则可以根据您现在拥有的任何您认为最好的工具的数据创建 table 定义.
一旦我在 table 中有了这个,我就使用这个 T-SQL 脚本来生成 DDL:
use scratch;
-- Reference for data types: https://github.com/PhenX/4d-dumper/blob/master/dump.php
declare @TableName varchar(255) = '';
declare C1 CURSOR for
select distinct table_name
from
[dbo].[4DMetadata]
order by 1;
open C1;
fetch next from C1 into @TableName;
declare @SQL nvarchar(max) = '';
declare @ColumnDefinition nvarchar(max) = '';
declare @Results table(columnDefinition nvarchar(max));
while @@FETCH_STATUS = 0
begin
set @SQL = 'CREATE TABLE [' + @TableName + '] (';
declare C2 CURSOR for
select
'[' +
column_name +
'] ' +
case data_type
when 1 then 'BIT'
when 3 then 'INT'
when 4 then 'BIGINT'
when 5 then 'BIGINT'
when 6 then 'REAL'
when 7 then 'FLOAT'
when 8 then 'DATE'
when 9 then 'DATETIME'
when 10 then
case
when data_length > 0 then 'NVARCHAR(' + cast(data_length / 2 as nvarchar(5)) + ')'
else 'NVARCHAR(MAX)'
end
when 12 then 'VARBINARY(MAX)'
when 13 then 'NVARCHAR(50)'
when 14 then 'VARBINARY(MAX)'
when 18 then 'VARBINARY(MAX)'
else 'BLURFL' -- Put some garbage to prevent this from creating a table!
end +
case nullable
when 0 then ' NOT NULL'
when 1 then ' NULL'
end +
', '
from
[dbo].[4DMetadata]
where
table_name = @TableName
order by column_id;
open C2;
fetch next from C2 into @ColumnDefinition;
while @@FETCH_STATUS = 0
begin
set @SQL = @SQL + @ColumnDefinition;
fetch next from C2 into @ColumnDefinition;
end
-- Set the last comma to be a closing parenthesis and statement terminating semi-colon
set @SQL = SUBSTRING(@SQL, 1, LEN(@SQL) - 1) + ');';
close C2;
deallocate C2;
-- Add the result
insert into @Results (columnDefinition) values (@SQL);
fetch next from C1 into @TableName;
end
close C1;
deallocate C1;
select * from @Results;
我使用生成的 DDL 来创建数据库 table 定义。
不幸的是,SSIS 不能与 4D 数据库 ODBC 驱动程序一起使用。它不断抛出身份验证错误。但是您可以使用您自己的定制工具加载此数据库,该工具适用于 4D 的 ODBC 怪异。
我有自己的工具(遗憾的是我不能分享它)可以将 XML 导出的数据直接加载到数据库中。所以我完成了。
祝你好运。