Clipper On Line • Ver Tópico - Dúvida inserir data no MySql
Página 1 de 2

Dúvida inserir data no MySql

MensagemEnviado: 13 Ago 2017 10:56
por porter
olá pessoal,
Estou tentando inserir dados na tabela CLIENTES, mas se o usuário não informar a data de nascimento, quero gravar o campo
com uma variável vazia mas ocorre um erro e o MySql não está aceitando, como ficaria o comando abaixo, pois no insert não
tenho como verificar se a variavel esta vazia ou não.

dtnascimento = ""
string sql = "INSERT INTO CLIENTES (CLI_NASCEU) VALUES (dtnascimento);

Obrigado.

Dúvida inserir data no MySql

MensagemEnviado: 13 Ago 2017 23:52
por JoséQuintas
FUNCTION DateSql( dDate )

   LOCAL cString

   cString := StrZero( Year( dDate ), 4 ) + "-" + StrZero( Month( dDate ), 2 ) + "-" + StrZero( Day( dDate ), 2 )
   IF cString == "0000-00-00"
      cString := "NULL"
   ELSE
      cString := StringSql( cString )
   ENDIF

   RETURN cString

Dúvida inserir data no MySql

MensagemEnviado: 14 Ago 2017 07:19
por ANDRIL
Sem precisar mexer no fonte, ajuste o campo na sua tabela para ter o valor padrão caso não venha no INSERT, tipo 0000:00:00 (se for DATE) ou 0000:00:00 00:00:00 (se for DATETIME).
Exemplo:

ALTER TABLE `city` CHANGE `DatadoDia` `CountryCode` DATETIME CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '0000:00:00 00:00:00';


Até+

Dúvida inserir data no MySql

MensagemEnviado: 14 Ago 2017 12:07
por JoséQuintas
Lembrando que data zerada não é padrão em SQL.
Se o MySQL estiver com STRICT MODE ativado também não aceita data zerada.
O padrão pra qualquer campo sem nada é NULL, que equivaleria ao NIL do Clipper/Harbour.

Dúvida inserir data no MySql

MensagemEnviado: 14 Ago 2017 13:23
por porter
Sem precisar mexer no fonte, ajuste o campo na sua tabela para ter o valor padrão caso não venha no INSERT, tipo 0000:00:00 (se for DATE) ou 0000:00:00 00:00:00 (se for DATETIME).
Exemplo:

ALTER TABLE `city` CHANGE `DatadoDia` `CountryCode` DATETIME CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '0000:00:00 00:00:00';


Lembrando que data zerada não é padrão em SQL.
Se o MySQL estiver com STRICT MODE ativado também não aceita data zerada.
O padrão pra qualquer campo sem nada é NULL, que equivaleria ao NIL do Clipper/Harbour.


Gravar "NULL" no campo Date, não está dando certo.

Assim da certo
INSERT INTO CLIENTES(IDCLI_COD,CLI_NOME,CLI_NASCEU) VALUES (2000,"JOAO","0000:00:00");
Assim da erro
INSERT INTO CLIENTES(IDCLI_COD,CLI_NOME,CLI_NASCEU) VALUES (2000,"JOAO","NULL");

ERROR 1292 (22007): Incorrect date value: 'NULL' form column 'CLI_NASCEU' at row 1

DESCRIBE CLIENTES;
Field Type Null Default
CLI_NASCEU Date YES NULL

Dúvida inserir data no MySql

MensagemEnviado: 14 Ago 2017 13:58
por JoséQuintas
Não é "NULL", é NULL

A função pode ser usada na montagem do comando, por isso retorna como texto.

"INSERT INTO CLIENTES(IDCLI_COD,CLI_NOME,CLI_NASCEU) VALUES (2000,"JOAO"," + DateSql( mCli_Nasceu ) + ")"

Mas pra facilitar "enxergar" os comandos, acabei criando uma função/classe.

:QueryCreate()
:QueryAdd( "IDCLI_COD", nCodigo )
:QueryAdd( "CLI_NOME", cNome )
:QueryAdd( "CLI_NASCEU", dData )
:QueryExecuteInsert( "CLIENTES" )


