AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 197324
Accepted
Gonzalo Vasquez
Gonzalo Vasquez
Asked: 2018-02-08 11:35:38 +0800 CST2018-02-08 11:35:38 +0800 CST 2018-02-08 11:35:38 +0800 CST

ERRO: "sql " não é uma variável conhecida

  • 772

Esta deve ser uma das perguntas mais idiotas que já fiz aqui, mas deve haver algo realmente doente escondido no meu script SQL que está bloqueando sua execução.

Estou invocando o arquivo cobertura.sql usando a seguinte sintaxe de amostra da CLI:

psql -h localhost -U myUser -f cobertura.sql myDB

Mas reclama com o seguinte erro:

psql:cobertura.sql:29: ERROR:  "sql " is not a known variable
LINE 14: sql := format('insert into cobertura_tmp select count(*) as ... cobertura.sql file:
DO language plpgsql $$
declare 
    eq  record;
    sql varchar;
BEGIN

create table if not exists cobertura_tmp  (num integer, realtime char(1), lat numeric, lng numeric);

truncate table cobertura_tmp;
for eq in select imei_equipo as imei  from cliente_avl_equipo where id_cliente in (select id from cliente where nombre ilike '%enangab%') limit 3

loop

sql := format('insert into cobertura_tmp select count(*) as num, tipo as realtime, round(CAST(latitud as numeric), 4) as lat ,round(CAST(longitud as numeric), 4) as lng   from reports.avl_historico_%s where latitud between -38.67405472 and -36.75131149 and longitud between  -73.08429161 and -69.65333954 group by tipo, round(CAST(latitud as numeric), 4),round(CAST(longitud as numeric), 4)', eq.imei);

execute sql;

end loop;

update cobertura_tmp set num= -1* num where realtime='S';

create table if not exists cobertura_tmp_resumen  (num integer, lat numeric, lng numeric);
truncate cobertura_tmp_resumen;
--    select sum(num) as num , lat, lng into cobertura_tmp_resumen from cobertura_tmp group by lat,lng;

--    drop table if exists cobertura_tmp;

END;
$$;

O mesmo script é executado remotamente e sem problemas no Mac OSX usando o Postico Versão 1.3.2 (2318).

PERGUNTA: Por que não está encontrando a sqlvariável que está na declareseção?

postgresql postgresql-9.4
  • 1 1 respostas
  • 5786 Views

1 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2018-02-08T16:38:18+08:002018-02-08T16:38:18+08:00

    Sua mensagem de erro diz:

    psql:cobertura.sql:29: ERROR:  "sql " is not a known variable
    LINE 14: sql := format('insert into cobertura_tmp select count(*) as ...
    

    Olhe atentamente: "sql ", não"sql"

    Isso significa que você tem um caractere furtivo e invisível logo após "sql" em vez de um caractere de espaço inocente. Não está na sua pergunta, provavelmente se perdeu na tradução quando você copiou e colou na sua pergunta aqui. Seu código original contém algo como:

    sql := format ...
    

    Você vê? Não? Porque não se pode ver . (Você pode notar que o espaço é um pouco maior neste caso particular - se seu navegador, fonte e conjunto de caracteres produzirem o mesmo resultado que o meu.) É um "espaço ideográfico" , Unicode U+3000, HTML &#12288. Apenas um exemplo aleatório. Existem vários caracteres como esse em Unicode. Substitua-o por um espaço simples para corrigir seu problema.

    dbfiddle aqui

    Eu odeio isso sobre Unicode, muitos caracteres que principalmente confundem as pessoas ...

    Para um teste rápido:

    SELECT ascii(' ');   -- 32    -- plain space
    SELECT ascii(' ');  -- 12288 -- not a plain space
    SELECT ' ' = ' ';   -- f     -- not the same!
    

    Um teste rápido se há caracteres não ASCII em uma string:

    SELECT octet_length(string) = char_length(string)  -- f
    FROM  (SELECT text 'sql := format' AS string) t;
    

    Assumindo a codificação UTF8, os caracteres não ASCII ocupam 2-4 bytes, enquanto os caracteres ASCII simples ocupam um único byte. octet_length()retorna o

    Número de bytes na string

    enquanto char_length()(igual a length()) retorna o número de caracteres . Para all-ASCII, ambos retornam o mesmo. Se octet_length()retornar um número maior, você tem caracteres suspeitos. Não precisa significar nada. Qualquer caractere acentuado em uma string é bom para isso.

    Ou use um editor que possa destacar suspeitos.


    Além disso, enquanto estiver nisso, seu código plpgsql seria consideravelmente mais eficiente assim:

    DO
    $$
    DECLARE
       _imei text;
       _sql  text;
    BEGIN
    
    IF to_regclass('pg_temp.cobertura_tmp') IS NULL  -- if tmp table does not exist
    THEN
       CREATE TABLE cobertura_tmp (
          num      integer
        , realtime char(1)
        , lat      numeric
        , lng      numeric
        );
    ELSE
       TRUNCATE TABLE cobertura_tmp;
    END IF;
    
    FOR _imei IN
       SELECT e.imei_equipo::text  -- imei is NOT NULL & *safe* against SQL injection
       FROM   cliente c
       JOIN   cliente_avl_equipo e ON e.id_cliente = c.id  -- assuming c.id is UNIQUE
       WHERE  c.nombre ILIKE '%enangab%'
       LIMIT  3
    LOOP
       _sql := format(
       $s$
       INSERT INTO cobertura_tmp (num, realtime, lat, lng)
       SELECT count(*)::int * (CASE WHEN a.tipo = 'S' THEN -1 ELSE 1 END) -- AS num
            , a.tipo                         -- AS realtime
            , round(a.latitud::numeric, 4)   -- AS lat
            , round(a.longitud::numeric, 4)  -- AS lon
       FROM   reports.avl_historico_%s a
       WHERE  a.latitud  BETWEEN -38.67405472 AND -36.75131149
       AND    a.longitud BETWEEN -73.08429161 AND -69.65333954
       GROUP  BY 2,3,4
       $s$
     , _imei);
    
       EXECUTE _sql;
    END LOOP;
    
    /* integrated above to avoid costly extra update:
    UPDATE cobertura_tmp
    SET    num = -1 * num
    WHERE  realtime = 'S';
    */
    
    -- ... etc
    
    END
    $$;
    

    Muitos pequenos detalhes, mas esse não é o tema da pergunta . Duvido que você precise de uma tabela temporária ...

    Experimente se quiser melhorar o código. Relacionado:

    • Como verificar se uma tabela existe em um determinado esquema
    • Inserir texto com aspas simples no PostgreSQL
    • 8

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve