我有一个实体Marks包含float中的“Result”:
/**
* @var float
*
* @ORM\Column(name="RESULT", type="float", nullable=false)
*/
private $result;
以下是
形式的列->add('result', 'choice', array(
'choices' => array(
'1' => '1.0',
'1.5' => '1.5',
'2' => '2.0',
'2.5' => '2.5',
'3' => '3.0',
'3.5' => '3.5',
'4' => '4.0',
'4.5' => '4.5',
'5' => '5.0',
'5.5' => '5.5',
'6' => '6.0'
),
'label' => 'Result',
))
我尽量不在数组中加引号,但它什么都没改变。
当我尝试添加带小数的标记(例如5.5)时,我收到以下错误:
An exception occurred while executing 'INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE) VALUES (?, ?, ?, ?, ?, ?)' with params [2, 97, "3.5", "27", "2", "2"]:
所以我尝试将setter更改为
/**
* Set result
*
* @param float $result
* @return ApprenticeMark
*/
public function setResult($result)
{
$this->result = floatval($result);
return $this;
}
但是我在3.5
上没有引号就得到了同样的错误An exception occurred while executing 'INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE) VALUES (?, ?, ?, ?, ?, ?)' with params [2, 97, 3.5, "27", "2", "2"]:
这是控制器部分:
$mark = new ApprenticeMark();
$form = $this->createForm(new ApprenticeMarkType(), $mark);
$request = $this->get('request');
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
$m->persist($mark);
$m->flush();
return $this->redirect($this->generateUrl('grids_apprentice_index',array('idApprentice' => $apprentice->getId())));
}
}
问题不是来自我的Oracle数据库,我在Oracle SQL Developer上运行没有错误:
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE) VALUES ('1', '101', 5.5, '27', '2', '2');
你知道如何解决这个问题吗?
此致
答案 0 :(得分:0)
这并没有解决避免PHP / Doctrine2 /等问题的最佳方法。堆栈,它只是试图证明数据库端发生了什么。
小数分隔符由会话的NLS_NUMERIC_CHARACTERS
setting确定。由于您的错误消息是法语,因此我假设您的NLS_TERRITORY
为FRANCE
,默认小数字符为,
,字符为.
您可以验证特定会议:
select value from nls_session_parameters
where parameter = 'NLS_NUMERIC_CHARACTERS';
当您使用字符串文字代替数字值时,将完成隐式to_char()
转换,并且NLS设置会影响字符串的解释方式。如果您的字符串值具有句点,但您的NLS设置需要逗号,则会出错:
alter session set nls_territory = 'UNITED KINGDOM';
session SET altered.
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', '5.5', '27', '2', '2');
1 rows inserted.
alter session set nls_territory = 'FRANCE';
session SET altered.
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', '5.5', '27', '2', '2');
Error starting at line : 28 in command -
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', '5.5', '27', '2', '2')
Error report -
SQL Error: ORA-01722: invalid number
01722. 00000 - "invalid number"
当然,让他们与其他方式错误不匹配:
alter session set nls_territory = 'UNITED KINGDOM';
session SET altered.
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', '5,5', '27', '2', '2');
Error starting at line : 48 in command -
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', '5,5', '27', '2', '2')
Error report -
SQL Error: ORA-01722: invalid number
01722. 00000 - "invalid number"
alter session set nls_territory = 'FRANCE';
session SET altered.
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', '5,5', '27', '2', '2');
1 rows inserted.
如果您插入数字而不是字符串,那么无论您的NLS设置如何,您都必须使用句点,因为逗号始终是值分隔符:
alter session set nls_territory = 'UNITED KINGDOM';
session SET altered.
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', 5.5, '27', '2', '2');
1 rows inserted.
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', 5,5, '27', '2', '2');
Error starting at line : 67 in command -
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', 5,5, '27', '2', '2')
Error at Command Line : 67 Column : 13
Error report -
SQL Error: ORA-00913: too many values
00913. 00000 - "too many values"
和
alter session set nls_territory = 'FRANCE';
session SET altered.
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', 5.5, '27', '2', '2');
1 rows inserted.
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', 5,5, '27', '2', '2');
Error starting at line : 77 in command -
INSERT INTO APPRENTICE_MARK (COEFFICIENT, ID, RESULT, FK_BRANCH, FK_YEAR, FK_MARKTYPE)
VALUES ('1', '101', 5,5, '27', '2', '2')
Error at Command Line : 77 Column : 13
Error report -
SQL Error: ORA-00913: too many values
00913. 00000 - "too many values"
回到你的PHP插入。即使您5.5
为float
,也会获得ORA-01722值。因此,它仍然必须作为字符串传递给Oracle,并且会话的NLS参数导致混淆。当您通过'5,5'
而不是它正在工作时,因为您的会话期待逗号。
假设您尚未(在)PHP堆栈中的某处设置NLS参数,Oracle将以某种方式继承您的操作系统的语言环境;你在一台讲法语的机器上运行(我假设)所以你必须使用逗号作为十进制分隔符。但是,在英语机器上运行完全相同代码的人现在会得到该错误,除非逗号被更改回句点。所以你要避免这个问题,而不是解决它。
理想情况下,您传递一个普通数字,因此数据库中不需要转换。目前尚不清楚为什么没有发生这种情况。您的查询具有绑定变量(来自VALUES (?, ?, ?, ?, ?, ?)
),因此似乎绑定是使用字符串完成的。即使你将它设置为浮点数,当Oracle看到它时它仍然是一个字符串。我不知道为什么 - 我对PHP知之甚少 - 但我会看看如何设置变量,也许可以深入研究Doctrine2如何处理绑定变量。您可以从PHP显式设置NLS,因此无论您的机器区域设置如何,它都是一致的。拥有更多PHP知识的人必须帮助您找到可持续的修复或解决方法......