我使用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(...)但它不是抽象层的目标。
非常感谢你的帮助。
答案 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
)
我不确定我们是否可以将完全查询作为字符串。