【问题标题】:How to insert a value that contains an apostrophe (single quote)?如何插入包含撇号(单引号)的值?
【发布时间】:2010-12-27 02:14:52
【问题描述】:

插入带有撇号的值的正确 SQL 语法是什么?

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

我一直收到错误消息,因为我认为 O 之后的撇号是该值的结束标记。

【问题讨论】:

  • 请确认您不会让自己受到 SQL 注入攻击。尽可能使用参数。
  • 您使用什么脚本语言?例如,PHP 中有一些函数可以为您正确执行此操作。
  • 在这里同意 Andrew:我希望这个问题只是关于通过 SQL 客户端或“查询浏览器”等运行 SQL,而不是实际在生产代码中的某个地方。不使用参数化语句是愚蠢的。
  • 它实际上是在代码中。如果我有一个参数化查询,我不需要做同样的事情吗?
  • 否定。根据您使用的数据库和驱动程序,参数的隔离可能会以不同的方式处理,但参数化语句中的参数不需要转义。见en.wikipedia.org/wiki/SQL_injection#Preventing_SQL_injection

标签: sql sql-update sql-insert


【解决方案1】:

在您的 SQL 中转义撇号(即双引号):

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

这同样适用于 SELECT 查询:

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

撇号或单引号是 SQL 中的一个特殊字符,用于指定字符串数据的开头和结尾。这意味着要将其用作文字字符串数据的一部分,您需要 escape 特殊字符。对于单引号,这通常是通过将您的报价加倍来完成的。 (两个单引号字符,不是双引号而不是单引号。)

注意:只有在通过原始 SQL 接口手动编辑数据时才应该担心这个问题,因为在开发和测试之外编写查询应该很少发生。在代码中,有一些技术和框架(取决于您的堆栈)负责转义特殊字符、SQL injection 等。

【讨论】:

  • $linkQuestion = str_replace ("'","''", $linkQuestion);(天哪,这很难读!)
  • 如果数据是 Insert into Person (First, Last) Values 'Joe', 'Father's shop' 会怎样。
  • 正如 vijesh 提到的,如果您必须通过脚本执行此操作,这将无济于事。让我们假设字符串文字不可更改。那么你如何使用它呢?
【解决方案2】:

你只需要在单引号上加倍...

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

【讨论】:

    【解决方案3】:

    您需要转义撇号。在T-SQL 中,这是一个双撇号,因此您的insert 语句变为:

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

    【讨论】:

    • AFAIK Values 必须用大括号括起来(这使得它与@JustinNiessner 的答案相同)
    【解决方案4】:

    因为单引号用于指示字符串的开始和结束;你需要逃避它。

    简短的回答是使用两个单引号 - '' - 以便 SQL 数据库将值存储为 '

    看看使用 REPLACE 来清理传入的值:

    您想检查'''',如果它们存在于字符串中,则将它们替换为'''''',以转义唯一的单引号。

    【讨论】:

      【解决方案5】:

      单引号通过加倍进行转义

      以下 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
      

      【讨论】:

        【解决方案6】:

        eduffy had a good idea。他只是在他的代码示例中把它倒过来了。在 JavaScript 或 SQLite 中,您都可以将撇号替换为重音符号。

        他(我很确定)将重音符号作为字符串的分隔符,而不是替换 O'Brian 中的撇号。对于大多数情况,这实际上是一个非常简单的解决方案。

        【讨论】:

        • 伟大而简单得多的解决方案,我的姓氏是 O`Reilly!
        • 无论如何建议使用转义字符。不小心:) 自从我使用键盘的那一天起。我在编写文档时无意中使用重音符号代替单引号。 (但是在代码中我使用 ' 作为字符标识符)。直到去年有人告诉我他的密码,我无法登录他的系统。直到几个小时我才知道我输入 ' 作为 `。
        【解决方案7】:

        可以通过使用撇号的ASCII table lookup 值39 调用CHAR 函数来插入撇号。然后可以将字符串值与concatenate operator 连接在一起。

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

        【讨论】:

          【解决方案8】:

          另一种转义撇号的方法是写一个字符串文字:

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

          这是一个更好的方法,因为:

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

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

          【讨论】:

          • 这个答案是 Oracle 特定的吗?我在网上找不到任何关于使用 SQL 的信息,而且我使用的这台 PC 不使用 SSMS。有 Microsoft SQL 的链接吗?那么,如何插入 that's what she said ]' etc 呢?方括号的存在,并且可能后跟一个勾号,是否告诉它破坏值?
          • 嗨@Suamere,我使用Oracle,所以我不得不搜索网络以判断这是否是特定的......我确实对这个主题几乎没有发现。 This acticle 建议它特定于 Oracle。但其他供应商可能有不同的方法......
          【解决方案9】:

          这就是我的数据作为 API 响应的样子,我想将其存储在 MYSQL 数据库中。它包含引号、HTML 代码等。

          例子:-

          {
          
          rewardName: "Cabela's eGiftCard $25.00",
          
          shortDescription: '<p>adidas gift cards can be redeemed in over 150 adidas Sport Performance, adidas Originals, or adidas Outlet stores in the US, as well as online at&nbsp;<a href="http://adidas.com/">adidas.com</a>.</p>
          
          terms: '<p>adidas Gift Cards may be redeemed for merchandise on&nbsp;<a href="http://adidas.com/">adidas.com</a>&nbsp;and in adidas Sport Performance, adidas Originals, and adidas Outlet stores in the United States.'
          
          }
          

          解决方案

          CREATE TABLE `brand` (
          `reward_name` varchar(2048),
          `short_description` varchar(2048),
          `terms` varchar(2048),  
          ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
          

          插入时,在后面跟着JSON.stringify()

              let brandDetails= {
              rewardName: JSON.stringify(obj.rewardName),  
              shortDescription: JSON.stringify(obj.shortDescription),
              term: JSON.stringify(obj.term),
               }
          

          上面是 JSON 对象,下面是向 MySQL 插入数据的 SQL Query。

          let query = `INSERT INTO brand (reward_name, short_description, terms) 
          VALUES (${brandDetails.rewardName}, 
          (${brandDetails.shortDescription}, ${brandDetails.terms})`;
          

          成功了……

          【讨论】:

            【解决方案10】:

            在值周围使用双引号。

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

            【讨论】:

            • 请注意,这不再是标准 SQL,尽管我知道 Informix(仅举一个 DBMS 的名称)允许它。您还应该说明如何使用单引号和/或双引号插入字符串,例如 He said, "Don't!" — 可以这样做:'He said, "Don''t!"'"He said, ""Don't!"""。在向具有已接受答案的长期存在的问题添加新答案时,您必须提供新的、完整的信息。使用双引号是新的——但仅限于少数 DBMS;你应该努力找出至少其中一个接受它们的人。
            【解决方案11】:

            改为使用反引号(在 ~ 键上);

            `O'Brien`
            

            【讨论】:

            • 那么问题就变成了:如何插入反引号?
            • 虽然这不是“正确”的答案,但我正在使用一组没有此名称的名称,并且我正在执行一次性操作,因此这立即解决了我的问题。谢谢!
            猜你喜欢
            • 2013-09-26
            • 2011-08-14
            • 1970-01-01
            • 1970-01-01
            • 2011-05-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多