如何插入包含撇号(单引号)的值?

478

如何在SQL语句中插入带撇号的值?

Insert into Person
  (First, Last)
Values
  'Joe',
  'O'Brien'

我一直收到一个错误,因为我认为O后面的撇号是值的结束标记。


24
请确认您没有暴露自己受到 SQL 注入攻击的风险,如有可能请使用参数。 - Andrew
你使用哪种脚本语言?例如,在PHP中有函数可以为您正确执行此操作。 - philfreo
同意Andrew的观点:我希望这个问题只涉及通过SQL客户端或“查询浏览器”等运行SQL,而不是实际上在生产代码中。不使用参数化语句是愚蠢的。 - charstar
这实际上是代码...如果我有一个参数化查询,不是也得做同样的事情吗? - leora
3
不需要转义参数化语句中的参数。具体取决于你使用的数据库和驱动程序,参数的隔离处理可能有所不同。请参考http://en.wikipedia.org/wiki/SQL_injection#Preventing_SQL_injection。 - charstar
PHP:如果带引号的文本数据存储在变量中,比如 $data,则执行以下操作 "$data = str_replace("'","''",$data);"。 - Shine Cardozo
13个回答

710

在SQL中转义单引号(即将单引号字符翻倍):

INSERT INTO Person
    (First, Last)
VALUES
    ('Joe', 'O''Brien')
              /\
          right here  

SELECT查询同样适用:

SELECT First, Last FROM Person WHERE Last = 'O''Brien'

SQL 中的撇号或单引号是一个特殊字符,用于指定字符串数据的开头和结尾。这意味着,如果你想在文本字符串中使用它,你需要转义该特殊字符。对于单引号,通常通过将其加倍实现。(即两个单引号字符,而不是双引号代替单引号。)

注意:只有当您通过原始 SQL 接口手动编辑数据时才需要担心此问题,因为在开发和测试之外编写查询应该是罕见的。在代码中,根据您的技术栈,有一些技术和框架来处理转义特殊字符、SQL 注入等问题。


8
$linkQuestion = str_replace("'", "''", $linkQuestion);这段代码的作用是将字符串变量$linkQuestion中的单引号字符(')替换成两个单引号字符('')。 - user462990
如果将数据插入到Person表中: (First, Last) 值 'Joe', 'Father's shop'。 - vijesh
如果你必须通过脚本来完成这个任务,那么这并没有什么帮助,正如vijesh所提到的。假设字符串字面值是不可改变的,那么你该如何处理它呢? - Jamesckel

60

你只需要在单引号前再加一个单引号...

insert into Person (First, Last)
values ('Joe', 'O''Brien')

38

你需要对撇号进行转义。在T-SQL中,使用双撇号进行转义,因此你的 insert 语句变成:

Insert into Person
(First, Last)
Values
'Joe', 'O''Brien'

1
据我所知,Values 必须用大括号括起来(这样就与 @JustinNiessner 的答案相同)。 - qwerty_so

23

由于单引号用于指示字符串的开始和结束,因此需要对其进行转义。

简单来说,为了使SQL数据库将该值存储为',您需要使用两个单引号-''

考虑使用REPLACE来清理传入的值:

您需要检查字符串中是否存在'''',如果存在,则将它们替换为'''''',以转义孤立的单引号。


18

单引号需要加倍来转义,

下面的 SQL 代码演示了这个功能。

declare @person TABLE (
    [First] nvarchar(200),
    [Last] nvarchar(200)
)

insert into @person 
    (First, Last)
values
    ('Joe', 'O''Brien')

select * from @person

结果

First   | Last
===================
Joe     | O'Brien

8
撇号字符可以通过调用 CHAR 函数并使用撇号的 ASCII表查询 值 39 来插入。然后可以使用 连接运算符 将字符串值连接在一起。
Insert into Person
  (First, Last)
Values
  'Joe',
  concat('O',char(39),'Brien')

6
eduffy提出了一个好主意,但他在代码示例中弄反了。在JavaScript或SQLite中,可以用重音符号替换撇号。
他(我相信是无意的)将重音符号错误地放置为字符串分隔符,而不是替换O'Brian中的撇号。对于大多数情况来说,这实际上是一个非常简单的解决方案。

非常棒且更简单的解决方案,而我的姓氏是O'Reilly! - PhillipOReilly
无论如何,建议使用转义字符。自从我开始使用键盘以来,我在撰写文档时不小心使用了重音符号代替单引号(但在代码中我使用'作为字符标识符)。直到去年有人告诉我他的密码,我无法登录他的系统。我们花了几个小时才发现我在输入时将'误打成了`。 - Learner

2

如果是静态文本,您可以使用两个单引号而不是一个,如下所示:

DEC @text = 'Khabir''s Account'

Khabir后面有两个单引号 ('')

如果您的文本不是静态的,并且是通过存储过程参数传递的,则

REPLACE(@text, '''', '')

2

另一种避免使用撇号的方法是编写字符串文字:

insert into Person (First, Last) values (q'[Joe]', q'[O'Brien]')

这是更好的方法,因为:

  1. 假设您有一个包含数千个名称的Excel列表,想要上传到您的数据库中。您可以简单地创建一个公式,使用单元格内容生成数千个INSERT语句,而不是手动查找撇号。

  2. 它也适用于其他转义字符。例如,将正则表达式模式值加载到表中,即 ^( *)(P|N)?( *)|( *)((<|>)\d\d?)?( *)|( )(((?i)(in|not in)(?-i) ?(('[^']+')(, ?'[^']+'))))?( *)$。


2
这个答案是针对Oracle的吗?我在网上找不到任何关于它与SQL一起使用的信息,而且我正在使用的这台电脑没有使用SSMS。你有Microsoft SQL的链接吗?然后,如何插入 that's what she said ]' etc ?方括号的存在,可能跟着一个单引号,是否告诉它要中断值? - Suamere
嗨@Suamere,我使用Oracle,所以我不得不搜索网络来确定这是否特定于它...实际上我很少找到关于这个主题的信息。这篇文章表明这是Oracle特有的。但对于其他供应商可能会有不同的方法... - Daniel Rust

2

在值的周围使用双引号。

insert into Person (First, Last) Values("Joe","O'Brien")

4
请注意,这不再是标准SQL语法,尽管我知道Informix等某些数据库管理系统允许使用此语法。您还应该解释如何使用单引号和/或双引号插入字符串,例如“He said, “Don’t!””:可以使用'He said, "Don''t!"'"He said, ""Don't!"""。当向已有被接受答案的老问题添加新答案时,您必须提供新的完整信息。使用双引号是一种新方法,但只限于少数几个数据库管理系统;您应该特别指出至少其中一个可接受它们的系统。 - Jonathan Leffler

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