Até que acaba meio parecido com REPLACE cCampo WITH xConteudo
Mas facilita enxergar os "pares" de variável e conteúdo.
O mesmo pra UPDATE.

Dúvida inserir data no MySql

MensagemEnviado: 14 Ago 2017 14:07
por JoséQuintas
Se interessar, a montagem de INSERT e UPDATE a partir do array aqui:

[url]https://github.com/JoseQuintas/JoseQuintas/blob/master/source/ze_adoclass.prg#L566,#L606[/url]

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 07:51
por Itamar M. Lins Jr.
Ola!
Esta função nova para data que o Przemek criou facilita mais ainda.
cString := StrZero( Year( dDate ), 4 ) + "-" + StrZero( Month( dDate ), 2 ) + "-" + StrZero( Day( dDate ), 2 )

Mude para:
 cString :=hb_dtoc(dDate,"yyyy-mm-dd") 
Um picture para datas!

  * harbour/source/rtl/dateshb.c
    + added new .prg functions to mange date and timestamp values:
      HB_DATETIME() -> <tTimeStamp>
      HB_CTOD( <cDate> [, <cDateFormat> ] ) -> <dDate>
      HB_DTOC( <dDate> [, <cDateFormat> ] ) -> <cDate>
      HB_NTOT( <nValue> ) -> <tTimeStamp>
      HB_TTON( <tTimeStamp> ) -> <nValue>
      HB_TTOC( <tTimeStamp>, [ <cDateFormat> ] [, <cTimeFormat> ] ) ->
                                                            <cTimeStamp>
      HB_CTOT( <cTimeStamp>, [ <cDateFormat> ] [, <cTimeFormat> ] ) ->
                                                            <tTimeStamp>
      HB_TTOS( <tTimeStamp> ) -> <cYYYYMMDDHHMMSSFFF>
      HB_STOT( <cDateTime> ) -> <tTimeStamp>
         <cDateTime> should be in one of the above form:
            - "YYYYMMDDHHMMSSFFF"
            - "YYYYMMDDHHMMSSFF"
            - "YYYYMMDDHHMMSSF"
            - "YYYYMMDDHHMMSS"
            - "YYYYMMDDHHMM"
            - "YYYYMMDDHH"
            - "YYYYMMDD"
            - "HHMMSSFFF"
            - "HHMMSSF"
            - "HHMMSS"
            - "HHMM"
            - "HH"
         Important is number of digits.
      HB_TSTOSTR( <tTimeStamp> [, <lShorten> ] ) -> <cTimeStamp> // YYYY-MM-DD HH:MM:SS.fff
      HB_STRTOTS( <cTimeStamp> ) -> <tTimeStamp>
         <cTimeStamp> should be in one of the above form:
            YYYY-MM-DD [H[H][:M[M][:S[S][.f[f[f[f]]]]]]] [PM|AM]
            YYYY-MM-DDT[H[H][:M[M][:S[S][.f[f[f[f]]]]]]] [PM|AM]
         The folowing characters can be used as date delimiters: "-", "/", "."
         T - is literal "T" - it's for XML timestamp format
         if PM or AM is used HH is in range < 1 : 12 > otherwise
         in range < 0 : 23 >
      HB_HOUR( <tTimeStamp> ) -> <nHour>
      HB_MINUTE( <tTimeStamp> ) -> <nMinute>
      HB_SEC( <tTimeStamp> ) -> <nSeconds>   // with milliseconds

  * harbour/source/rtl/datec.c
    + accept timestamp parameters in CMONTH() and CDOW() functions

  * harbour/source/rtl/empty.c
    + added support for timestamp items



Já havia comentado em outro post mais antigo sobre essa possibilidade de alteração da gravação "default" da data no MySQL.

Saudações,
Itamar M. Lins Jr.

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 08:34
por JoséQuintas
PROCEDURE Main

   LOCAL d

   d := Ctod("")
   ? hb_Dtoc( d, "YYYY-MM-DD" )
   ? hb_Dtoc( Date(), "YYYY-MM-DD" )

   RETURN


- -
2017-08-15


