Sql select语句中文本内有单引号时出错

Sql select语句中文本内有单引号时出错,sql,database,postgresql,postgresql-9.3,Sql,Database,Postgresql,Postgresql 9.3,使用Postgresql 9.3获取错误: select 'hjhjjjhjh'mnmnmnm'mn' 错误: 错误:“'mn'”中或旁边的语法错误 SQL状态:42601 人物:26 我尝试将文本中的单引号替换为: select REGEXP_REPLACE('hjhjjjhjh'mnmnmnm'mn', '\\''+', '''', 'g') 及 但它没有起作用 以下是真实代码: CREATE OR REPLACE FUNCTION generate_mallet_input2() RE

使用Postgresql 9.3获取错误:

select 'hjhjjjhjh'mnmnmnm'mn'
错误:

错误:“'mn'”中或旁边的语法错误
SQL状态:42601
人物:26

我尝试将文本中的单引号替换为:

select REGEXP_REPLACE('hjhjjjhjh'mnmnmnm'mn', '\\''+', '''', 'g')

但它没有起作用

以下是真实代码:

CREATE OR REPLACE FUNCTION generate_mallet_input2() RETURNS VOID AS $$ 
DECLARE 
sch name;
r record;   
BEGIN

    FOR sch IN 
     select schema_name from information_schema.schemata where schema_name not in ('test','summary','public','pg_toast','pg_temp_1','pg_toast_temp_1','pg_catalog','information_schema') 
    LOOP 

         FOR r IN EXECUTE 'SELECT rp.id as id,g.classified as classif, concat(rp.summary,rp.description,string_agg(c.message, ''. '')) as mess
            FROM ' || sch || '.report rp
            INNER JOIN ' || sch || '.report_comment rc ON rp.id=rc.report_id
            INNER JOIN ' || sch || '.comment c ON rc.comments_generatedid=c.generatedid 
            INNER JOIN ' || sch || '.gold_set g ON rp.id=g.key
            WHERE g.classified = any (values(''BUG''),(''IMPROVEMENT''),(''REFACTORING''))
            GROUP BY g.classified,rp.summary,rp.description,rp.id'
         LOOP

            IF r.classif = 'BUG' THEN
                EXECUTE format('Copy( select REPLACE(''%s'', '''', '''''''') as m ) To ''/tmp/csv-temp/BUG/'|| quote_ident(sch) || '-' || r.id::text || '.txt ''',r.mess);
            ELSIF r.classif = 'IMPROVEMENT' THEN
                EXECUTE format('Copy( select REPLACE(''%s'', '''', '''''''') as m ) To ''/tmp/csv-temp/IMPROVEMENT/'|| quote_ident(sch) || '-' || r.id || '.txt '' ',r.mess);
            ELSIF r.classif = 'REFACTORING' THEN
                EXECUTE format('Copy( select REPLACE(''%s'', '''', '''''''') as m ) To ''/tmp/csv-temp/REFACTORING/'|| quote_ident(sch) || '-' || r.id || '.txt '' ',r.mess);
            END IF;             

         END LOOP;



    END LOOP; 
    RETURN; 

END;
$$ LANGUAGE plpgsql STRICT; 

select * FROM generate_mallet_input2();
错误:

埃罗:你是一个“邮递员”
LINHA 1:…e.http.impl.conn.SingleClientConnManager$HTTPCLIENT-803)。
新的SSLSocketFactory.connectSocket方法使用InetSocketAddress.getHostName()参数调用X509HostnameVerifier。当选定的IP地址具有反向查找名称时,将使用解析的名称调用验证器,因此IP检查失败。
4.0版本检查了原始IP/主机名,但这无法使用新的connectSocket()方法完成
TestHostnameVerifier.java只检查127.0.0.1/.2,因此掩盖了问题,因为匹配的证书既有“localhost”又有“127.0.0.1”,但实际上只匹配了“localhost”。使用8.8.8.8的测试用例会更好。对于不需要反向DNS查找的问题,我承诺了一个稍微好一点的解决方法。

Oleg。为了解决这个问题,我不得不求助于一个相当丑陋的黑客。更好的解决方案需要更改X509HostnameVerifier API。我觉得不支持X509HostnameVerifier接口,因为在证书中使用CN的IP地址本身就是一种黑客行为。


请查看。

。即使是第二个,也需要服务器提供可信证书。我看不出这两种情况有什么不同。。错误的测试。尝试连接到。证书的CN=93.62.162.60,但已对93-62-162-60.ip23.fastwebnet.it进行检查。嗯,我的评论不是为了恢复补丁。第一个场景已经可以利用,现在仍然可以利用。您的补丁是“正确”的解决方案,不会破坏API。

但是为了避免任何安全问题(包括已经存在的问题),必须更改API。。我无法重现这个问题。到远程对等方的SSL连接通过默认主机名验证。

