Doctrine2 ORA-01722:Nombre non valide

时间:2014-02-12 13:04:51

标签: php sql oracle symfony doctrine-orm

我有一个实体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');

你知道如何解决这个问题吗?

此致

1 个答案:

答案 0 :(得分:0)

这并没有解决避免PHP / Doctrine2 /等问题的最佳方法。堆栈,它只是试图证明数据库端发生了什么。

小数分隔符由会话的NLS_NUMERIC_CHARACTERS setting确定。由于您的错误消息是法语,因此我假设您的NLS_TERRITORYFRANCE,默认小数字符为,,字符为.您可以验证特定会议:

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.5float,也会获得ORA-01722值。因此,它仍然必须作为字符串传递给Oracle,并且会话的NLS参数导致混淆。当您通过'5,5'而不是它正在工作时,因为您的会话期待逗号。

假设您尚未(在)PHP堆栈中的某处设置NLS参数,Oracle将以某种方式继承您的操作系统的语言环境;你在一台讲法语的机器上运行(我假设)所以你必须使用逗号作为十进制分隔符。但是,在英语机器上运行完全相同代码的人现在会得到该错误,除非逗号被更改回句点。所以你要避免这个问题,而不是解决它。

理想情况下,您传递一个普通数字,因此数据库中不需要转换。目前尚不清楚为什么没有发生这种情况。您的查询具有绑定变量(来自VALUES (?, ?, ?, ?, ?, ?)),因此似乎绑定是使用字符串完成的。即使你将它设置为浮点数,当Oracle看到它时它仍然是一个字符串。我不知道为什么 - 我对PHP知之甚少 - 但我会看看如何设置变量,也许可以深入研究Doctrine2如何处理绑定变量。您可以从PHP显式设置NLS,因此无论您的机器区域设置如何,它都是一致的。拥有更多PHP知识的人必须帮助您找到可持续的修复或解决方法......