【问题标题】:SQL Server varchar(MAX) datatype in delphi using RemObjectsDelphi中使用RemObjects的SQL Server varchar(MAX)数据类型
【发布时间】:2013-11-12 13:03:08
【问题描述】:

收到了更改应用程序中评论字段最大大小的请求。之前将其设置为 varchar(500),因此在阅读文档后我决定将字段的数据类型从 varchar(500) 更改为 varchar(max )。数据库接受更改没有任何问题(使用 Microsoft SQL Server Management Studio 2005 和 Microsoft SQL Server Management Studio 2008 进行数据库管理)。 然后我继续更换软件。软件是用 Delphi 编写的,带有 RemObjects 以与数据库通信。所以我更改了服务器的 TDASchema,它将我的新 varchar(max) 字段映射为 String(65536) 数据类型(给我一个有点担心这样一个明确的静态大小,但我继续说)。然后我为我的 TDAMemDataTable 对象检索了 DataTable Schema,它更新了所有字段。

我启动了应用程序并决定查看我的数据库是否会接受对这个特定更改字段的更改。我编辑了其中一条记录并单击按钮以将 DataSet 与服务器同步并收到这样的失败消息:

数据类型varchar(max)和text在equal to operator中不兼容

我将其解释为我的服务器对象(将数据库字段与 RemObjects 对象映射的对象)已将字段数据类型映射到 RemObjects 中的错误数据类型。

如何解决?有哪些替代方案?

附:在此版本中,来自 RemObjects 的 Build .1267 日志明确指出:

已修复:DataSnap:无法将更新发布到 MSSQL 2005 VARCHAR(MAX)

我正在使用构建版本 .1067。不知道更新是否会解决问题

附言更新到最新版本的 RemObjects 后,问题依然存在。

【问题讨论】:

    标签: sql-server database delphi remobjects


    【解决方案1】:

    此错误消息通常发生在尝试使用相等运算符比较 varchar(n) 和文本时(通常在 sql 中的 where 子句中,但可能在其他地方)。 MSDN 上有一篇文章涵盖了可能与此相关的几点。

    当您将数据存储到 VARCHAR(N) 列时,这些值的物理存储方式相同。但是,当您将其存储到 VARCHAR(MAX) 列时,屏幕后面的数据将作为 TEXT 值处理。所以在处理 VARCHAR(MAX) 值时需要一些额外的处理。 (仅当大小超过 8000 时)

    您提到 TDASchema 已将您的新字段映射为 String(65536),尽管之前从未使用过 RemObjects,但我会假设它自己的代码(或您的代码)中的某处正在尝试进行某种比较,因此错误信息。

    尝试使用 VARCHAR(8000) 代替 MAX,看看是否能解决问题。

    如果您可以在代码中找到执行此相等性检查的位置,另一个选项是尝试执行cast()

    【讨论】:

    • 我同意你提出的错误原因,比较发生在库中的某个地方(也许当某些触发器将单元格的旧条目与新条目进行比较时,其中一个是文本,另一个是 varchar)使用 VARCHAR(8000) 的问题是它将在数据库中分配大量空间,我不希望发生这种情况,其中 MAX 属性准确分配存储特定 varchar 所需的空间。
    • 是的,这是个问题。如果你能找出什么样的 cmets 将进入这个领域,你至少可以猜测一下并将尺寸缩小到一个可观的水平。
    • 或者也许某种异常处理程序会捕获异常并手动转换值?在此之前从未使用过 remobjects 是我唯一的想法。
    • 感谢您的想法,但我宁愿等待使用过 RemObjects 并且可能遇到类似问题的人,或者如果我做错了什么可以指出我的方向
    【解决方案2】:

    正如您所怀疑的,我认为您的问题的根源在于字段没有作为正确的类型进入 TDASchema。我刚刚在这里尝试过,varchar(max) 和 nvarchar(max) 字段分别作为 Memo 和 WideMemo 进入我的架构,而不是 String(65536)。

    我通过 FireDAC 使用 Delphi XE6 和 SQL Server 2008 R2。

    这表明从数据库中检索元数据时出现问题。您使用的是什么数据库驱动程序?您可以尝试 FireDAC(如果可用)或其他驱动程序来查看问题是否仍然存在?

    【讨论】:

      【解决方案3】:

      Delphi 7 和 MS SQL Server 2008 R2 (SP2) 的解决方案

      德尔福:

          with TADOStoredProc.Create(Self) do
          try
            Connection := AConnection;
            ProcedureName := ASPName;
            Parameters.Refresh;
            Parameters.ParamByName('@XML').Value := AXML;
            try
              ExecProc;
      ...
      

      MS SQL 服务器:

      ALTER PROCEDURE dbo.StoredProcName
          @XML        NVARCHAR(MAX)
         ,@ErrMsgOut  NVARCHAR(MAX) = NULL OUT
      AS BEGIN
      SET NOCOUNT ON
      DECLARE @RETURN INT = 0
             ,@idoc   INT
      
      BEGIN TRY
          -- Prepare XML
          DECLARE @XML_TEXT VARCHAR(MAX)
          SET @XML_TEXT = CONVERT(VARCHAR(MAX), @XML) 
          EXEC sp_xml_preparedocument @idoc OUTPUT, @XML_TEXT
      
          -- Open XML
          SELECT  *
          FROM    OPENXML (@idoc, '/ServicesList/ServicesItem', 2)
          WITH
          (
              YourFields AndTypes
          )
      ...
      

      【讨论】:

        猜你喜欢
        • 2011-11-24
        • 1970-01-01
        • 2020-08-25
        • 1970-01-01
        • 1970-01-01
        • 2013-08-27
        • 1970-01-01
        • 1970-01-01
        • 2021-03-22
        相关资源
        最近更新 更多