2

我在没有 ORM 的情况下独立使用 DBAL,因为我不需要它。但是,我现在在查询中使用 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 日期时间,因为我的日期是分时的,它会为 oracle 完美处理的函数添加太多额外代码。

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

非常感谢你的帮助。

4

2 回答 2

1

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

Doctrine(或 PDO 的价值)将简单地将字符串绑定SEQ_JOURNAL.NEXTVALLGM_ID列。

据我所知,你有两种方法来处理这个问题。

第一种方法

先增加序列的值,得到:

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

在插入语句中使用检索到的 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,可以将列的默认值设置为当前日期。

于 2014-01-30T16:25:48.993 回答
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  
)  

我不确定我们能否将确切的查询作为字符串获取。

于 2013-04-12T11:45:09.853 回答