2

这是来自 Oracle SQL 查询。它在数据库中应该有撇号的地方有这些奇怪的细长矩形。(我希望我们可以在这里粘贴屏幕截图)

当我复制并粘贴结果时,它看起来像这样。

spouse�s

有没有办法编写一个 SQL SELECT 语句,在字段中搜索这个字符并在结果中用撇号替换它?

编辑:出于报告目的,我只需要更改 SELECT 语句中的结果,我无法更改数据库。


我跑了这个

从对偶中选择转储('�');

返回

典型值 = 96 长度 = 3:239,191,189

到目前为止,这似乎有效

select translate('What is your partner's first name?', '�', '''') from dual;

但这不起作用

从表名中选择翻译(字段名,'�','''')


从 TN 中选择 FN

你配偶的名字是什么?

从 TN 中选择转储(FN,1016)

Typ=1 Len=33 CharacterSet=US7ASCII: 57,68,61,74,20,69,73,20,79,6f,75,72,20,73,70,6f,75,73,65, 92 , 73,20,66,69,72,73,74,20,6e,61,6d,65,3f


编辑:所以我已经确定这是反引号字符。我无法更新数据库,所以我正在尝试这段代码

从 TN 中选择 REGEX_REPLACE(FN,"\0092","\0027")

我得到 ORA-00904:"Regex_Replace":invalid identifier

4

5 回答 5

6

这似乎是您的字符集配置的问题。检查您的 NLS_LANG 和其他 NLS_xxx 环境/注册表值。您必须检查 oracle 服务器、您的客户端和该数据插入器的客户端。

尝试转储值。你可以用一个简单的选择来做到这一点:

SELECT DUMP(the_column)
  FROM xxx
 WHERE xxx

更新:我认为在尝试更换之前,先寻找问题的根源。如果发生这种情况是因为字符集问题,您可能会遇到糟糕数据的大问题。

更新2:回答评论。问题可能不在数据库服务器端,可能在客户端。问题(如果这是问题)可能是服务器与客户端通信的转换。它用于服务器-客户端错误的配置协调。例如,如果服务器定义了 UTF8 字符集,而您的客户端使用 US7ASCII,那么所有尖音符都将显示为 ?。

另一种方法是,如果服务器定义了 UTF8 字符集,而您的客户端也定义了 UTF8,但应用程序无法显示 UTF8 字符,那么问题出在应用程序端。

更新3:在你的例子中:

  • select translate('What. 之所以有效,是因为 � 是完全相同的字符:您已粘贴在两面。
  • select translate(Fieldname. 它不起作用,因为�没有存储在数据库中,它是客户端收到的字符可能是因为从数据表中发生了一些转换,直到它显示给你。

下一步:查看DUMP语法并尝试提取神秘字符的代码(从未粘贴的表中提取...!)。

于 2009-07-16T21:43:56.597 回答
2

我想说这个角色很有可能是一个单勾“智能引用”(我讨厌这个名字)。智能引号是字符 91-94(使用 Windows 编码)或 Unicode U+2018、U+2019、U+201C 和 U+201D。

于 2009-07-16T21:51:50.310 回答
1

我将提出一种基于前端应用程序的客户端方法来解决该问题:

我怀疑这个问题更多地与您尝试显示单词配偶的字体与字符之间的不匹配有关。当您尝试以没有字符代码字形的 Unicode 字体显示字符时,会出现该图标。

Oracle 数据库将尽职地返回插入到其列中的任何字符。考虑到您尝试在应用程序中显示数据的字体,您和您的应用程序更多地取决于您和您的应用程序来解释它的外观,因此我建议调查一下这个神秘的字符是什么取代了您的撇号。首先使用 FerranB 推荐的 DUMP()。

尝试运行以下查询以获取字符代码:

SELECT DUMP(<column with weird character>, 1016) 
FROM <your table> 
WHERE <column with weird character> like '%spouse%';

如果这不能从数据库中获取您的实际文本,则需要修改 WHERE 子句以实际获取有问题的列。

找到字符的代码后,您可以使用regex_replace()内置函数替换字符,方法是确定字符的原始十六进制代码,然后提供 ASCII / C0 控件和基本拉丁字符 0x0027 ( '),使用与此类似的代码:

UPDATE <table>
    set <column with offending character> 
            = REGEX_REPLACE(<column with offending character>,
                            "<character code of �&gt;",
                            "'")
WHERE regex_like(<column with offending character>,"<character code of �&gt;");

如果您不熟悉 Unicode 和不同的字符编码方式,我建议您阅读 Joel 的文章The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)。直到我读了那篇文章,我才知道。


编辑: 如果你看到0x92,这里可能存在字符集不匹配:

CP-1252(默认 Windows 代码页)中的 0x92 是一个反引号字符,看起来有点像撇号。此代码不是有效的 ASCII 字符,在 IS0-8859-1 中也无效。因此,可能数据库是 CP-1252 编码(不太可能),或者是通过 CP-1252 插入的数据库连接,或者撇号以某种方式转换为 0x92。数据库返回在 CP-1252 中有效的值(或其他 0x92 有效的字符集),但您的 db 客户端连接不期望 CP-1252。因此,奇怪的问号。

FerranB 可能是对的。我会与您的 DBA 或其他管理员讨论此问题,以解决问题。如果你不能,我会尝试进行上面的更新(似乎你不能),或者这样做:

INSERT (<normal table columns>,...,<column with offending character>) INTO <table>
SELECT <all normal columns>, REGEX_REPLACE(<column with offending character>,
                             "\0092",
                             "\0027")  -- for ASCII/ISO-8859-1 apostrophe
FROM <table>
WHERE regex_like(<column with offending character>,"\0092");

DELETE FROM <table> WHERE regex_like(<column with offending character>,"\0092");
于 2009-07-16T21:38:55.657 回答
0

TRANSLATE() 是用于替换或消除已知单字符代码的有用函数。

于 2009-07-17T13:07:19.830 回答
0

在执行此操作之前,您需要了解实际发生的情况。在我看来,有人在数据库中插入了非 ascii 字符串。例如 Unicode 或 UTF-8。在修复此问题之前,请确保这实际上是一个错误。撇号有多种形式,而不仅仅是“'”。

于 2009-07-16T21:43:48.687 回答