gpt4 book ai didi

oracle - 将 Oracle CLOB 字段设置为 null 失败,出现 ORA 22275

转载 作者:行者123 更新时间:2023-12-03 15:59:02 25 4
gpt4 key购买 nike

我们有一个(!)客户将 Oracle CLOB 字段设置为 NULL 失败,并显示

[FireDAC][Phys][Ora] ORA 22275 - Invalid LOB locator specified

发送到数据库的查询*

update tt_hrs set
TT_INFO = ?
where
TT_HRS_ID = ?

Params:
0 - : <NULL>
1 - : 276727

通过 FireDAC 查询数据集显示,字段 TT_HRSlDataset.Fields[i].DataTypeftWideMemo

我在互联网上找到的许多内容都与更新您使用的 CLOBS 的“旧方法”(Oracle 8.0.5 IIRC)相关

UPDATE ClobTable
SET
Value = EMPTY_CLOB()
WHERE
Id = :Id
RETURNING
Value
INTO
:Value

但据我所知,不再需要此类声明。

在 SQLPLUS 中,我可以在我们自己的 Oracle 12c 数据库上毫无问题地执行这些操作,因此 the difference between EMPTY_CLOB() and NULL似乎并不重要:

update tt_hrs set tt_info='test' where tt_hrs_id=276727;
update tt_hrs set tt_info=NULL where tt_hrs_id=276727;
update tt_hrs set tt_info=empty_clob() where tt_hrs_id=276727;
  • 如错误消息所示,我们在 Delphi Tokyo 10.2.2 中使用 FireDAC32 位 Windows 应用。
  • 该字段没有 NOT NULL 约束,它不在索引中,没有触发器。
  • 客户端使用 OracleDB12 第 1 版。
  • 我们的更新代码是由 FireDAC 从 TClientDataSet 生成的连接到用户编辑的网格。

问题:

Oracle 设置中是否有任何内容可以解释此行为?
也许他们设置了一些“兼容模式”来支持旧应用程序之类的...我对 Oracle 不太熟悉。

注意:它绝不会与 2 字节字符 I reported earlier 的问题有关。 ?

在这里捕获救命稻草......

* 我们可以记录这一点,因为我们有一个 TDataSetProvider 后代,它记录在重写的 DoBeforeExecute 中发送的内容。

最佳答案

我们一直无法找到此问题的确切原因,但已找到解决方法。

受影响的代码都通过 TClientDataSet 工作,并且我们已经使用了 TDataSetProvider 后代以及覆盖的 DoBeforeExecute 来记录发送到的实际 SQL数据库(用于调试目的)。这在我们的代码中调用了一个日志记录过程,并且我们添加了以下内容:

// Force parameter to ftOraClob when NULL:
if TFDQuery(TDataSetProvider(Sender).Dataset).Connection.Params.DriverID = S_FD_OraId then
for i := 0 to params.count-1 do
if (params[i].DataType = ftMemo) and (VarIsNull(params[i].Value) or VarIsClear(params[i].Value)) then
params[i].DataType := ftOraClob;

这会强制 Datasnap.Provider.pas 中的 TSQLResolver.GenUpdateSQL 中的 AddField 子例程遵循以下路径:

else if UseFieldInUpdate(Field) then
begin
Result := True;
if (Field.DataType = ftOraClob) and (not InformixLob) then
begin
NoParam := True;
if InObject then
SQL.Add(string.Format(' %s.%s = EMPTY_CLOB(),', [Alias, QuoteFullName(Field.FullName, PSQLInfo(Tree.Data).QuoteChar), { Do not localize }
Field.FullName]))

从而编写 = EMPTY_CLOB() 而不是 = NULL,Oracle DB 乐意接受。

注意:我们测试 ftMemo 因为我们有一个活跃的映射规则,上面写着

with AConnection.FormatOptions.MapRules.Add do 
begin
SourceDataType := dtWideHMemo;
TargetDataType := dtMemo;
end;

(参见 https://stackoverflow.com/a/47904988/512728 )
如果您没有这个,则需要测试 ftWideMemo

关于oracle - 将 Oracle CLOB 字段设置为 null 失败,出现 ORA 22275,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52061416/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com