16 de abr. de 2021

Literais

Literais


    Quando falamos sobre um valor literal em uma consulta de banco de dados estamos nos referindo há um valor fixo, isso significa que esse valor se repetirá em todas as linhas retornadas pela consulta. Temos 4 tipos de literais textos, numéricos, datas e intervalos, abaixo alguns exemplos do uso, note que embora o valor dentro do literal pareça igual nas colunas "Número" e "Caractere" uma o valor 101 é exibido em formato numérico enquanto na outra em formato de sequência de caracteres, essa indicação é facilmente identificada através do alinhamento dos valores dentro da coluna.

Uso de literais em SQL




Texto Literal

    Textos podem ser utilizados como literais de maneira bem simples basta incluir os caracteres entre aspas simples, podendo receber um ALIAS, caso o alias seja omitido o título da coluna será o valor utilizado no literal excluindo os espaços.
String como literal no SQL
    Quando há necessidade de incluir aspas no texto que será exibido no literal é necessário fazer a indicação de um delimitador alternativo chamado de quote_delimiter que basicamente é a substituição da delimitação através de aspas simples por outra indicada podendo ser (), {}, [] ou <>. A letra 'Q' no delimitador pode ser maiúscula ou minúscula, e as símbolos usados como delimitador podem ser incluídos dentro do literal. Há ainda a possibilidade de duplicar as aspas para indicar que a mesma está sendo utilizada dentro do literal. Abaixo exemplos de uso dos delimitadores.

    O Oracle permite até 4000 bytes em um único literal, podendo ser 32767 caso o parâmetro MAX_STRING_SIZE esteja com o valor igual a EXTENDED.

