首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >原理从数据库检索时,SQL Server唯一标识符不会转换为char或nvarchar

原理从数据库检索时,SQL Server唯一标识符不会转换为char或nvarchar
EN

Stack Overflow用户
提问于 2010-05-04 13:43:30
回答 2查看 2K关注 0票数 3

当我从数据库中检索一条记录时,Doctrine用"null“而不是数据库中的唯一id来填充它。

一些研究和测试已经将这个问题归结为PDO/dblib驱动程序问题。通过PDO直接查询时,返回null代替唯一id。

作为参考,http://trac.doctrine-project.org/ticket/1096在这方面有一些内容,然而,它在11个月前更新了,没有对解决方案发表评论。

正如在http://bugs.php.net/bug.php?id=24752&edit=1中提到的,解决此问题的一种方法是将列转换为字符。然而,Doctrine似乎并没有在生成模型之外公开原生字段类型,这使得在构建sql查询时检测唯一标识符类型并在内部转换它们变得有点困难。

有没有人找到解决这个问题的办法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-19 15:34:56

我为此提交了一个补丁,在PHP 5.3.7和更高版本中有补丁。有关http://bugs.php.net/54167的详细信息,请参阅此错误报告

从PHP 5.3.7开始,它将以字符串的形式返回唯一标识符,这在Doctrine 1和Doctrine 2中工作得很好。

在我的例子中,我还需要在freetds.conf中指定tds版本,以便正确地接收字符串形式的唯一标识符值。为我工作的tds版本(可能特定于我正在与之通信的SQL server版本)是"tds version = 7.0“。

票数 2
EN

Stack Overflow用户

发布于 2011-11-10 02:17:09

PHP有两个修复,Bug #54167用dblib解决了空问题。不幸的是,当它被合并到PHP中时,另一个bug导致了唯一标识符的另一个问题,这破坏了它们。基本上,它们会丢失低位(用0填充它们,如E3407588-2B77-0000-0200-000000000000)。There is a bug fix,但它要到PHP5.4才会出来。

一般的解决方案是将唯一标识转换为字符串,但Doctrine不处理此问题。Doctrine的一个简单补丁包括将列定义从string(36)更改为guid,然后让Doctrine在Query.php文件中为您进行转换。示例如下:

代码语言:javascript
复制
// In the schema file
columns:
  userid:
    type: guid
    fixed: false
    unsigned: false
    notnull: false
    primary: true
    autoincrement: false

// Which generates this in the base model
$this->hasColumn('userid', 'guid', null, array(
         'type' => 'guid',
         'fixed' => 0,
         'unsigned' => false,
         'notnull' => false,
         'primary' => true,
         'autoincrement' => false,
));

// Only after you change this in Doctrine/DataDict/Mssql.php on line 192-194
case 'uniqueidentifier':
    $type[] = 'guid'; // changed from 'string'
    $length = 36;

// Then to use the new guid datatype, edit Doctrine/Query.php starting on line 487
foreach ($fields as $fieldName) {
        $columnName = $table->getColumnName($fieldName);
        if (($owner = $table->getColumnOwner($columnName)) !== null &&
                $owner !== $table->getComponentName()) {

            $parent = $this->_conn->getTable($owner);
            $columnName = $parent->getColumnName($fieldName);
            $parentAlias = $this->getSqlTableAlias($componentAlias . '.' . $parent->getComponentName());
            $sql[] = $this->_conn->quoteIdentifier($parentAlias) . '.' . $this->_conn->quoteIdentifier($columnName)
                   . ' AS '
                   . $this->_conn->quoteIdentifier($tableAlias . '__' . $columnName);
        } else {
            /* This new code will get the column definition, look for guid, then cast the column as a string to work around PHP bug 60033.  Everything above this line is unchanged */
            $columnName = $table->getColumnName($fieldName);

            $columnDefinition = $table->getColumnDefinition($columnName);

            if ($columnDefinition['type'] == 'guid') {
                $sql[] = 'CAST(' . $this->_conn->quoteIdentifier($tableAlias) . '.' . $this->_conn->quoteIdentifier($columnName) . ' as VARCHAR(36))'
                   . ' AS '
                   . $this->_conn->quoteIdentifier($tableAlias . '__' . $columnName);

            } else {
                    // this block is unchanged from the original
                $sql[] = $this->_conn->quoteIdentifier($tableAlias) . '.' . $this->_conn->quoteIdentifier($columnName)
                   . ' AS '
                   . $this->_conn->quoteIdentifier($tableAlias . '__' . $columnName);
            }
        }
    }

我不确定您是否需要在if语句的第一部分添加相同的代码,但我添加了此代码,现在我的所有唯一标识符都正确返回(较低部分不是零,如E3407588-2B77-0000-0276-3D9E8DE868D6)。也许Doctrine的人会添加这个补丁,因为Doctrine对于SQL Server的唯一标识符对于任何版本的PHP<5.4都是无用的。

我知道不建议手动编辑Doctrine代码,但这是在我尝试从源代码运行PHP5.4 beta2并花费数小时尝试让较新的sqlsrv驱动程序在Doctrine 1.2中工作之后。此外,与使用旧的mssql_query代码重写所有查询相比,这些代码行要容易得多。

希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2763059

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档