Como usei DateSql(), vai acabar sendo só uma linha no aplicativo inteiro.
Mas vou revisar se faço uso em outros lugares, de algo parecido.
De qualquer forma, data vazia continua precisando de ajuste.

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 08:43
por JoséQuintas
Poderia ser assim também:

Transform( Dtos( Date() ), "@R 9999-99-99" )

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 08:57
por JoséQuintas
Achei outro uso, no arquivo CNAB.
Neste seria difícil um equivalente a não se o hb_Dtoc() mesmo.

?? StrZero( Day( jpfinan->fiDatEmi ), 2 ) + StrZero( Month( jpfinan->fiDatEmi ), 2 ) + StrZero( Year( jpfinan->fiDatEmi ) - 2000, 2 )

?? hb_Dtoc( jpfinan->fiDatEmi, "DDMMYY" )

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 09:27
por Itamar M. Lins Jr.
Ola!
Melhor configurar direto no Mysql, entretanto se a data estiver vazia e quer zeros:
? STRTRAN( hb_Dtoc( ctod(""), "YYYY-MM-DD" )," ","0")


Saudações,
Itamar M. Lins Jr.

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 09:41
por JoséQuintas
Mas acho interessante como eu fiz, criar uma DateSql() ou ValueSql() pra tudo.
Quem usa comando SQL vai usar muito isso, então mais prático chamar uma única função.
E já acerta do jeito que quiser nessa função (NULL ou '0000-00-00')

Eu só acho interessante usar NULL porque vale pra TUDO: SQL Server, Access, MySQL, Excel, etc., até mesmo ADS (DBF).
Não precisa se preocupar ao trocar a base de dados.
E vale pra base de dados que tenha sido criada em outro aplicativo - tem essa também.

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 09:52
por JoséQuintas
Mas hb_Dtoc() foi muito interessante, aqui só no "fonte público".

https://github.com/JoseQuintas/JoseQuintas/commit/05a30292fa50cfb9994faa30c12dbebf3e2d58e0

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 10:01
por JoséQuintas
Lembrei da função inversa, pena que não funciona do mesmo jeito.

PROCEDURE Main

   ? hb_Ctod( "20170815", "YYYYMMDD" )
   ? hb_Ctod( "15082017", "DDMMYYYY" )
   ? hb_Ctod( "2017-08-15", "YYYY-MM-DD" )
   ? hb_Ctod( "15-08-2017", "DD-MM-YYYY" )

   RETURN



/ /
/ /
08/15/17
08/15/17

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 11:07
por porter
Na tabela Clientes, tenho os campos
IDCLI_COD, CLI_NOME, CLI_NASCEU

Se a variável nasceu = "", quero omitir esse campo no Insert, dessa forma automaticamente o campo CLI_NASCEU assumiria NULL
mas, não estou conseguindo, achei esse exemplo, estou tentando seguir essa lógica mas não sei se o MySql aceita tomar decisão
dentro do comando INSERT.

nasceu=""

sql = "INSERT INTO Clientes"
sql = sql & "(IDCLI_cod,"
If !( nasceu = "")
{
sql = sql &"Cli_Nasceu"
}
sql = sql & ") VALUES ("2010/10/10")
If !( nasceu = "")
{
sql = sql & ",'2010/10/10'"
}
sql = sql & ")"

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 12:03
por Itamar M. Lins Jr.
Ola!
Poter, crie o habito de criar as variáveis com uma letrinha em minúsculo informando o tipo.
dNasceu := iif( empty(data),NULL,dData)

Coloque seu código dentro das tags code e /code dentro dos colchetes [].

Use += para criar a string com o comando SQL.
assim:
dNasceu := iif( empty(data),NULL,dData)
cSQL := 'INSERT INTO Clientes (IDCLI_cod,cli_nasceu) Values ( '
cSql += ' " ' + xcod + ' ", '
cSql += ' " ' + dNasceu + ' " '
cSql += ' ) '


Monte a sequencia cSQL e veja antes via alert() se está tudo ok.

Saudações,
Itamar M. Lins Jr.

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 13:50
por JoséQuintas
Eu fui passando por fases ao fazer isso, procurando encontrar um jeito que acharia interessante.

