插入包含新行和引号的文本列的条目时出错

Posted

技术标签:

【中文标题】插入包含新行和引号的文本列的条目时出错【英文标题】:Error Inserting Entry With Text Column That Contains New Line And Quotes 【发布时间】:2012-05-07 13:09:00 【问题描述】:

我有一个 Informix 11.70 数据库。我无法在表上成功执行此插入语句。

INSERT INTO some_table(
    col1,
    col2,
    text_col,
    col3) 
VALUES(
    5, 
    50, 
    CAST('"id","title1","title2"
"row1","some data","some other data"
"row2","some data","some other"' AS TEXT), 
    3);

我收到的错误是:

[错误代码:-9634,SQL 状态:IX000] 没有从字符转换为文本。

我发现我应该添加这个语句以便允许在文本文字中使用新行,所以我在我已经编写的同一个查询上方添加了这个:

EXECUTE PROCEDURE IFX_ALLOW_NEWLINE('t');

仍然,我收到同样的错误。

我还阅读了 IBM 文档,其中说:要允许换行,我可以在 ONCONFIG 文件中设置 ALLOW_NEWLINE 参数。我想最后一个需要对服务器的管理访问权限来更改我没有的配置文件,我不想利用这个设置。

【问题讨论】:

【参考方案1】:

Informix 的 TEXT(和 BYTE)列早于任何标准,并且在许多方面都是非常特殊的类型。 Informix 中的 TEXT 与其他 DBMS 中的 TEXT 非常不同。其中一个长期存在(超过 20 年)的问题是没有可用于向其中插入数据的字符串文字表示法。 'No cast from char to text' 是说没有从字符串文字到 TEXT 的显式转换。

您有多种选择:

在表中使用 LVARCHAR(如果您的值不会超过几 KiB,这很好,因为总行长度约为 32 KiB)。 LVARCHAR 列的最大大小略低于 32 KiB。 使用可以处理 Informix“定位器”结构的编程语言 - 在 ESQL/C 中,用于保存 TEXT 的类型是 loc_t。 考虑改用 CLOB。但是,这具有相同的限制(没有字符串到 CLOB 转换),但是您可以使用 FILETOCLOB() 函数将信息从客户端上的文件获取到数据库(并且 LOTOFILE 从DB 到客户端上的文件)。

如果您可以使用 LVARCHAR,那是迄今为止最简单的替代方法。

【讨论】:

感谢您的回复。不幸的是,用于与数据库通信的是 Java,还有一个 ORM(尤其是 Hibernate)。因此,我担心我无法利用 loc_t 定位器结构。至于 LVARCHAR 类型,它看起来与 MS SQL Server 的 NVARCHAR 具有大致相同的限制,还是我错了?如果不是,我担心我们的文本列会包含超过 4096 个字符的字符串(如果使用 UTF-8)。 LVARCHAR 默认为 2048 字节,但最多可以达到 32 KiB。但整行长度也有 32 KiB 的限制。 BYTE、TEXT、BLOB 和 CLOB 在行中存储一个固定大小(56 字节或 64 字节)的描述符,数据存储在其他地方。 LVARCHAR 存储在行中。你需要多大?您使用的是哪个 JDBC 驱动程序? Informix 驱动程序(与 Java 通用客户端或 JDBC 的 JCC 版本相反)应该可以很好地处理 BYTE、TEXT,但可能不像所示的 SQL 那样作为字符串文字。 我假设您在没有 CAST 的情况下尝试过但它失败了?人们通常不会在遇到问题之前添加 CAST,但以防万一…… 我们正在使用 IBM 的 Informix 驱动程序。存储的大部分数据是大型 CSV 数据,从用户上传的文件中读取。该应用程序已经被编写为使用 PostgreSQL,因此没有直接从数据库服务器读取文件。我们的任务是迁移同一个应用程序以使用 Informix。而且,是的,我尝试使用 CAST 失败。 你也可以尝试使用PreparedStatement。它适用于 JDBC 和 TEXT 列。请参阅我的问题:***.com/questions/483284/…【参考方案2】:

我忘记提及问题中的一个重要细节 - 我使用 Java 和 Hibernate ORM 来访问我的 Informix 数据库,因此 Jonathan Leffler's answer 中的一些建议方法(特别是 loc_t 处理)很遗憾不适用.另外,我需要存储动态长度的大数据,我担心LVARCHAR 列不足以容纳它。

我的工作方式是遵循Michał Niklas 的建议from his comment,并使用PreparedStatement。这可以通过 Informix 以自己的方式处理 TEXT 数据类型来解释。

【讨论】:

以上是关于插入包含新行和引号的文本列的条目时出错的主要内容,如果未能解决你的问题,请参考以下文章

尝试更新包含聚合函数(计数)的选择案例语句时出错

如何插入包含单引号的字符串

java中使用mysql批量插入大文本(二进制)数据时出错

在存储过程中将 varchar 转换为数字时出错

SQL Server存储过程插入长字符串时出错:字符串后引号未闭合

通过包过程插入带有可变数组列的表时出错