【问题标题】:PHP script is truncating text field to 4096 characters when connecting to SQL Server 2005 & 2016 via ODBC / FreeTDS通过 ODBC / FreeTDS 连接到 SQL Server 2005 和 2016 时,PHP 脚本将文本字段截断为 4096 个字符
【发布时间】:2019-09-19 15:45:59
【问题描述】:

我正在使用 FreeTDS / ODBC 从 CentOS7 使用 PHP 连接到 SQLServer2005 数据库。它运行良好,除了一个字段——一个大的“注释”文本字段被截断为 4096 个字符。如何让我的 PHP odbc_exec 查询检索整个文本字段?

我正在将数据库从 SQLServer2005 迁移到 SQLServer2016,但文本字段截断问题似乎在两者上的行为方式相同。

我尝试在查询本身中设置文本大小:

SET TEXTSIZE 2147483647; SELECT note FROM soap WHERE organizationId=41 and patientId=2019 AND noteId=189

我已经使用我的 odbc/freetds 设置在 isql 中测试了上述连接和查询,它似乎可以正确检索整个文本字段。这是我的 freetds.log 的部分输出:

17:30:50.367355 29543 (token.c:1542):tds7_get_data_info:
        colname = note
        type = 35 (text)
        server's type = 35 (text)
        column_varint_size = 4
        column_size = 2147483647 (2147483647 on server)

我已尝试在 odbc.ini 文件中设置文本大小:

[ClaimsServiceNewTest]
Driver                  = /usr/lib64/libtdsodbc.so.0
Description             = Advanced Billing Service Database (TESTING OLD SQL)
Trace                   = Yes
TraceFile               =/tmp/sql.log
ForceTrace              = Yes
SERVERNAME              = ClaimsServiceNewTest
User                    = ********
Password                = ********
Database                = ********
Port                    = 1433
TDS_Version             = 7.1
TextSize                = 2147483647

我还在 freetds.conf 文件中设置了文本大小:

 # If you get out-of-memory errors, it may mean that your client
        # is trying to allocate a huge buffer for a TEXT field.
        # Try setting 'text size' to a more reasonable limit
        text size = 4294967295 

只有当我尝试在我的 PHP 脚本中运行查询时,它才会被截断。

有什么建议吗?我对这一切都很陌生,所以如果我遗漏了一些明显的东西,请告诉我。我还注意到 isql 正在将 TDSDUMP 输出到我的 freetds.log 文件,但我的 PHP 查询不是——我不知道这是否是预期的行为,但如果您对从我的 PHP 查询输出 TDSDUMP 有建议,我想它会有额外的有用信息。

感谢您的考虑!

编辑:Mark Thomas 的一个很好的建议是更改 php.ini 中的 mssql.textlimitmssql.textsize。我已经在 php.ini 文件中更改了它(并且还在脚本中使用:ini_set('mssql.textlimit', 10000000); 进行了更改,但我看不出它有什么不同(在更改 php.ini 后重新启动 apache 就足够了,对吧?)。

【问题讨论】:

  • 不相关,但您可能需要考虑升级到受支持的 sql server 版本。
  • 谢谢——你提醒我提到,作为迁移的一部分,我实际上要将数据库迁移到 SQL Server Management Studio v17.9.1。我在 17.9.1 中有一个测试数据库设置,它似乎正在工作,但我还没有在迁移的那部分触发。连接到新的 17.9.1 数据库时,文本截断问题的行为相同。
  • 呃... SQL Server Management Studio 根本不是数据库服务器:-?无论如何,您可能想尝试odbc_binmode(..., ODBC_BINMODE_RETURN)。这解决了我在使用另一个 DBMS (Oracle) 时的问题。
  • 哈,我已经太久了——新数据库是 SQL Server 2016 (13.0.5081.1)。我刚刚尝试了您的 odbc_binmode 建议,并没有立即得到好的结果(到目前为止它似乎返回了 '1'),但我很欣赏这个建议,我会进一步探索它。
  • 我似乎记得必须将该字段转换为 varchar(max)。尝试使用cast( varchar(max), note ) as note 代替查询中的注释。

标签: php sql-server freetds unixodbc


【解决方案1】:

感谢Mark Thomas' answer,我能够(最终)找到解决方案。在php.ini中,需要将ODBC对LONG字段的处理从默认的odbc.defaultlrl = 4096改成更高的值——我用的是odbc.defaultlrl = 2000000

问题解决了!

再次感谢所有帮助并为我指明正确的方向。

【讨论】:

    【解决方案2】:

    我对 PHP 有点生疏,但我认为在连接到某些数据类型(如您的示例中)时可以发挥默认限制。

    这里之前的帖子讨论了它,并提供了一个解决方案,通过检查 php.ini 文件中 mssql 文本文件大小的默认值可能会有所帮助:mssql_fetch_object text character limit?

    【讨论】:

    • 感谢您的建议!我已经更改了我的 php.ini 文件中的 mssql.textlimitmssql.textsize 值,以及带有 ini_set 的脚本中的值,但到目前为止还没有骰子。
    猜你喜欢
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 2022-10-07
    • 1970-01-01
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多