Numa época, pra enxergar o comando, criava o comando e depois trocava partes.

cSql := "INSERT INTO CLIENTES ( IDCLI_CODCLI, CLI_NOME, CLI_NASCEU ) VALUES ( [CODIGO], [NOME], [NASCEU] )"
cSql := Replace( cSql, "[CODIGO]", StringSql( xCod ) )
cSql := Replace( cSql, "[NOME]", StringSql( xcli_nome) )
cSql := Replace( cSql, "[NASCEU]", DateSql( dNasceu ) )


Mas quando a lista é grande, não tem jeito, melhor algum recurso extra, criando os pares e depois montando o comando, e vale pra INSERT e UPDATE.
Aí que entra a classe.

Como é o comando SQL:

INSERT INTO tabela ( campos ) VALUES ( valores )
UPDATE tabela SET campo=valor, campo=valor, ... WHERE condição

Nos dois tem a lista de nomes e valores, então primeiro é guardar a lista em um array e depois completar.
No INSERT a lista é em duas partes, e no UPDATE tem também a condição
E nos dois tem a tabela.

WITH OBJECT cnMySql
   :QueryCreate()
   :QueryAdd( "IDCLI_CODCLI", xCod )   
   :QueryAdd( "CLI_NOME", xCli_nome )
   :QueryAdd( "CLI_NASCEU", dNasceu )
   :QueryExecuteInsert( "CLIENTES" )     
// :QueryExecuteUpdate( "CLIENTES", "IDCLI_CODCLI=" + xCod )
END WITH


Para o que mencionou, para omitir um campo, bastaria:

IF ! Empty( dNasceu )
   :QueryAdd( "CLI_NASCEU", dNasceu )
ENDIF


Mas lembre-se que na alteração vai ser obrigado a indicar valor, porque pode ser que o usuário está limpando o conteúdo anterior.

Se for montar direto, teria que colocar iif() nos dois locais, o que vai deixar o fonte de montagem do comando mais confuso, principalmente se tiver muitos campos, e vai facilitar o erro.

cSql := "INSERT INTO CLIENTES ( IDCLI_CODCLI, CLI_NOME"
IF ! Empty( dDate )
   cSql += ", CLI_NASCEU"
ENDIF
cSql += " ) VALUES ("
cSql += xCodCli + ", '"  + cli_nome + "'"
IF ! Empty( dDate )
   cSql += ", '"  + hb_Dtoc( xCli_Nasceu, "YYYY-MM-DD" ) + "'"
ENDIF
cSql += ")"


Percebe a diferença em enxergar os campos nos dois fontes?
Ou em conferir se a quantidade de nomes e valores está correta?
Pode ser interessante criar uma rotina pra isso, e poder colocar no fonte um "par" de cada vez, com nome e valor.

É apenas sugestão.
A minha está valendo pra mim até eu criar outra diferente.... rs

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 14:01
por JoséQuintas
Faltou dizer:
E pode colocar a parte de conversão na rotina que monta a string, menos coisa no fonte do aplicativo pra confundir.
É assim que uso.

Dúvida inserir data no MySql

