VARCHAR字段固定为255个字符

时间:2017-04-10 19:29:00

标签: php sql-server freetds

我使用的是PHP,SQL Server 2012和FreeTDS。在TDS版本= 7.4的情况下,我的所有VARCHAR字段都被截断为255个字符。

我已经读过,这种情况发生在小于7.0的TDS版本中,因此不适用于此配置。

当我们使用TDS版本7.1时,这工作正常,但我们的托管服务提供商似乎已经改变了一些东西(仍在努力解决这个问题),现在我们因某些原因无法连接7.1。

以下是tsql -C的输出:

Compile-time settings (established with the "configure" script)
                            Version: freetds v1.00.27
             freetds.conf directory: /usr/local/etc
     MS db-lib source compatibility: no
        Sybase binary compatibility: no
                      Thread safety: yes
                      iconv library: yes
                        TDS version: auto
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: no
                            OpenSSL: yes
                             GnuTLS: no
                               MARS: no

这是我的freetds.conf:

[global]
    tds version = 7.4
    text size = 2147483647

[my-server-name]
    host = my-server-name
    port = 1433
    tds version = 7.4
    instance = my-db-instance

我使用与mssql_*相同的值通过PHP(使用旧的my-server-name函数)进行连接。我已经通过将tds version更改为7.1来验证它正在使用该配置,但连接不起作用。

我之前使用的是freetds v0.91,我下载了最新的稳定版本,并按照其网站上的构建说明进行了更新,但它没有帮助解决问题。

此代码库中有大量的表,查询,存储过程和函数,因此更新对这些VARCHAR字段的所有调用以使用类似CAST(column AS TEXT)的内容不是一种选择。

为我显示问题的示例代码如下:

<?php
$conn = mssql_connect('my-server-name', 'my-username', 'my-password');
mssql_select_db('my-database', $conn);
$result = mssql_query("SELECT longFieldName FROM myTable");
while ($row = mssql_fetch_array($result, MSSQL_ASSOC)) {
    var_dump($row);
}

这是从一个创建为:

的表中提取的
CREATE TABLE myTable (longFieldName VARCHAR(2000));
INSERT INTO myTable (longFieldName) VALUES ('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.');

当我运行PHP代码时,我希望转储完整的字符串,而是输出以下字符串:

array(1) {
  'longFieldName' =>
  string(255) "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor i"
}

是什么导致这些字段被截断为255个字符?

编辑:

看起来这可能是PHP特有的。我尝试使用tsql进行连接,然后我完成了查询并获得了完整的字符串。我使用的是PHP 5.5.15(cli),我使用以下配置设置了xdebug:

[xdebug]
zend_extension="/usr/local/lib/xdebug.so"
xdebug.var_display_max_children = -1
xdebug.var_display_max_data = -1
xdebug.var_display_max_depth = -1
xdebug.remote_port = 9000
xdebug.remote_enable = 1
xdebug.remote_connect_back = 1

以下MSSQL配置:

[MSSQL]
mssql.allow_persistent = On
mssql.max_persistent = -1
mssql.max_links = -1
mssql.min_error_severity = 10
mssql.min_message_severity = 10
mssql.compatability_mode = Off
mssql.connect_timeout = 5
mssql.timeout = 6000000000
mssql.textsize = 2147483647
mssql.secure_connection = Off

更新

我没有看到7.0版本的这个问题。总结每个版本会发生什么:

  • 7.0:能够连接和varchar字段未截断,但不支持64位整数。
  • 7.1:无法连接(which is a separate issue)。当我们过去能够连接时,我们没有截断问题。
  • 7.2及以上:能够连接,但varchar字段被截断。

1 个答案:

答案 0 :(得分:1)

我相信我已经找到了截断问题。

当我尝试更新我的FreeTDS版本时,我实际安装了FreeTDS的第二个版本,这就是tsql -C使用的版本。但是当我通过在我的freetds.conf中设置dump file = /tmp/freetds.log然后运行测试并查看日志来启用日志记录时,第一行说:

Starting log file for FreeTDS 0.91

所以PHP实际上使用FreeTDS版本0.91。根据{{​​3}},0.91仅支持TDS版本7.2。

因此,当我指定7.3或7.4时,我认为它是默认为旧版本,由日志文件中较低的另一行确认:

Connecting to 172.19.4.129 port 1433 (TDS version 4.2)

所以这就是截断问题的原因。我必须更新PHP正在使用的FreeTDS版本。