Firebird数据库异常及常用操作

一、运行时异常,raised exception class EIB_ISCError with message 'ISC ERROR CODE:335544375

ISC ERROR MESSAGE:

unavailable database'.

异常原因:Firebird server服务没启动。

嵌入式版Firebird数据库介绍参考:http://www.firebirdsql.org/manual/ufb-cs-embedded.html

二、创建数据库异常:

Error

SQL error code = -104

Token unknown - line 1, column 68

value>

原来语句中的“vlaue”与关键字有冲突,所以执行出错,修改字段名问题即得到解决,类似这样的关键字还在有no、value、level、position等。

题外话,这个问题,只在Firebird时才出现;在Oracle或者mysql上都测试过不会出现。另外在创建Firebird库时,一定要选用UNICODE_FSS,可以避免一些不必要的麻烦。

三、多线程使用IBObjects问题。

在子线程中使用IBObjects时,一定要单独创建,即不能使用主线程的IBObjects控件,否则会报各种AV异常!

在子线程中创建IBObjects控件时(注意是创建而不是使用),一定要先创建TIB_Session对象(主线程中没有此要求),然后再创建TIBOQuery和TIB_Connection对象,然后使TIB_Session对象作为后两个对象的Owner,否则使用的时候会报AV(Access violation)异常,如下所示创建:

    TIB_Session* session = new TIB_Session(NULL);
    TIBOQuery* qry = new TIBOQuery(session);
    TIB_Connection* conn = new TIB_Connection(session);
    conn->Username = "SYSDBA";
    conn->Password = "masterkey";
    conn->IB_Session = session;
    conn->Connected = false;
    conn->DatabaseName = databaseName;

    conn->Connected = true;

    qry->IB_Connection = conn;
    qry->SQL->Text = sql;

    qry->Open();

     ........

而且,释放对象时一定要按照如下顺序:

delete qry;

delete conn;

delete session;

否则会报EInvalidPointer with message Invalid pointer operation异常。

参考:http://tech.dir.groups.yahoo.com/group/IBObjects/message/41931



三、firebird 不支持top函数名,替换为first函数名

错误:select top 1 * from aq_jlinfo order by filedt desc

正确:select first 1 * from aq_jlinfo order by filedt desc


四. 联合查询
    firebird 的联合查询的子查询中不支持order by,所以如果需要order by, 则需要用 select * from 包装一下;
    而且Firebird不支持查询语句第一个字符就是括号, 例如:

select * from (select ... from tableA order by field desc ) union all select * from tableB


五、查询某个表的字段信息

SELECT RF.RDB$FIELD_NAME AS
FieldName,
T.RDB$TYPE_NAME AS DataType,
F.RDB$FIELD_LENGTH AS
FieldLength,
RF.RDB$NULL_FLAG AS AllowNulls,
CS.RDB$DEFAULT_COLLATE_NAME
AS CharacterSet,
RF.RDB$DEFAULT_SOURCE AS
Defaultvalue,
F.RDB$COMPUTED_SOURCE AS
ComputedSource,
F.RDB$FIELD_SUB_TYPE AS SubType,
F.RDB$FIELD_PRECISION
AS FieldPrecision
FROM RDB$RELATION_FIELDS RF
LEFT JOIN RDB$FIELDS F ON
(F.RDB$FIELD_NAME = RF.RDB$FIELD_SOURCE)
LEFT JOIN RDB$TYPES T ON
(T.RDB$TYPE = F.RDB$FIELD_TYPE)
LEFT JOIN RDB$CHARACTER_SETS CS ON
(CS.RDB$CHARACTER_SET_ID = F.RDB$CHARACTER_SET_ID)
WHERE RF.RDB$RELATION_NAME
= '你的表名' AND
T.RDB$FIELD_NAME = 'RDB$FIELD_TYPE'
ORDER BY
RF.RDB$FIELD_POSITION;

四、查询函数

1.查询头几行记录

mssql: select top 10 * from table1
firebird:select first 10 * from table1
IB:select * from table rows 10

2.count函数

sql = select count(*) from BIZ_ProcessResult

ACCESS:int cnt = Query->FieldByName("Expr1000")->AsInteger;

firebird : int cnt = Query->FieldByName("COUNT")->AsInteger;


参考:http://blog.csdn.net/salc3k/article/details/6918216

http://blog.csdn.net/farce/article/details/5315810

五、级联操作

主从表可以通过外键进行级联更新、删除,比如:

ALTER TABLE AQ_JLINFO ADD
JLID Varchar(40) primary key;

ALTER TABLE AQ_SAFEOPINION ADD
JLID Varchar(40) REFERENCES AQ_JLINFO(JLID) ON UPDATE CASCADE ON DELETE CASCADE;

参考:http://stackoverflow.com/questions/20641368/firebird-trigger-before-delete

六、unsupposed on-disk structure for file “D:\xxx\xx.fdb”   found 32779,support 13

这是由于创建火鸟数据库文件的程序与使用此数据库文件的程序使用的不是同一个版本的fbclient.dll造成的(FlameRobin使用的是Firebird服务程序下的fbclient.dll),把创建此数据库的程序使用的fbclient.dll替换为Firebird服务程序下的fbclient.dll,比如把Firebird服务程序下的fbclient.dll复制到创建数据库的exe目录下,然后在工程中如下设置:

String __fastcall GetClientLibNameFunc()
{
    String appPath = ExtractFilePath(Application->ExeName);
    return appPath + "fbclient.dll";
//    return appPath + "fbembed.dll";//嵌入式版本
}

WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    Ib_session::IB_GetClientLibNameFunc = GetClientLibNameFunc;

    ...
    return 0;
}

参考:http://www.firebirdfaq.org/faq80/

Firebird版本和文件结构的对应关系参考: http://www.ibase.ru/devinfo/prevver.htm


七、Master - Detail with TIBOQuery

Yes, you can achieve that:

In the master query, you should have a field whose name will be passed as
parameter to the detail query. For example:

In the master TIBOQuery: SELECT CODE, NAME FROM MASTER_TABLE
In the detail: SELECT A, B, C FROM DETAIL_TABLE WHERE MASTER_CODE = :CODE

Add a DataSource and set the DataSet To the Master TIBOQuery
In the detail Query, Set the Datasource to the one you just created.

That's it.

参考:http://www.codenewsfast.com/cnf/article/0/permalink.art-ng2076q25547

你可能感兴趣的:(Firebird数据库异常及常用操作)