Número Literal

    Diferente dos caracteres, números não precisam de aspas simples ( ' ) para informar que são literais, basta incluí-los na consulta, mas assim como os caracteres literais, os números literais também tem suas particularidades.
    Na imagem abaixo, podemos ver formas diferentes de usar literais numéricos. Vale destacar que para números inteiros positivos não é necessário utilizar o sinal de mais ( + ) e que quando se usa casas decimais o limite é de 38 dígitos. Para que o retorno seja no formato BINARY_FLOAT devemos utilizar 'f' após o número e no caso de DOUBLE_FLOAT devemos utilizar 'd' enquanto a letra 'e' simboliza uma notação científica.


    Ao utilizar literais com números devemos ter cuidado quanto ao separador. Para verificar qual o padrão está definido podemos realizar uma consulta e verificar como está definida a parametrização para a sessão ou para o banco de dados através das consultas abaixo:

        select * from nls_session_parameters
        where parameter = 'NLS_NUMERIC_CHARACTERS';

        select * from nls_database_parameters
        where parameter = 'NLS_NUMERIC_CHARACTERS';



    No exemplo abaixo, temos 3 expressões que deveriam ter o mesmo resultado, mas por erro ao escrever a consulta não traz o resultado esperado. Quando o literal utilizado for do tipo numérico devemos utilizar o ponto ( . ) como separador das casas decimais, caso for utilizado a vírgula ( , ) como separador o literal deve ser passado como caractere, ou seja, dentro de aspas simples ( ' ). Caso o separador seja a vírgula e não esteja dentre de aspas simples o banco de dados irá identificar a vírgula como separador de colunas conforme exemplo abaixo.



Data e Horário Literal

    Para os literais de datas é possível informa-los como texto ou utilizar a função TO_DATE e realizar a conversão para formato de data, ou ainda utilizando a função SYSDATE ou SYSTIMESTAMP, sendo ainda permitido efetuar operações com as funções.


    Para identificar o formato de datas utilizado pelo banco de dados, basta realizar uma consulta em NLS_DATABASE_PARAMETERS procurando pelo parâmetro NLS_DATE_FORMAT.


   Caso o horário seja omitido em um literal de data e hora, a hora será interpretada como '00:00:00' ou '12:00:00' dependendo do padrão de horário ser 24 horas ou 12 horas.
    Da mesma maneira, que podemos utilizar as datas, podemos utilizar o formato timestamp como literal, inclusive utilizando as variantes de local time zone ou com um time zone específico.


Intervalo Literal

    Os intervalos especificam períodos de tempo podendo ser anos e meses ou dias, horas, minutos e segundos, de acordo com o tipo de dado utilizado YEAR TO MONTH ou DAY TO MINUTE, conforme visto aqui e também podemos utilizar literais com os intervalos para especificar esses períodos. Nesse tipo de literal informamos 1 ou 2 campos, onde o primeiro é a maior unidade de medida e o segundo a menor unidade de medida, por exemplo, ao passar um literal '123-2' para o tipo YEAR TO MONTH, estamos dizendo que temos 123 anos e 2 meses. 
    Abaixo exemplos do uso do intervalo com anos e meses, nos exemplos podemos notar o uso dos intervalos literais, como a precisão para anos é de 2, precisamos informar a precisão nos casos dos literais maiores que 2 casas, no caso dos mesmo o padrão é 3. no caso dos literais '123-9' estamos é necessário a utilização do year(3) to month enquanto nos outros podemos apenas informar year ou month.

    Lembrando que caso o literal informado não esteja no padrão esperado ou estoure o tamanho da precisão a consulta não irá executar retornando um erro.

    Da mesma maneira, podemos utilizar os literais para
DAY TO MINUTE e suas partes. Podendo utilizar apenas uma parte ou mais de uma parte, desde que respeitado o formato necessário.




    O uso de intervalos literais costuma ser um tema recorrente nas provas de certificação 1Z0-071, por isso deve ser um tema estudado e testado bastante.



Fonte:


7 de abr. de 2021

Tipos de Dados - Demais tipos

    Além dos tipos de dados que já vimos, onde podemos manipular e armazenar, caracteres, dígitos e datas, temos outros tipos de dados que veremos abaixo.

LONG

    Atualmente não é mais recomendável utilizar colunas do tipo LONG, pois estão defasadas, devendo ser utilizadas BLOB, CLOB ou NCLOB, sendo recomendando também a conversão de colunas LONG para LOB. Contudo, o banco de dados ainda suporta esse tipo de dados por questões de retro compatibilidade.

O tipo de dados LONG é um tipo que permite armazenar sequências de caracteres de até 2Gb. Esse tipo de dados possui várias peculiaridades entre elas:

  • Somente uma coluna long por tabela;
  • Colunas long não podem ser utilizadas em índices;
  • Não podem ser utilizadas em expressões regulares;
  • Não podem ser utilizadas na cláusula WHERE ou em constraints de integridade.
  • Não podem ser utilizadas em GROUP BY, ORDER BY, CONNECT BY ou no select com função DISTINCT.

RAW e LONG RAW

    Os tipos RAW e LONG RAW são utilizados para armazenar dados que não são convertidos explicitamente pelo banco de dados Oracle quando move os dados entre diferentes sistemas. Podem ser utilizados para armazenamento de áudios, gráficos, imagens ou documentos. Assim como ocorre com o tipo LONG, é recomendável utilizar os tipos de dados LOB ao invés do LONG RAW. Tipos RAW funcionam como VARCHAR2, pois tem tamanho variável. Os tipos RAW podem ser implicitamente convertidos em CHAR, VARCHAR2 ou LONG e também podem ser explicitamente convertidos em hexadecimal utilizando a função RAWTOHEX e HEXTORAW. 

ROWID

    Todas as linhas no armazenadas no banco de dados Oracle tem um endereço específico que é utilizada para a organização dos dados dentro do banco, esses endereços de cada linha são chamados de rowids. Para saber qual o endereço de um linha basta incluir a pseudocoluna ROWID na área de select da consulta. A pseudocoluna ROWID também pode ser utilizada no campo WHERE.





    Os valores de rowid são formados na base de 64, podem conter caracteres de a-z ou A-Z, dígitos de 0-9 e os sinais + (mais) e / (barra). O tamanho do conteúdo de rowid vai depender também do sistema operacional utilizado no banco de dados.

UROWID

    Urowid significa universal rowid e são utilizados quando os rowids não estão armazenados dentro do banco de dados Oracle, podendo ser tabelas externas do banco ou mesmo de outros bancos de dados acessados pelo Oracle por meio de Gateways.

Tipos LOB

    O tipo de dados LOB significa Large Objects, ou seja objetos grandes. Podemos classificar o dados LOB em internos e externos de acordo com a maneira que é armazenado no banco de dados, os  LOBs internos são armazenados dentro do banco de dados e podem ser do tipo CLOB, NCLOB ou BLOB, enquanto o LOB externo é armazenado fora do banco de dados e é chamado de BFILE. Esses tipos de dados servem para armazenar informações grandes ou fora de padrões, como áudios e imagens. Os tipos LOB podem armazenar até 4000 bytes na forma de coluna, no caso de ter mais de 4000bytes serão sempre armazenados externamente. Colunas LOBs possuem localizadores que referenciam se os valores estão armazenados internamente ou externamente, quando fazendo um select em uma coluna LOB, o banco de dados retorna os localizadores dos registros dessa coluna.

CLOB

    O tipo de dados CLOB armazena dados em formato caractere tanto de byte único como multibyte, são suportados caracteres de tamanho fixo ou variável. Objetos CLOB tem suporte completo para transações, podendo ter commits ou rollbacks em seus dados. As colunas do tipo CLOB podem armazenar até (4Gb-1) * (valor do parâmetro CHUNK), caso o valor para o parâmetro CHUNK padrão tenha sido utilizado na definição da coluna nesse caso o valor que poderá ser armazenado será definido por (4Gb -1) * (tamanho do bloco do banco de dados).

NCLOB

    O tipo de dados NCLOB armazena dados em formato Unicode, são suportados caracteres de tamanho fixo ou variável com ambos utilizando o conjunto de caracters nacional. Objetos NCLOB tem suporte completo para transações, podendo ter commits ou rollbacks em seus dados. As colunas do tipo NCLOB podem armazenar até (4Gb-1) * (valor do parâmetro CHUNK), caso o valor para o parâmetro CHUNK padrão tenha sido utilizado na definição da coluna nesse caso o valor que poderá ser armazenado será definido por (4Gb -1) * (tamanho do bloco do banco de dados).

BLOB

    BLOB significa Binary Large OBjects e armazena dados binários grandes e não estruturados, objetos BLOB tem suporte completo para transações, podendo ter commits ou rollbacks em seus dados. As colunas do tipo BLOB podem armazenar até (4Gb-1) * (valor do parâmetro CHUNK), caso o valor para o parâmetro CHUNK padrão tenha sido utilizado na definição da coluna nesse caso o valor que poderá ser armazenado será definido por (4Gb -1) * (tamanho do bloco do banco de dados).

BFILE

    O tipo BFILE serve para acessar arquivos binários que estão armazenados fora do banco de dados. É possível realizar a troca do caminho onde o arquivo está armazenado ou mesmo o nome do arquivo sem afetar os dados do mesmo utilizando a função BFILENAME. Os dados dentro de um BFILE são apenas para leitura, não sendo possível realizar alterações e é tarefa do DBA garantir que os processos do banco de dados Oracle possuam permissão de leitura nos arquivos BFILE. Um arquivo BFILE poderá ter no máximo 264-1 bytes, contudo esse valor poderá ser menor de acordo com o sistema operacional.

JSON

    Introduzido a partir da versão 21c serve para armazenar arquivos JSON de maneira nativa em formato binário, isso melhora o desempenho, pois não há mais necessidade de conversão. Além do tipo de dados JSON, os arquivos JSON são suportados pelos tipos VARCHAR2, BLOB e CLOB.


Fonte:

https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Data-Types.html#GUID-A3C0D836-BADB-44E5-A5D4-265BA5968483

31 de mar. de 2021

Tipos de Dados - Datas

    Os tipos de dados que trabalham com datas se dividem em 2 tipos: datahora e intervalos, onde os tipos datahora armazenam datas e horários de fato e intervalos retornam os intervalos entre 2 datas.

    Lembrando que sempre que for trabalhar com tipos de dados de data é bom verificar antes como está a configuração do banco de dados para estes tipos de dados, pois isso pode impactar nos resultados esperados. Para verificar como estão as configurações podemos fazer 2 consultas na tabela dummy DUAL.

    select DBTIMEZONE from dual;

    select SESSIONTIMEZONE from dual;


Tipo de dataValores validos para DataValores validos para  INTERVALOS

YEAR

-4712 até 9999 (excluindo ano 0)

Qualquer inteiro positivo ou negativo

MONTH

01 até 12

0 até 11

DAY

01 até 31 (limitado de acordo com o mês e ano)

Qualquer inteiro positivo ou negativo

HOUR

00 até 23

0 até 23

MINUTE

00 até 59

0 até 59

SECOND

00 até 59.9(n), onde 9(n) é a precisão de milissegundos . A opção 9(n) não se aplica para DATE.

0 até 59.9(n), onde 9(n) é a precisão de milissegundos

TIMEZONE_HOUR

-12 até 14 (Esses valores consideram horários de verão) Não se aplica para DATE ou TIMESTAMP.

Não se aplica

TIMEZONE_MINUTE

00 até 59. Não se aplica para DATE ou TIMESTAMP.

Não se aplica

TIMEZONE_REGION

Consulte a coluna TZNAME na view V$TIMEZONE_NAMES. Não se aplica para DATE ou TIMESTAMP

Não se aplica

TIMEZONE_ABBR

Consulte a coluna TZABBREV na view V$TIMEZONE_NAMES. Não se aplica para DATE ou TIMESTAMP.

Não se aplica

DATE

    O tipo de dados DATE armazena informações de dia e hora, podemos até mesmo utilizar outros tipos de dados para armazenar datas, como um tipo de dados de caracteres por exemplo, contudo essa não é a solução mais adequada visto que para isso temos os tipos de dados de datas, em que é possível diferenciar cada parte da data como dia, mês, ano, hora, minuto e segundo. Também é possível fazer conversões de dados armazenados em colunas do tipo de data para formatos de número ou caractere através das funções TO_CHAR e TO_NUMBER, que veremos mais adiante. Utilizando essas funções é possível criar uma data a partir de um literal.



Como faço para descobrir a data atual no banco de dados? Simples, basta realizar uma consulta na tabela DUAL retornando SYSDATE.



TIMESTAMP

    O Tipo TIMESTAMP funciona como o tipo DATE mas ele armazena a data, a hora e a fração de segundos, podendo ir de 0 a 9 casas para os milissegundos sendo o padrão o valor 6. Assim como é possível retornar a data do sistema, é possível retornar o valor atual de um timestamp no sistema.


    Também é possível utilizar a função TO_TIMESTAMP para converter, por exemplo, uma data para o formato timestamp.


TIMESTAMP WITH TIME ZONE

  O tipo de dados TIMESTAMP[(frações de milissegundos)] WITH TIME ZONE funciona da mesma maneira que o tipo TIMESTAMP, porém, armazena além do timestamp o time zone, que pode estar no formato TIMEZONE REGION NAME ou TIME ZONE OFFSET. Assim como no tipo TIMESTAMP, a fração de segundos pertimitida pode variar de 0 até 9 e quando omitida na declaração da coluna o valor padrão assumido será 6.



TIMESTAMP WITH LOCAL TIME ZONE

    Essa é mais uma variante do tipo TIMESTAMP, porem diferente do TIMESTAMP WITH TIME ZONE na coluna não é armazenado as informações do timestamp do banco de dados e quando é solicitado em um select é retornado de acordo com com o timezone da sessão do usuário. Este tipo de dados é bastante útil quando há uma aplicação que trabalha com diferentes timezones e deve ser exibido as datas e horários de acordo com a configuração de cada usuário. Assim como os demais tipos de dados derivados de timestamp, este também permite determinar a quantidade de casas decimais que serão armazenados para os segundos, podendo ser de 0 a 9 e caso omitido o padrão será 6. Para criar uma coluna utilizando esse tipo é necessário utilizar a seguinte sintaxe:

    TIMESTAMP [(precisão de segundos)] WITH LOCAL TIME ZONE


INTERVALOS

    Intervalos são tipos de dados que armazenam períodos de tempo, temos a possibilidade de armazenar valores de 2 formas: intervalos de anos e meses ou intervalos de dias e segundos. É possível utilizar intervalos como validações na cláusula WHERE de uma consulta.

INTERVAL YEAR TO MONTH

    Armazena um período de tempo baseado em anos e meses, para utilizar temos a seguinte sintaxe:

    INTEVAL YEAR [(precisão dos anos)] TO MONTH

Caso a precisão não seja especificada o valor padrão é 2 e deve ser um número inteiro.

Abaixo alguns exemplos.

Intervalo de 300 meses, será armazenado como 25 anos, enquanto um intervalo de 306 meses é armazenado no como 25 anos e 6 meses.



    A precisão deve ser respeitada, caso contrário irá retornar erro, no exemplo abaixo, não foi determinada a precisão dos anos, que nesse caso assume o valor padrão que é 2, como o literal informado para o ano tem 3 dígitos, excede a precisão de 2 e pode ser resolvido incluindo a precisão após a palavra YEAR.



INTERVAL DAY TO SECOND

    Este intervalo armazena um período de tempo que pode ser em dias, horas, minutos ou segundos, esse tipo de dados é muito útil quanto é necessário armazenar uma diferença precisa entre duas datas e horários.

Sua sintaxe é a seguinte:

    INTEVAL DAY[(precisão do dia)] TO SECOND [(precisão da fração de segundos)]

    Note que neste tipo de dados, podemos informar ou não tanto a precisão do dia quanto a fração de segundos. A fração de segundos, assim como nos tipos TIMESTAMP, pode ser de 0 a 9 e tem como padrão o valor 2, já a precisão dos dias aceita os mesmos valores e também tem a precisão com valor 2 como padrão.


    Também é possível realizar operações entre os tipos DAY TO SECOND. Note no exemplo abaixo, que diminuindo 1 dia de 1440 minutos, o resultado é 0.

23 de mar. de 2021

Tipos de Dados - Numéricos

    Seguindo conhecendo os tipos de dados suportados pelo Banco de Dados Oracle, agora vamos entender como funcionam os tipos de dados numéricos.

NUMBER

    O tipo de dados NUMBER pode armazenar 0, valores negativos até  1.0 x 10-130 e valores positivos até 1.0 x 10126 sem incluí-lo, caso seja igual ou maior retornará erro. 

    A sintaxe para criação de uma coluna do tipo NUMBER é NUMBER(p,e) onde p indica precisão e o e escala. Mas o que seriam precisão e escala para uma coluna NUMBER?

Precisão de uma coluna NUMBER indica quantas dígitos serão armazenados.

Já a escala determina a quantidade de casas decimais o número irá suportar incluindo esse valor, no caso de um valor positivo. No caso de um valor negativo, a precisão irá arredondar a quantidade de casas log antes da virgula.

    Também é possível criar uma coluna determinando apenas a precisão, nesse caso a sintaxe do tipo da coluna seria NUMBER(p). Seguem alguns exemplos de configurações utilizadas como NUMBER:

Dado informadoDefinição da ColunaArmazenado como

123.89

NUMBER

123.89

123.89

NUMBER(3)

124

123.89

NUMBER(3,2)

excede a precisão

123.89

NUMBER(4,2)

excede a precisão

123.89

NUMBER(5,2)

123.89

123.89

NUMBER(6,1)

123.9

123.89

NUMBER(6,-2)

100

.01234

NUMBER(4,5)

.01234

.00012

NUMBER(4,5)

.00012

.000127

NUMBER(4,5)

.00013

.0000012

NUMBER(2,7)

.0000012

.00000123

NUMBER(2,7)

.0000012

1.2e-4

NUMBER(2,5)

0.00012

1.2e-5

NUMBER(2,5)

0.00001

FLOAT

    O tipo de dados FLOAT é considerado um subtipo do tipo NUMBER, esse tipo também permite sua declaração com ou sem precisão da mesma maneira que o tipo NUMBER, já a escala não pode ser definida e é interpretada pelos dados. O tipo FLOAT é utilizado com frequência para o armazenamento de pontos flutuantes, mas o que são pontos flutuantes? Basicamente é um número real, que pode ter uma vírgula em qualquer posição dele ou simplesmente não ter uma vírgula, podendo ser representado por notação exponencial.

Segue um comparativo do armazenamento de dados em colunas do tipo NUMBER e FLOAT.

CREATE TABLE test (col1 NUMBER(5,2), col2 FLOAT(5));

INSERT INTO test VALUES (1.23, 1.23);
INSERT INTO test VALUES (7.89, 7.89);
INSERT INTO test VALUES (12.79, 12.79);
INSERT INTO test VALUES (123.45, 123.45);

SELECT * FROM test;

      COL1       COL2
---------- ----------
      1.23        1.2
      7.89        7.9
     12.79         13
    123.45        120
    A conversão de um número binário para precisão decimal se faz pela multiplicação de n por 0.30103, já para a conversão de um decimal para precisão binária a multiplicação é feita por 3.32193. O valor máximo armazenado é de 126 dígitos com precisão binária que é equivalente a 38 dígitos de precisão decimal.

BINARY_FLOAT

    O tipo de dados BINARY_FLOAT é um dado de ponto flutuante de 32 bits com precisão individual e que cada BINARY_FLOAT requer 4 bytes.

BINARY_DOUBLE

    É um tipo de dados de ponto flutuante de 64 bits com precisão de duas casas e que cada BINARY_DOUBLE requer 8 bytes.

    A diferença entre tipos de NUMBER e os BINARY é que colunas NUMBER tem precisão decimal enquanto os BINARY a precisão é binária. Os tipos binários suportam valores especiais infinitos e valores Not a Number (NaN).


BINARY_FLOATBINARY_DOUBLE

Valor máximo positivo finito

3.40282E+38F

1.79769313486231E+308

Valor mínimo posiitivo finito

1.17549E-38F

2.22507485850720E-308


Fonte:

https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Data-Types.html#GUID-A3C0D836-BADB-44E5-A5D4-265BA5968483