Doctrine DBAL和Oracle关键字

时间:2013-04-11 15:01:05

标签: php oracle doctrine-orm dbal

我使用DBAL作为独立而没有ORM,因为我不需要它。但是我现在在查询中使用oracle关键字时遇到了一些问题。 例如,我有以下代码:

$journal = array(
    'LGM_ID'        => 'SEQ_JOURNAL.NEXTVAL',
    'LGM_USER_LOGIN'    => "a user",
    'LGM_DATE'      => 'CURRENT_TIMESTAMP'
);
$db->insert('JOURNAL', $journal);

这不起作用,我收到以下错误:

ORA-01722: invalid number

我认为这是因为序列的使用。用整数替换数组中的第一项后,我有以下错误:

ORA-01858: a non-numeric character was found where a numeric was expected

这次我认为这是因为CURRENT_TIMESTAMP关键字。

我认为在结束时传递查询关键字转换为字符串并且它不起作用。有没有办法使用序列或其他关键字而不使用ORM等额外的东西?

对于序列我认为我可以在获得nextval之前运行另一个请求。 但是,对于CURRENT_TIMESTAMP,我真的不想使用php Datetime,因为我的日期是按时间划分的,它会为oracle完美处理的函数添加太多额外的代码。

我的最后一个解决方案是将完整查询编写为字符串并使用$ db-> query(...)但它不是抽象层的目标。

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:1)

我不确定CURRENT_TIMESTAMP的行为如何,但我确定的是序列的字符串会产生错误。

Doctrine(或PDO代表它的价值)只会将字符串SEQ_JOURNAL.NEXTVAL绑定到LGM_ID列。

据我所知,您有两种方法可以解决这个问题。

第一种方法

首先增加序列的值并获取它:

$id = (int) $db->fetchColumn('SELECT SEQ_JOURNAL.NEXTVAL FROM dual');

在insert语句中使用检索到的ID:

$journal = array(
    'LGM_ID' => $id,
    'LGM_USER_LOGIN' => "a user",
    'LGM_DATE' => 'CURRENT_TIMESTAMP'
);

$db->insert('JOURNAL', $journal);

这种方法的缺点是它涉及两个查询。

第二种方法

这个是基于预备语句,而不是DBAL的快捷方式(insert()是DBAL的真实预处理语句的快捷方式,executeUpdate()):

$db->executeUpdate("
    INSERT INTO JOURNAL (
        LGM_ID,
        LGM_USER_LOGIN,
        LGM_DATE
    ) VALUES (
        SEQ_JOURNAL.NEXTVAL,
        :userLogin,
        CURRENT_TIMESTAMP
    )
", array(
    :userLogin => 'a user',
));

在我看来它比第一个好,你可以使用CURRENT_TIMESTAMP函数(我不确定第一个用例)。

如果要以不同方式处理CURRENT_TIMESTAMP,可以将列的默认值设置为当前日期。

答案 1 :(得分:0)

我正在回答最后一条评论,因为我无法按照自己的意愿格式化新评论。

我可以用DBAL记录的所有内容是:请求和参数:

INSERT INTO JOURNAL (LGM_TYPE, LGM_SUBTYPE, LGM_OBJECT_ID, LGM_OBJECT_TABLE, LGM_DATA, LGM_ID, LGM_USER_LOGIN, LGM_DATE) VALUES (?, ?, ?, ?, ?, ?, ?, ?)  

Array  
(  
    [0] => 3  
    [1] => 0  
    [2] => 245  
    [3] => ENTITY  
    [4] => Deletion of specific entity  
    [5] => 1  
    [6] => user  
    [7] => CURRENT_TIMESTAMP  
)  

我不确定我们是否可以将完全查询作为字符串。