Firebird 版本和返回值

Firebird versions and returning value

我正在尝试使用 kinterbasdb 和 Python 2.7 将数据写入服务器上的 Firebird 数据库,并打印添加数据的键值。当我写入数据库的本地副本时,它工作得很好。

insert = """INSERT INTO myTable (myID,DT_TIMESTAMP)
                VALUES (?,?)
                RETURNING myTable_KEY"""
data = ("idTest", datetime.now())
conAdd = kinterbasdb.connect(dsn=nm, user=dbUser, password=dbPass)
cur = conAdd.cursor()
cur.execute(insert, data)
return_key = cur.fetchone()[0]
conAdd.commit()
cur.close()

但是returning这个词导致在网络上访问数据库时出现问题:

ProgrammingError: (-104, 'isc_dsql_prepare: \n  Dynamic SQL Error\n  SQL error code = -104\n  Token unknown - line 3, column 13\n  RETURNING' 

查看Firebird的版本,本机版本为2.0,服务器版本为1.5。我不明白这一点,因为我刚刚将服务器版本复制到本地驱动器进行测试。我正在使用 kinterbasdb,我认为它是数据库的接口,无论它是本地的还是服务器上的。事实证明,v2.0 有 'returning' 字,但 v1.5 没有。我需要我的 Python 代码才能在服务器版本上运行。

我有两个问题:为什么版本不一样?以及如何获取v1.5返回的键值(多个用户同时输入数据)?

RETURNING 子句是在 Firebird 2.0 中引入的。它不能用于早期的 Firebird 版本。另请参阅 Firebird 2 发行说明中的​​ RETURNING Clause for Insert Statements

所以回答你的问题"Why are the versions different?",因为这就是为什么它们是不同的版本:新版本引入了新功能。如果您的意思是 'why do I have a different version locally',那么可能是因为您在本地安装了该版本。请注意(在 Firebird 3 之前),较新的 Firebird 版本可以访问较旧的数据库 files。因此,如果您将数据库 file 从服务器复制到本地,那么您可以使用安装在您机器上的较新版本的 Firebird 访问它。

您真的应该考虑升级到更新的 Firebird 版本。上一个 Firebird 1.5 版本是 8 年前发布的,而 2.0 也已经 5 年没有更新了。从那时起,引入了几项新功能,并修复了错误(包括安全错误)。当前版本是 Firebird 3.0,Firebird 2.5 仍然支持 bug 修复。

另请注意,kinterbasdb 是一个废弃的驱动程序(在其维护者于 2007 年去世后),相反,还有两个其他驱动程序正在积极维护:FDB and pyfirebirdsql.

回答你的第二个问题 "And how can I get the key value returned in v1.5 (multiple simultaneous users will be entering data)?":你需要手动 select 来自生成器的新值并在你的插入语句中显式使用它而不是依赖触发器为您生成它。

另见 How to create an autoincrement column?:

If you use an older version of Firebird, you should first get the value using GEN_ID and then use it in INSERT statement. To read in the generator value, you can use some single-record table like RDB$DATABASE:

select GEN_ID(GEN_T1_ID, 1) from RDB$DATABASE;

为什么本地和服务器上有不同版本的 Firebird 的答案是(来自 Mark Rotteveel)kinterbasd 不是作为嵌入式服务器,但主机上有 Firebird 服务。在某些时候,有人在我的 desktop/local PC 上安装了不同版本的 Firebird 服务。我没有意识到这一点,所以我认为 RETURNING 语句可以在服务器端数据库上工作,因为它在本地工作。

我正在写入的每个 table 都有一个没有毫秒的日期时间戳,我需要从每个条目中获取密钥,因为它在其他 table 中用作外键。我没有研究自动编号生成器(我确定这是 'correct' 解决问题的方法),而是使用 select SQL 语句来 return键:

select="select " + key + " from " + table + " where cast (myTIMESTAMP as timestamp) = '" + myTIMESTAMP.strftime('%m/%d/%Y %H:%M:%S') + "'"

其中 myTIMESTAMP = datetime.now().replace(microsecond=0)

设置在添加数据的insert SQL语句之前。