如何在SQL中替换字符串中的字符?

14

我们的数据库中有数百个单元格包含 ?,而不是 '。可能会在所有行和列以及每个单元格多个单词中发生此情况。以下是仅一个单元格的示例。

Parents? CUI assumed equal to the sum of the father?s/stepfather?s and mother?s/ stepmother?s income .

我想编写一个SQL语句,找到所有包含?(单元格中可能有多个)的单元格,并用'替换它们。我确定所有的?都必须被替换,没有例外。

我知道有一个replace函数,但我不知道如何在SQL中从一个字符串中提取一个字符。

这是我找到的一个示例,但它对我没有帮助。

UPDATE dbo.authors

SET    city = replace(city, 'Salt', 'Olympic')
WHERE  city LIKE 'Salt%';

有什么想法吗?


你想把 ? 更新为 '' 吗?'' 是一个空字符串,在 Oracle 中与 null 相同。 - Ben
可能是如何替换Oracle数据库列中的特定值?的重复问题。 - Vadzim
4个回答

16
UPDATE databaseName.tableName
SET columnName = replace(columnName, '?', '''')
WHERE columnName LIKE '%?%'

16
你确定存储在数据库中的数据确实是问号吗?从示例数据中,我倾向于怀疑问题是字符集转换的问题,在客户端字符集无法表示字符时,使用“?”作为替换字符。可能,数据库实际上存储的是Microsoft的“智能引号”字符,而不是简单的撇号。
DUMP函数显示数据库中实际存储的内容是什么?
SELECT column_name,
       dump(column_name,1016)
  FROM your_table
 WHERE <<predicate that returns just the sample data you posted>>

您使用的是哪个应用程序来查看数据?客户端的 NLS_LANG 设置是什么?

数据库和国家字符集是什么?数据存储在 VARCHAR2 列中还是 NVARCHAR2 列中?

SELECT parameter, value
  FROM v$nls_parameters
 WHERE parameter LIKE '%CHARACTERSET';

如果所有的问题字符都以0x19(十进制25)的形式存储在数据库中,那么你的REPLACE应该是这样的:

UPDATE table_name
   SET column1 = REPLACE(column1, chr(25), q'[']'),
       column2 = REPLACE(column2, chr(25), q'[']'),
       ...
       columnN = REPLACE(columnN, chr(25), q'[']')
 WHERE INSTR(column1,chr(25)) > 0
    OR INSTR(column2,chr(25)) > 0 
    ...
    OR INSTR(columnN,chr(25)) > 0

可能是这样。我会去看看的。虽然我不知道NLS_LANG是什么。数据存储为VARCHAR2。 - WowBow
@Justin..我发现在数据库中,这个字符甚至都看不见...它是空格。通过在列名上运行转储方法,我找到了这个 .>> Typ=1 Len=38 CharacterSet=US7ASCII: 53,74,75,64,65,6e,74,19,73,20,53,53,4e,20,6d,61,74,63,68,2c,20,62,75,74,20,6e,6f,20,6e,61,6d,65,20,6d,61,74,63,68. 这是什么意思?当它被显示时,它甚至不是问号,而是一些奇怪的字符。该字符包含类似于0019的内容。 - WowBow
@WowBow - 这个“DUMP”是对应于你发布的样本数据(“父母?CUI被假定等于父亲/继父和母亲/继母收入之和。”)吗?这两者似乎不匹配。 - Justin Cave
@WowBow - 好的,那就更有意义了。这些有问题的字符总是0x19吗? - Justin Cave
在我的浏览器上,它看起来像00 19(但它看起来像一张图片)。而且是在任何地方都一样。 - WowBow
显示剩余6条评论

8
这将用 ' 替换所有的 ?:
UPDATE dbo.authors    
SET    city = replace(city, '?', '''')
WHERE city LIKE '%?%'

如果你需要更新不止一个列,你可以每次执行时更改city为不同的列名,或者像下面这样列出所有要更新的列:

UPDATE dbo.authors    
SET    city = replace(city, '?', '''')
      ,columnA = replace(columnA, '?', '''')
WHERE city LIKE '%?%'
OR columnA LIKE '%?%'

我们不需要一个where子句吗? - WowBow
@MatX - where子句只会过滤行,因此它只会检查需要更新的行。唯一的优点是性能,但这是一个值得考虑的点。我会将其添加到查询中。 - Curtis
哦...如果我要更新多个列怎么办...也就是说,我会有多个SET语句。在这种情况下,我应该如何编写where子句,因为我正在处理多个列? - WowBow
@MatX - 我已经更新了我的回答。不过最好先检查一下Justin所说的,确保你的数据实际上包含“?”。 - Curtis

1
使用REPLACE函数。
例如:SELECT REPLACE('t?es?t', '?', 'w'); 来源

1
另外两个答案说的是相同的事情。 - Jon Heller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接