MensagemEnviado: 15 Ago 2017 14:03
por JoséQuintas
Um outro com mais campos.
Fica bonito de se ver... rs
Conversão só se for pra gravar número como string.
Tente imaginar montar esse comando INSERT "a mão", como ficaria o fonte.

         WITH OBJECT cnMySql
            :QueryCreate()
            :QueryAdd( "RECIBO",     mRecibo10Recibo )
            :QueryAdd( "NEXTRA",     mNumExtrato )
            :QueryAdd( "COD",        mRecibo10Cod )
            :QueryAdd( "LOCOD",      mRecibo10LoCod )
            :QueryAdd( "LOCNOME",    mRecibo10LocNome )
            :QueryAdd( "NOME",       mRecibo10Nome )
            :QueryAdd( "VALOR",      mRecibo10Valor )
            :QueryAdd( "DIA_VENC",   mRecibo10Dia_Venc )
            :QueryAdd( "DATA",       mRecibo10Data )
            :QueryAdd( "ALUGUELNP",  mRecibo10AluguelNP )
            :QueryAdd( "ALUGUELQP",  mRecibo10AluguelQP )
            :QueryAdd( "COM",        mRecibo10Com )
            :QueryAdd( "VALORCOMIS", mRecibo10ValorComis )
            :QueryAdd( "TC",         mRecibo10Tc )
            :QueryAdd( "DB",         mRecibo10Db )
            :QueryAdd( "MES",        mRecibo10Mes )
            :QueryAdd( "MESTO",      mRecibo10MesTo )
            :QueryAdd( "EMITIDO",    mRecibo10Emitido )
            :QueryAdd( "ADIANTA",    mRecibo10Adianta )
            :QueryAdd( "TIPO",       mRecibo10Tipo )
            :QueryAdd( "PAGO",       mRecibo10Pago )
            :QueryAdd( "ANOBASE",    StrZero( Year( mDataBaixa ), 4 ) )
            :QueryAdd( "CRDATPAG",   mDataBaixa )
            :QueryExecuteInsert( "CORRENTE" )
         END WITH

Dúvida inserir data no MySql

MensagemEnviado: 06 Nov 2017 14:05
por Cisino Junior
porter escreveu:Se a variável nasceu = "", quero omitir esse campo no Insert, dessa forma automaticamente o campo CLI_NASCEU assumiria NULL


Olá porter, se no schema da sua tabela MySQL o campo "CLI_NASCEU" está como not null, significa que é obrigatório que esse campo seja preenchido. Então, você pode fazer a validação no seu aplicativo, e verificar se o usuário entrou com o dado desse campo, ou, alterar o campo para que ele aceite valor nulos, ou seja, não será obrigatório que o valor desse campo seja passado no IINSERT, você também pode setar um valor default para o campo, mas não aconselho visto que é a data de nascimento de alguém. Não sei se foi você quem modelou o banco de dados, ou outra pessoa, mas não é boa prática deixar campos que aceitem null, revise o modelo conceitual do seu banco de dados. E já que o campo está como not null, faça a validação no seu aplicativo de todos os dados obrigatórios a serem cadastrados.

Atenciosamente,
Cisino Junior.

Dúvida inserir data no MySql

MensagemEnviado: 06 Abr 2023 14:48
por HASA
Boa tarde, estou migrando dados com o mysql 8 e estou recendo o seguinte erro Incorrect date value, tentei: "0000-00-00", "00000000", "", "NULL", "null" mesmo erro em todas a vezes, campo criado assim: data_ultima_compra date DEFAULT NULL, alguem passou por isso e pode ajudar-me.

HASA

Dúvida inserir data no MySql

MensagemEnviado: 06 Abr 2023 16:11
por JoséQuintas
É NULL
e não 'NULL' nem "NULL"

Dúvida inserir data no MySql

MensagemEnviado: 06 Abr 2023 16:55
por HASA
Boa tarde, Zé mas como monto o envio desse NULL, tentei com Macro e tbm não deu exemplo:

cNULL="NULL"

cSql := "INSERT INTO contador ( `id_contador`, `nome`, `dtcadastro` ) " +;
"VALUES ( '1' , '"+;
ALLTRIM( D_CONTAB->NOME ) +"' , '"+;
IF( CTOD( D_CONTAB->DTCADASTRO ), &cNULL, Data_sql( D_CONTAB->DTCADASTRO ) ) +"' ); "

Da erro: Erro BASE/1003 Vari vel nÆo existe: NULL

/* Executa Query */
oQuery := oServer:Query( cSql )

Não estou sabendo como enviar esse NULL, se eu coloco "NULL", para na execução da linha cSql, mas ao executar do o erro acima.

HASA

Dúvida inserir data no MySql

MensagemEnviado: 06 Abr 2023 18:40
por alxsts
Olá!

HASA escreveu:Boa tarde, estou migrando dados com o mysql 8 e...


Lendo o código que postou, percebe-se que está misturando alhos com bugalhos...