--
正在执行requestGET HTTP/1.1
[DEBUG]SingleClientConnManager-获取路由HttpRoute[{s}->]
[DEBUG]DefaultClientConnectionOperator-连接到
[DEBUG]RequestAddCookies-Cookies选定:最佳匹配
[DEBUG]DefaultHttpClient-尝试1执行请求
[DEBUG]DefaultClientConnection-发送请求:GET/HTTP/1.1
[DEBUG]头->>GET/HTTP/1.1
[DEBUG]头->>主机:
[DEBUG]头->>连接:保持活动状态
[DEBUG]头->>用户代理:Apache HttpClient/4.1(java 1.5)
[DEBUG]DefaultClientConnection-接收响应:HTTP/1.1 200 OK
[DEBUG]头-您需要转义引用的
标记:

select 'hjhjjjhjh''mnmnmnm''mn'

您需要转义引用的
标记:

select 'hjhjjjhjh''mnmnmnm''mn'
需要转义的不是字符串的内容,而是它在发送到服务器的SQL中的表示形式

为了表示一个
,您需要用SQL语法编写两个:
。因此,
'IMSoP's answer'
表示字符串
IMSoP's answer
'
表示
'
,而
'
表示
'

但关键的是,在尝试运行SQL之前,您需要这样做。您不能将无效的SQL命令粘贴到查询窗口中并告诉它自行修复

所以,转义的自动化完全取决于您如何创建那个SQL。根据您更新的问题,我们现在知道您正在使用pl/pgsql创建SQL语句,其格式为
format()
调用:

format('Copy( select REPLACE(''%s'', '''', '''''''') as m ) To ''/tmp/csv-temp/BUG/'|| quote_ident(sch) || '-' || r.id::text || '.txt ''',r.mess)
让我们稍微简化一下,使示例更清晰:

format('select REPLACE(''%s'', '''', '''''''') as m', r.mess)
如果
r.mess
foo
,则结果如下:

select REPLACE('foo', '', ''''') as m
这个替换没有任何用处,因为第一个参数是空字符串,第二个参数中有3个
'
标记;但是,即使您固定了
标记的数量,它也不会起作用。如果
r.mess
的值改为
bad'stuff
,则会得到以下结果:

select REPLACE('bad'stuff', '', ''''') as m
这是无效的SQL;无论您尝试在何处运行它,它都不会起作用,因为Postgres认为
'bad'
是一个字符串,而接下来的
内容是无效语法

想一想如果
r.mess
sqlinjection'),它会是什么样子;删除表格用户--

select REPLACE('SQL injection'); DROP TABLE users; --', '', ''''') as m
现在我们有了有效的SQL,但它可能不是您想要的

因此,您需要做的是在将
r.mess
混合到字符串中之前,转义
中的标记:

format('select '%s' as m', REPLACE(r.mess, '''', ''''''))
现在,我们正在将
坏东西
更改为
坏东西
,然后再将其放入SQL,并以以下方式结束:

select 'bad''stuff' as m
这就是我们想要的

但实际上有一些更好的方法可以做到这一点:

%L
修饰符用于,它输出转义和带引号的字符串文字:

format('select %L as m', r.mess)
使用而不是
replace()
,并像对待文件名一样将字符串连接在一起:

'select ' || quote_literal(r.mess) || ' as m'
最后,如果函数看起来真的像你问题中的函数,你可以通过根本不使用循环来避免整个问题;只需使用适当的
WHERE
子句将每组行复制到文件中:

 EXECUTE 'Copy
     SELECT concat(rp.summary,rp.description,string_agg(c.message, ''. '')) as mess
        FROM ' || sch || '.report rp
        INNER JOIN ' || sch || '.report_comment rc ON rp.id=rc.report_id
        INNER JOIN ' || sch || '.comment c ON rc.comments_generatedid=c.generatedid 
        INNER JOIN ' || sch || '.gold_set g ON rp.id=g.key
        WHERE g.classified = ''BUG'' -- <-- Note changed WHERE clause
        GROUP BY g.classified,rp.summary,rp.description,rp.id
) To ''/tmp/csv-temp/BUG/'|| quote_ident(sch) || '-' || r.id::text || '.txt '''
';
EXECUTE'复制
选择concat(rp.summary,rp.description,string_agg(c.message,“.”)作为mess
从“| | sch | |”开始。报告rp
内部连接“| | sch | |”.report|u comment rc ON rp.id=rc.report|u id
内部联接“| | sch | |”。在rc上注释c。注释_generateId=c.generateId
内部连接“| | sch | |”。rp.id上的黄金集g=g.key
其中g.classified=''BUG'-需要转义的不是字符串的内容,而是它在发送到服务器的SQL中的表示形式

为了代表一个单一的
'This'is'a'test'
'This''is''a''test'
CREATE Table test( testfield varchar(30));
INSERT INTO test VALUES ('''This''is''a''test''');
SELECT 
  '''' || REPLACE(Substring(testfield FROM 2 FOR LENGTH(testfield) - 2),'''', '''''') || '''' 
FROM Test;