Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么使用like';%查询另一列中实际包含数据的列时会得到结果文本%';_Sql_Blob_Firebird - Fatal编程技术网

Sql 为什么使用like';%查询另一列中实际包含数据的列时会得到结果文本%';

Sql 为什么使用like';%查询另一列中实际包含数据的列时会得到结果文本%';,sql,blob,firebird,Sql,Blob,Firebird,对于Firebird 2.5.8和一个包含十几个blob字段的表,我有这样一种奇怪的查询行为: SELECT * FROM TABLE WHERE BLOBFIELD4 LIKE '%SOMETEXT%' 虽然SOMETEXT实际上在不同的列中,而不是BLOBFIELD4中(发生在每个blob列中),但我得到了结果 我遗漏了什么?谢谢你提供的数据。我使用最新的IB Expert和Firebird 2.5.5(我手头的)进行了一些快速测试 看起来你实际拥有的数据比你想象的要多得多 首先-将

对于Firebird 2.5.8和一个包含十几个blob字段的表,我有这样一种奇怪的查询行为:

SELECT * 
FROM TABLE 
WHERE BLOBFIELD4 LIKE '%SOMETEXT%' 
虽然
SOMETEXT
实际上在不同的列中,而不是
BLOBFIELD4
中(发生在每个blob列中),但我得到了结果


我遗漏了什么?

谢谢你提供的数据。我使用最新的IB ExpertFirebird 2.5.5(我手头的)进行了一些快速测试

看起来你实际拥有的数据比你想象的要多得多

首先-将文本数据保存在标记为
CHARSET NONE
的列中是一种糟糕而危险的做法!确保您的列标记了一些合理的字符集,比如Windows1250或UTF8之类的。而且,您的所有应用程序(包括开发工具)与数据库服务器的连接也有一些明确定义的字符集,适合您的文本数据。

或者,如果您希望这些blob被视为二进制的,那么将它们显式地创建为
SUB_-TYPE binary
not
SUB_-TYPE TEXT

但是,下面是在数据库上运行的简单脚本

alter table comm
add    NF_VC    VARCHAR(4000) CHARACTER SET UTF8,
add    NF_BL    BLOB SUB_TYPE 1 SEGMENT SIZE 4096 CHARACTER SET UTF8
然后

然后

注意,我故意强制Firebird执行转换BLOB->VARCHAR->BLOB。 为了安全起见

现在检查一些数据

 select id_comm, nf_vc
 from comm where
 nf_vc containing 'f4le dans 2 ans'

你现在看到了什么

在第一张图片中,我们看到了一个非常神秘的现象——这条线被选中了,但我们无法在其中看到您的搜索模式“f4le dans 2 ans”。 但是 你能看到标记、双星号和
**
? 是的,一开始你可以!但是你看不到他们的结局!!! 这意味着,你看不到全文,而只是其中的第一部分

在第二张图片上,您看到了非常相同的行ID=854392,但重新转换回BLOB,并在两端额外标记了
@

你能看到起点和终点上的标记吗?
你能看到你的搜索模式吗

是和是-如果您查看网格行(白色)。
否和否-如果查看并显示工具提示(黄色)

所以,同样,你搜索的数据——它确实存在。但你只是因为某种原因看不到它

现在,字符串没有完全显示的典型原因是什么? 它可以是零值字节(或几个字节,UNICODE代码点),这是
C
语言标记行结束的方式,是Windows和许多库和程序中广泛使用的自定义方式。或者其他一些不寻常的值(EOF,EOT,-1,等等),这使得您使用的那些程序错误地检测到文本的结尾,而实际上它还没有结束

再看一下这两个截图,在哪里,线条开始不同了?它在
\viewkind4之后\par}
和之前的
pard
。注意这个奇怪的异常现象!也就是说,
pard
应该以反斜杠开头-
\
-作为一个有效的RTF命令。但它却被一些看不见的东西,一些空白的东西所取代。可能是什么

让我们回到您评论中的原始查询

此外,在评论中加入重要细节也是不好的做法!他们是很难找到有任何人,这是没有跟踪的故事从一开始。而且添加的评论越多,它就变得越难。正确的方法是编辑问题,将新数据添加到问题正文中,然后添加注释(为了通知起见),说明问题已编辑。请以后以这种方式添加新数据

乍一看,我们的钓鱼以零结尾,我们看到的文本没有你的模式,就以
\par}
结尾

但果真如此吗?切换到二进制视图,然后

瞧!在重新找回丢失的pard之前有什么?有一个非常零字节我前面提到过

那么,到底发生了什么,总而言之

  • Firebird是正确的,找到数据是因为数据确实存在于blob中
  • 您读取数据的应用程序不正确。由于与零字节混淆,它们只显示部分数据,而不是全部数据
  • 写入数据的应用程序可能不正确。或者数据本身 那个零字节是怎么结束的?为什么RTF结构损坏,缺少pard前面的反斜杠?插入数据时传递给服务器的数据大小是否比应该的大,是否在有意义的数据之后传递一些垃圾?数据大小是否正确,但插入前数据内容已损坏

    那里有些可疑。我不认为RTF规范明确禁止零字节,但拥有零字节是非常不典型的,因为它会在太多的应用程序和库中触发这样的错误

    另外,表中有许多BLOB类型的列,其设计似乎很差。 “宽”表通常会导致将来的开发和维护出现问题。 虽然这不是您的问题的本质,但请确实考虑将此表重新构建为一个狭窄的表,并将数据保存为多个一块行。
    现在,它将为您提供一些固定的附加工作,但将来可能会使您避免雪球般的问题。

    谢谢您提供的数据。我使用最新的IB ExpertFirebird 2.5.5(我手头的)进行了一些快速测试

    看起来你实际拥有的数据比你想象的要多得多

    首先-将文本数据保存在标记为
    CHARSET NONE
    的列中是一种糟糕而危险的做法!确保您的列标记了一些合理的字符集,比如Windows1250或UTF8之类的。而且,所有应用程序(包括开发工具)与数据库服务器的连接也有一些明确的定义
    update comm
    set nf_bl = '@@' || nf_vc || '@@'
    
     select id_comm, nf_vc
     from comm where
     nf_vc containing 'f4le dans 2 ans'
    
     select id_comm, nf_bl
     from comm where
     nf_bl containing 'f4le dans 2 ans'
    
    select id_comm, COM1
    from comm where
    COM1 containing 'f4le dans 2 ans'