通常,Clarion 使用数据字典 (DCT) 作为程序将使用的持久数据(文件)的中心。还有其他方法可以定义表格,但由于您提到您从 APP 编译,我的结论是您的 APP 链接到 DCT。
在 DCT 中,您拥有应用程序将使用的每个文件的声明。在文件声明中,您可以告知逻辑和磁盘文件名。错误信息说你的磁盘文件名定义有问题。
Clarion 语言将逻辑数据结构定义与其磁盘文件分开。 Clarion 程序的“文件”是一种复杂的数据结构,符合以下条件:
structName FILE, DRIVER( 'driverType' ), NAME( 'diskFileName' )
key KEY( keyName )
index INDEX( indexName )
recordName RECORD
field DATATYPE
.
.
END
END
以上是基本的声明语法,一个真实的例子是这样的:
orders FILE, DRIVER( 'TopSpeed' ), NAME( 'sales.dat\orders' )
ordersPK KEY( id ), PRIMARY
customerK INDEX( customerID )
notes MEMO( 4096 )
RECORD RECORD
id LONG
customerID LONG
datePlaced DATE
status STRING( 1 )
END
END
orderItems FILE, DRIVER( 'TopSpeed' ), NAME( 'sales.dat\items' )
itemsPK KEY( orderID, id ), PRIMARY
RECORD RECORD
orderID LONG
id LONG
productID LONG
quantityOrdered DECIMAL( 10, 2 )
unitPrice DECIMAL( 10, 2 )
END
END
现在,通过上述两个声明,我有两个逻辑文件驻留在同一个磁盘文件中。这是为某些文件驱动程序提供的功能,例如 TopSpeed 文件驱动程序。由系统设计人员决定是否以及哪些文件将驻留在同一个磁盘文件中,如果是这种情况,我可以在另一篇文章中讨论。
目前,问题可能是由于您可能没有更改文件声明的 NAME 属性,并且您使用的驱动程序不支持多文件存储。
这是针对上述相同情况的修订文件定义,但针对的是 SQL 数据库。
szDBConn CSTRING( 1024 ) ! //Connection string to DB server
orders FILE, DRIVER( 'ODBC' ), NAME( 'orders' ), OWNER( szDBconn )
ordersPK KEY( id ), PRIMARY
customerK INDEX( customerID )
notes MEMO( 4096 ), NAME( 'notes' )
RECORD RECORD
id LONG, NAME( 'id | READONLY' )
customerID LONG
datePlaced DATE
status STRING( 1 )
END
END
orderItems FILE, DRIVER( 'ODBC' ), NAME( 'order_items' ), OWNER( szDBconn )
itemsPK KEY( orderID, id ), PRIMARY
RECORD RECORD
orderID LONG
id LONG
productID LONG
quantityOrdered DECIMAL( 10, 2 )
unitPrice DECIMAL( 10, 2 )
END
END
现在,如果您注意,您会注意到存在szDBconn 变量声明,它在文件声明中被引用。这对于通知 Clarion 文件驱动程序系统传递 ODBC 管理器以连接到数据库是必要的。查看Connection Strings 获取大量连接字符串示例。
检查文件的 DCT 定义,看看它们是否反映了驱动程序的期望。
另外,请注意 Clarion 允许混合使用不同的文件驱动程序以供同一程序使用。因此,如果需要,您可以调整现有程序以使用外部数据源。
这是一个完整的 Clarion 程序,用于将信息从 ISAM 文件传输到 DBMS。
PROGRAM
MAP
END
INCLUDE( 'equates.clw' ) ! //Include common definitions
szDBconn CSTRING( 1024 )
inputFile FILE, DRIVER( 'dBase3' )
RECORD RECORD
id LONG
name STRING( 50 )
END
END
outuputFile FILE, DRIVER( 'ODBC' ), NAME( 'import.newcustomers' ), |
OWNER( szDBconn )
RECORD RECORD
id LONG
name STRING( 50 )
backendImportedColumn STRING( 8 )
imported GROUP, OVER( backendImportedColumn )
date DATE
time TIME
END
processed CHAR( 1 )
END
END
CODE
IF NOT EXISTS( COMMAND( 1 ) )
MESSAGE( 'File ' & COMMAND( 1 ) & ' doesn''t exist' )
RETURN
END
imputFile{ PROP:Name } = COMMAND( 1 )
OPEN( inputFile, 42h )
IF ERRORCODE()
MESSAGE( 'Error openning file ' & inputFile{ PROP:Name } )
RETURN
END
szDBconn = 'Driver={{PostgreSQL ANSI};Server=192.168.0.1;Database=test;' & |
'Uid=me;Pwd=plaintextpassword'
OPEN( outputFile, 42h )
IF ERRORCODE()
MESSAGE( 'Error openning import table: ' & FILEERROR() )
RETURN
END
! // Lets stuff the information thatll be used for every record
outputFile.imported.date = TODAY()
outputFile.imported.time = CLOCK()
outputFile.processed = 'N'
! //arm sequential ISAM file scan
SET( inputFile, 1 )
LOOP UNTIL EOF( inputFile )
NEXT( inputFile )
outputFile.id = inputFile.id
outputFile.name = input.name
ADD( outputFile )
END
BEEP( BEEP:SystemExclamation )
MESSAGE( 'File importing completed' )
好吧,这个示例程序只是为了展示应该如何使用程序的不同元素。我没有使用窗口让用户跟踪进度,而是使用了 Clarion 的原语,例如 ADD(),它确实有效,但在循环内部可能会拖累性能。
最好将整个读取封装在使用outputFile{ PROP:SQ } = 'BEGIN TRANSACTION' 打开的事务中,最后发出outputFile{ PROP:SQL } = 'COMMIT'。
是的,通过 PROP:SQL 可以发出服务器接受的任何命令,包括 DROP DATABASE,因此它非常强大。小心使用。
古斯塔沃