Se está migrando de DBF para SQL, tem que testar se o campo do DBF está vazio e não NULL. Se o campo do DBF estiver vazio, montar a query com NULL. Caso contrário, montar a query com o conteúdo do campo convertido para o formato SQL. Veja as alterações que fiz no teu código:
LOCAL cSQL

cSQL := "INSERT INTO contador ( `id_contador`, `nome`, `dtcadastro` ) VALUES ( '1' , '"
cSQL += ALLTRIM( D_CONTAB->NOME ) + "' , '"
cSQL += IF( EMPTY( D_CONTAB->DTCADASTRO ), "NULL", Data_sql( D_CONTAB->DTCADASTRO ) ) + " ); "


Testar se um campo contem o valor NULL é usado para testar dados retornados do banco de dados, por exemplo no retorno de um SELECT.

Lembrando que:
HASA escreveu:data_ultima_compra date DEFAULT NULL

Quando na definição da coluna da tabela existe a cláusula DEFAULT, não é obrigatório enviar valor para ela. Caso não envie, o valor DEFAULT é gravado durante o INSERT...

Dúvida inserir data no MySql

MensagemEnviado: 06 Abr 2023 19:39
por JoséQuintas
Na prática, é só olhar as mensagens do tópico, tem lá a função DateSQL()

Como já foi dito, na inclusão não precisa, mas na alteração sim.
Talvez melhor acostumar a colocar sempre, mesmo na inclusão.

Perde essa mania de usar macro, não é pra ficar usando à toa, é só em último caso, em situações especiais.
Esquece que isso existe.

Mas.... criou a função DATA_SQL() pra converter data e tá colocando iif no comando ?????
Sinal de que a função tá incompleta.

cSQL := "INSERT INTO TABELA ( DATA ) VALUES ( " + Data_Sql( dData ) + " )"

FUNCTION Data_SQL( dData )

   IF Empty( dData )
      RETURN "NULL"
  ENDIF

   RETURN ['] + hb_Dtoc( dData, "YYYY-MM-DD" ) + [']


Sem macro e sem complicações.

Dúvida inserir data no MySql

MensagemEnviado: 06 Abr 2023 19:45
por JoséQuintas
E isso de colocar crase:

INSERT INTO TABELA ( `codigo`, `nome` )


Isso também é último caso, quando o nome do campo foge da regra geral, por exemplo, usar nome reservado.
O HeidiSQL usa isso pra tudo, mas de um modo geral é só trabalho extra e poluição.

Dúvida inserir data no MySql

MensagemEnviado: 07 Abr 2023 14:42
por HASA
- Boa tarde José e Alexandre, amanhã texto e com certeza ajeito minhas funções, desde já agradeço,
BOA PASCOA A TODOS!
HASA

Dúvida inserir data no MySql

MensagemEnviado: 10 Abr 2023 09:23
por HASA
-Bom dia, gostaria de agradecer aos amigos pelas dicas, e deixar uma também, no meu caso a confusão se deu em ASPAS simpes e ASPAS duplas, estava fazendo certo, mas não respeitando a regra das aspas.
Valeu mesmo pessoal.

HASA

Dúvida inserir data no MySql

MensagemEnviado: 10 Abr 2023 13:16
por JoséQuintas
HASA escreveu:-Bom dia, gostaria de agradecer aos amigos pelas dicas, e deixar uma também, no meu caso a confusão se deu em ASPAS simpes e ASPAS duplas, estava fazendo certo, mas não respeitando a regra das aspas.
Valeu mesmo pessoal.


Por isso acaba sendo interessante criar a função de conversão.
Porque cada novo fonte pode conter o erro de aspas.

Além disso, tem caracteres que o MySQL não aceita, ou precisa algo especial.
Uma função StringSQL() pode facilitar acertar isso em tudo.
Por exemplo, um texto com aspas, ou um texto com ENTER, ou outros.
Caracteres especiais precisam da barra invertida antes de cada um.

[vamos ver o que 'temos']

vira

[vamos ver o que \'temos\']

Caracteres especiais não significa acentuados, é por exemplo esse da aspa simples, que delimita a string, e o MySQL não saberia como tratar isso no meio do texto, porque pra ele indica início e fim do texto.