0% acharam este documento útil (0 voto)
16 visualizações23 páginas

Model View Controller: SQL Básico

SQL Básico

Enviado por

tozzicc
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
16 visualizações23 páginas

Model View Controller: SQL Básico

SQL Básico

Enviado por

tozzicc
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato DOCX, PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 23

SQL Básico

(Model View Controller)

SQL nível básico (Joins, Funções de Agregação e Subquerys), TcQuery e Embedded SQL.

1
SQL Básico

Sumário

1. SQL..........................................................................................................................3
1.1. Select................................................................................................................3
1.2. Clausula WHERE.............................................................................................4
1.3. Funções de agregação...................................................................................6
1.3.1. SUM...........................................................................................................6
1.3.2. COUNT......................................................................................................6
1.3.3. AVG...........................................................................................................7
1.3.4. MAX...........................................................................................................7
1.3.5. MIN.............................................................................................................7
1.3.6. GROUP BY................................................................................................7
1.3.7. HAVING.....................................................................................................8
1.3.8. DISTINCT..................................................................................................8
1.4. Função de String ( SUBSTRING/SUBSTR )..................................................9
1.5. ORDER BY.......................................................................................................9
1.6. Joins...............................................................................................................10
1.6.1. INNER JOIN............................................................................................10
1.6.2. LEFT JOIN ou LEFT OUTER JOIN........................................................11
1.6.3. RIGHT JOIN or RIGHT OUTER JOIN.....................................................13
1.6.4. FULL JOIN or FULL OUTER JOIN.........................................................14
1.6.5. CROSS JOIN...........................................................................................15
1.7. Unions............................................................................................................15
1.7.1. UNION.....................................................................................................16
1.7.2. UNION ALL.............................................................................................16
1.8. SUB SELECTS...............................................................................................16
2. TCQuery................................................................................................................17
3. Embedded SQL.....................................................................................................19

2
SQL Básico

1. SQL
1.1. Select

Este comando recupera informações gravadas no banco de dados. A diferença básica


de um select para um programa orientado a registros é que em um select você pode
recuperar várias linhas para uma determinada condição, ao contrário do programa que
teria que efetuar vários acessos para obter o mesmo resultado.
Ex. se você escrever um programa padrão ADVPL você terá que posicionar o registro,
fazer um laço até o final do arquivo, lendo o próximo registro, etc. Veja agora como
fazer em linguagem SQL.

Sintaxe:

SELECT [<apelido>.] <Nome da Coluna> [<Nome de Retorno>], n...


FROM <Nome da Tabela> [<apelido>], n ...

<Nome da Coluna> => Informar o nome(s) da(s) coluna(s) da(s) tabela(s) que você
deseja apresentar/manipular em seu aplicativo. Se você informar o símbolo ‘*’
(Asterisco) o comando assumirá todas as colunas da tabela.

<Nome da Tabela> => Informar o nome de todas as tabelas associadas ao resultado


esperado. Se existirem colunas com mesmo nome em tabelas diferentes, você deverá
associar o nome da tabela junto ao nome da coluna (SA1010.A1_NOME).

<Apelido> => sinônimo utilizado para referenciar uma tabela correspondente.

<Nome de Retorno> => Será o nome da coluna apresentado para sua aplicação
como o nome original de resultado da query.

 Ex. Select simples

SELECT *
FROM SA1990

SELECT A1_COD, A1_NOME


FROM SA1990

Quando utilizamos ‘*’ o SGDB estará retornando todas as colunas da tabela,


recomendamos sempre informar as colunas que realmente você estará
utilizando, por que, se a tabela possuir muitas colunas o tempo de resposta do
seu select pode ser mais demorado.

 Ex. Select com colunas compostas [ +, -, *, /, (, ) ]

SELECT C6_QTDVEN * C6_PRCVEN VALOR


FROM SC6990

Para colunas do tipo numérico podemos fazer qualquer tipo de cálculo,


lembrando que para o cálculo serão considerados os operadores que estiverem
dentro de parênteses para depois consideram os externos e assim por diante.
Vale a pena lembrar que no banco de dados os campos numéricos são do tipo
float, portanto não possuem limitação de casas decimais. No momento de
utilizar o resultado devemos efetuar o arredondamento dos dados com a função
abaixo:

3
SQL Básico

Sintaxe: ROUND(Coluna,Precisão)

SELECT
round(round(C6_QTDVEN,4)*round(C6_PRCVEN,2),2)VALOR
FROM SC6990

 Ex. Select com uso de apelido nas colunas

SELECT A1_COD CODIGO, A1_NOME NOME, R_E_C_N_O_ RECNO


FROM SA1990

Neste caso percebemos que na frente de cada nome de coluna existe um outro
nome referenciando a respectiva tabela que chamamos de apelido. Este nome
será utilizado como referência na resposta da query.

 Ex. Select com uso de apelido nas tabelas

SELECT SA1.A1_COD, SA1.A1_NOME


FROM SA1990 SA1

SELECT SA1.A1_COD CODIGO, SA1.A1_NOME NOME, SC5.C5_NUM


NUM
FROM SA1990 SA1, SC5990 SC5

Agora temos um exemplo de utilização de mais de uma tabela, para


referenciarmos a vários campos

 Ex. Select com uso de múltiplas tabelas com seleção de todas as


colunas de uma tabela, e apenas algumas de outra tabela

SELECT SA1.*, SC5.C5_NUM NUM


FROM SA1990 SA1, SC5990 SC5

 Ex. Select com concatenação de colunas

SELECT A1_COD + A1_LOJA CODIGO


FROM SA1990

Obs: Para Banco de dados Oracle e Informix utilize dois pipes ‘|’ no lugar de
‘+’.
1.2. Clausula WHERE

Esta clausula é uma das mais importantes do comando SELECT, pois é a partir dela
que filtramos os dados da query. O filtro que estaremos informando é muito parecido
com a que utilizamos em uma função indregua(), em ADVPL.

Sintaxe:
SELECT [<apelido>.] <Nome da Coluna> [<Nome de Retorno>], n....
FROM <Nome da Tabela> [<apelido>], n ...
WHERE <Condição de filtro>
<Condição de filtro> - informar uma expressão lógica que estará eliminando as linhas
que estiverem dentro do contexto informado.
Dentro da condição de filtro você pode utilizar os seguintes operadores:

4
SQL Básico

= Igualdade
> Maior que
< Menor que
>= Maior que ou igual a
<= Menor que ou igual a
<> Diferente
!= Diferente
!< Não menor a
!> Não maior a
AND Verdadeiro se ambas expressões forem verdadeiras
OR Verdadeiro se qualquer expressão for verdadeira
BETWEEN Verdadeiro se a expressão está dentro de um determinado intervalo
EXISTS Verdadeiro se uma subquery contém alguma linha
IN Verdadeiro se o operando é igual a uma das expressões da lista
NOT Inverte o valor de qualquer outra expressão boleana
LIKE ([ _ ],%) Verdadeiro se a expressão fixa for encontrada

 Ex. Select utilizando alguns dos operadores

SELECT *
FROM SE1990
WHERE E1_FILIAL = '01'
AND E1_CLIENTE BETWEEN ' ' AND 'zzzzzz'
AND E1_LOJA BETWEEN ' ' AND 'zz'
AND E1_PREFIXO LIKE 'P%'
AND E1_NUM BETWEEN ' ' AND 'zzzzzz'
AND E1_VENCREA BETWEEN '20000225' AND '20001231'
AND E1_EMISSAO <= '20001231'
AND E1_TIPO IN ('DP ','NF
','AB-','NCC','NCD')
AND NOT E1_EMISSAO = '20000401'
AND D_E_L_E_T_ <> '*'

Nota:A clausula where deve sempre compor o máximo


possível de campos que se adequam a uma chave de índice e
o máximo de filtro possível definido, desta forma as suas
query’s terão sempre um resposta rápida.

1.3. Funções de agregação

5
SQL Básico
O objetivo principal das funções de agregação é criar colunas de acumuladores de um
determinado agrupamento definido pela cláusula group by. Se esta cláusula não for
informada o retorno será sempre uma linha.

Sintaxe genérica para as funções:

SELECT [DISTINCT] [<FUNCAO>( ] <Nome da coluna|*>[)]


[ WHERE <Condicional de Filtro por linha> ]
[ GROUP BY <Colunas de agrupamento, coluna1, …, coluna16> ]
[ HAVING <Condição de agrupamento> ]

1.3.1. SUM

Esta função retorna a somatória de uma coluna(s) defina pelo usuário.

 Ex. Select que retorna o total de saldo de duplicatas de clientes

SELECT SUM(A1_SALDUP)
FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna o saldo total dos títulos em aberto eliminando os


registros excluídos da base de dados.

1.3.2. COUNT

Esta função totaliza o número de linhas na tabela, utlizando filtro para tal. Se
for informado o nome de uma coluna, a função contará apenas as linhas que
não estiverem com seu conteúdo nulo..

 Ex. Select que retorna o total de linhas da tabela

SELECT COUNT(*)
FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna o total de linhas não excluídas.

 Ex. Select que retorna o total de linhas da tabela, considerando


somente uma coluna

SELECT COUNT(A1_FILIAL)
FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna o total de linhas não excluídas. Se houver conteúdo


nulo em alguma linha, esta não será contada.

6
SQL Básico

1.3.3. AVG

Esta função retorna a média aritmética da coluna informada, filtrando as linhas


pela clausula where ou having.

 Ex. Select para média do saldo a receber de cada cliente

SELECT AVG(A1_SALDUP)
FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo retorna a média da coluna A1_SALDUP, não considerando


as linhas excluídas.

1.3.4. MAX

Esta função retorna o valor máximo da coluna especificada.

 Ex. Select para o maior valor da coluna R_E_C_N_O_

SELECT MAX(R_E_C_N_O_)
FROM SA1990

Este exemplo retornará o maior valor da coluna, o mesmo é muito usado


para se saber qual a próxima sequência disponível. Nunca despreze as
linhas excluídas, por que este número é sequencial e único na tabela.

1.3.5. MIN

Esta função retorna o valor mínimo da coluna especificada.

 Ex. Select do menor valor da data de emissão do pedido

SELECT MIN(C6_EMISSAO)
FROM SC6990
WHERE C6_CLI = ‘ 123456’
AND D_E_L_E_T_ <> ‘*’

Este exemplo retorna o menor valor da coluna C6_EMISSAO.

1.3.6. GROUP BY

Esta cláusula define quais colunas determinam o agrupamento do comando


select.

 Ex. Select para obter valor total de pedidos por cliente e data

SELECT C6_CLI, C6_LOJA, C6_EMISSAO, SUM(C6_VALOR) TOTAL


FROM SC6990

7
SQL Básico
WHERE D_E_L_E_T_ <> ‘*’
GROUP BY C6_CLI, C6_LOJA, C6_EMISSAO

Este exemplo faz a somatória da coluna C6_VALOR, efetuando o


agrupamento do resultado por cliente, loja e data.

 Ex. Select para obter quantidade de pedidos por cliente

SELECT C6_CLI, C6_LOJA, COUNT(*) QTD_PED


FROM SC6990
WHERE D_E_L_E_T_ <> ‘*’
AND C6_EMISSAO between ‘19990101’ and ‘19990630’
GROUP BY C6_CLI, C6_LOJA

Este exemplo retorna a quantidade de pedidos, agrupando o resultado por


cliente e loja, filtrando o resultado por data de emissão.

1.3.7. HAVING

Esta cláusula tem por finalidade filtrar os dados que estão numa condição de
agrupamento. Apesar de ser uma cláusula de filtro (semelhante à cláusula
where), ela é dependente da cláusula group by.

 Ex. Select para obter códigos inseridos com duplicidade

SELECT A1_COD, A1_LOJA, COUNT(*)


FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’
GROUP BY A1_COD, A1_LOJA
HAVING COUNT(*) > 1

Este exemplo faz a contagem do número de ocorrências de código e loja


em duplicidade. A clausula having elimina as ocorrências não duplicadas,
ou seja count(*) <= 1.

1.3.8. DISTINCT

Esta cláusula elimina repetições para a coluna informada.

 Ex. Select para obter todos os CFOs utilizados pelo cliente

SELECT DISTINCT F4_CF


FROM SF4990
WHERE D_E_L_E_T_ <> ‘*’

Este exemplo elimina do resultado os CFO’s repetidos.

 Ex. Select para obter código das filiais com linhas existentes (válido
para tabela com X2_MODO = ‘E’)

SELECT DISTINCT A1_FILIAL


FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’

8
SQL Básico

1.4. Função de String ( SUBSTRING/SUBSTR )

Esta função é idêntica a função SUBSTR usada em ADVPL, e pode ser utilizada em
qualquer ponto do select onde informamos uma coluna.

OBS: Para MSSQL Server e Sybase a sintaxe é SUBSTRING. Em Oracle e Informix a


sintaxe é SUBSTR.

Sintaxe genérica para as funções:

SUBSTR[ING](<Origem>, <n posição inicial>, <tamanho em bytes>)

 Ex. Select para apresentar parte do nome do cliente para todos os


clientes que possuem ‘5’ na segunda posição do código.

SELECT SUBSTRING(A1_NOME,1,20) NOME


FROM SA1990
WHERE SUBSTRING(A1_CODIGO,2,1) = ‘5’
AND D_E_L_E_T_ <> ‘*’

Não recomendamos a utilização da função na cláusula WHERE, pois o banco


terá que fazer uma busca em toda a tabela, por não possuir índice do conteúdo
a ser filtrado.

1.5. ORDER BY

Esta cláusula ordena o resultado do select independente do índice utilizado para


acessar o dado. O resultado pode ser ordenado de forma crescente(ASC) ou
decrescente (DESC).
Um detalhe importante para performance do comando é tentar utilizar na cláusula
ORDER BY as mesmas colunas que compõe um índice já existente no banco de
dados, caso contrário o banco terá que ordenar os dados na área temporária
(TempDB) o que pode prejudicar a performance do comando.

Sintaxe :

SELECT …
FROM …
ORDER BY <Coluna1> [ASC|DESC],…,<Coluna16> [ASC|DESC]

 Ex. Select para apresentar o nome de todos os clientes por ordem


decrescente de nome.

SELECT A1_NOME
FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’
ORDER BY A1_NOME DESC

 Ex. Select para apresentar os cliente por ordem de código e loja de


forma crescente.

SELECT A1_COD, A1_LOJA


FROM SA1990
WHERE D_E_L_E_T_ <> ‘*’
ORDER BY A1_COD, A1_LOJA

9
SQL Básico
Note que neste exemplo não é necessário informar a expressão ASC, para
obter o resultado de forma crescente.

Nota: Em alguns casos de query´s você irá perceber que o resultado já


estará apresentando as linhas por uma certa ordenação, isto quer dizer que
o banco de dados utilizou um índice para resolver o problema, mas isto não
indica que sempre o dado será retornado nesta ordem, portanto se você
precisar que os dados retornados estejam ordenados você dever sempre
informa o ORDER BY.
1.6. Joins

Esta operação é uma das mais poderosas expressões de um comando select, pois
com ela podemos relacionar tabelas obtendo informações cruzadas. Este comando
pode ser escrito de duas formas, porém alguns bancos suportam apenas uma delas.
Estaremos apresentado esta forma e comentaremos suas diferenças.

O relacionamento entre as tabelas é feito utilizando o símbolo de igualdade entre duas


colunas, sendo uma coluna de cada tabela. Lembre-se que o relacionamento é feito
de forma binária, ou seja, só podemos relacionar duas tabelas de cada vez, mas
podemos com isto relacionar quantas tabelas desejarmos, limitado pela capacidade do
banco de dados.

Como recomendação devemos sempre tentar relacionar no máximo quatro tabelas,


lógico que existe exceções, mas sempre que houver o relacionamento de muitas
tabelas o banco de dados precisará de mais tempo para conseguir resolver o
problema e em alguns caso não será viável. Existem várias situações que dependem
de experiência e teste para conseguirmos chegar na melhor solução possível.

Sempre que utilizarmos joins devemos sempre informar todas as tabelas que serão
relacionadas na clausula from e todos os seus relacionamentos na clausula where se
por acaso não for feito o relacionamento de uma destas tabelas o banco de dados
estará fazendo um produto cartesiano (CROSS JOIN) entre todas as linhas da tabela
que não foi relacionado com as demais tabelas. Se isto acontecer o servidor poderá
ter sérios problemas de uso excessivo de CPU.

Existem Cinco tipos de JOINS:

1.6.1. INNER JOIN

Um join simples é formado pelo relacionamento de duas ou mais tabelas.

 Ex. Select para retornar todas os pedidos de venda e o nome do


cliente

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5-
>SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

 Ex. Select para retornar todas os pedidos de venda, nome do cliente e


o nome do Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME

10
SQL Básico
FROM SC5990 SC5, SA1990 SA1, SA3990 SA3
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SA3.A3_FILIAL = ‘01’
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5-
>SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5-
>SA1
AND SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1-
>SA3
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

1.6.2. LEFT JOIN ou LEFT OUTER JOIN

O resultado de um left join inclui todas as linhas da tabela que foi


específica a esquerda da clausula LEFT OUTER, ou seja, independente
de existir ou não um dado relacionado na tabela informada mais à
direita da tabela todas as linhas referentes a tabela da esquerda serão
retornadas. Nas linhas que não existe um linha de relação com a tabela
a direita os campos desta tabela serão retornados com valor nulo.
O símbolo ( *= ) representa um LEFT JOIN para o MSSQL Server,
Sybase, o campo indicado do lado do símbolo (*) será o da tabela que
você deseja que todas as linhas sejam retornadas independentemente
da existência do dado da coluna mais a direita, vamos ver exemplos de
query’s para estes Bancos de Dados.
 Ex. Select para retornar todas os pedidos de venda e o nome do
cliente mesmo que não exista o cliente

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE *= SA1.A1_COD <= Define o rel.SC5-
>SA1
AND SC5.C5_LOJACLI *= SA1.A1_LOJA <= Define o rel.SC5-
>SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

 Ex. Select para retornar todas os pedidos de venda, nome do cliente e


o nome do Vendedor mesmo que não exista o Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME


FROM SC5990 SC5, SA1990 SA1, SA3990 SA3
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SA3.A3_FILIAL = ‘01’
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5-
>SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5-
>SA1
AND SA1.A1_VEND *= SA3.A3_COD <= Define o rel.SA1-
>SA3
AND SC5.D_E_L_E_T_ <> '*'

11
SQL Básico
AND SA1.D_E_L_E_T_ <> '*'

O símbolo (+ ) representa um LEFT JOIN para o Oracle, o campo


indicado do lado do campo que será o da tabela que você deseja que
todas as linhas sejam retornadas independentemente da existência do
dado da coluna mais a direita, vamos ver exemplos de query’s para
estes Bancos de Dados.
 Ex. Select para retornar todas os pedidos de venda e o nome do
cliente mesmo que não exista o cliente

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND (+) SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5-
>SA1
AND (+) SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5-
>SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

 Ex. Select para retornar todas os pedidos de venda, nome do cliente e


o nome do Vendedor mesmo que não exista o Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME


FROM SC5990 SC5, SA1990 SA1, SA3990 SA3
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SA3.A3_FILIAL = ‘01’
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5-
>SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5-
>SA1
AND (+) SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1-
>SA3
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

Na clausula from especificamos a palavra OUTER que irá representar


um LEFT JOIN para o Informix, o campo da esquerda será o da tabela
que você deseja que todas as linhas sejam retornadas
independentemente da existência do dado da coluna mais à direita,
vamos ver exemplos de query’s para estes Bancos de Dados.

 Ex. Select para retornar todas os pedidos de venda e o nome do


cliente mesmo que não exista o cliente

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5 OUTER, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5->SA1
AND SC5.D_E_L_E_T_ <> '*'

12
SQL Básico
AND SA1.D_E_L_E_T_ <> '*'

 Ex. Select para retornar todas os pedidos de venda, nome do cliente e


o nome do Vendedor mesmo que não exista o Vendedor

SELECT SC5.C5_NUM, SA1.A1_NOME, SA3.A3_NOME


FROM SC5990 SC5, SA1990 SA1 OUTER, SA3990 SA3
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SA3.A3_FILIAL = ‘01’
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5-
>SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5-
>SA1
AND SA1.A1_VEND = SA3.A3_COD <= Define o rel.SA1-
>SA3
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

Nota: Não é possível fazer outer joins subsequentes, ou seja, se


você fizer outer join de uma tabela que logo em seguida tem um
relacionamento com outra tabela.

1.6.3. RIGHT JOIN or RIGHT OUTER JOIN

O resultado de um Right join inclui todas as linhas da tabela que foi


específica a direita da clausula RIGHT OUTER, ou seja, independente
de existir ou não um dado relacionado na tabela informada mais à
esquerda da tabela todas as linhas referentes a tabela da direita serão
retornadas. Nas linhas que não existe um linha de relação com a tabela
a direita os campos desta tabela serão retornados com valor nulo.

O símbolo ( =* ) representa um RIGHT JOIN para o MSSQL Server,


Sybase, o campo indicado do lado do símbolo (*) será o da tabela que
você deseja que todas as linhas sejam retornadas independentemente
da existência do dado da coluna mais a esquerda, vamos ver
exemplos de query’s para estes Bancos de Dados.
 Ex. Select para retornar todos os clientes mesmo que não exista
pedidos relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE =* SA1.A1_COD <= Define o rel.SC5-
>SA1
AND SC5.C5_LOJACLI =* SA1.A1_LOJA <= Define o rel.SC5-
>SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

13
SQL Básico

O símbolo ( + ) representa um RIGHT JOIN para o Oracle, o campo


indicado do lado do símbolo (+) será o da tabela que você deseja que
todas as linhas sejam retornadas independentemente da existência do
dado da coluna mais à esquerda, vamos ver exemplos de query’s para
estes Bancos de Dados.
 Ex. Select para retornar todos os clientes mesmo que não exista
pedidos relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE = SA1.A1_COD (+) <= Define o rel.SC5-
>SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA (+) <= Define o rel.SC5-
>SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

Na clausula from especificamos a palavra OUTER que irá representar


um RIGHT JOIN para o Informix, o campo indicado do lado direito que
você deseja que todas as linhas sejam retornadas independentemente
da existência do dado da coluna mais à esquerda, vamos ver exemplos
de query’s para estes Bancos de Dados.
 Ex. Select para retornar todos os clientes mesmo que não exista
pedidos relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1 OUTER
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.C5_CLIENTE = SA1.A1_COD <= Define o rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o rel.SC5-
>SA1
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

Nota: Não é possível fazer outer joins subsequentes, ou seja, se você


fizer outer join de uma tabela que logo em seguida tem um
relacionamento com outra tabela.

1.6.4. FULL JOIN or FULL OUTER JOIN

Um full outer join é o resultado de um inner join + right join + left join ,
desta forma você terá o resultado com todas as linhas da primeira
tabela mais o resultado com todas as linhas da Segunda tabela e
apresentará em mesma linha os itens que forem possíveis de
relacionamento.
Exemplo para o Banco MSSQL Server e Sybase

 Ex. Select para retornar todos os clientes e todos os pedidos mesmo


que não exista pedidos ou clientes relacionados

14
SQL Básico

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5 FULL OUTER SA1990 SA1
ON SC5.C5_CLIENTE = SA1.A1_COD <= Define o
rel.SC5->SA1
AND SC5.C5_LOJACLI = SA1.A1_LOJA <= Define o
rel.SC5->SA1
WHERE SC5.C5_FILIAL = '01'
AND SA1.A1_FILIAL = ' '
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

Nota: Nos demais Bancos de Dados não existem este tipo de join. Mas
existem outras formar de resolver este problema utilizando inner join +
left join + right join + unions , iremos ver a seguir como utilizar o union
desta forma teremos a solução também para os demais bancos de
dados, e até mesmo os que tem a opção.

1.6.5. CROSS JOIN

É o mais simples e dificilmente utilizado, ele simplesmente faz um


produto cartesiano em as tabelas especificadas na clausula where. O
comando é o mesmo em todos os Bancos de Dados.
 Ex. Select para retornar todos os clientes e todos os pedidos mesmo
que não exista pedidos ou clientes relacionados

SELECT SC5.C5_NUM, SA1.A1_NOME


FROM SC5990 SC5, SA1990 SA1

Nota: Existem vários casos de programadores que esquecem de


relacionar algumas tabelas, e acontece um grande problema de
performance. Se você esquecer de relacionar uma tabela e a mesma
tiver um número de linhas muito grande nós estaremos consumindo
processador e i/o de disco inutilmente.
1.7. Unions

A expressão UNION permite você combinar o resultado de dois ou mais


SELECTs em um único resultado. Uma das restrições para combinar o
uso de UNION é que devemos ter uma estrutura única em cada um
dos SELECTs, ou seja, os mesmos devem ter o mesmo número de
colunas devem ter tipos de dados compatíveis.

15
SQL Básico
 Ex. Select para retornar todos os clientes da empresa 01 e da empresa
02 desconsiderando duplicidades

SELECT A1_COD, A1_LOJA, A1_NOME


FROM SA1990

1.7.1. UNION

SELECT A1_COD, A1_LOJA, A1_NOME


FROM SA1010

 Ex. Select para retornar todos os clientes da empresa 01 e da empresa


02 considerando todas duplicidades

SELECT A1_COD, A1_LOJA, A1_NOME


FROM SA1990

1.7.2. UNION ALL

SELECT A1_COD, A1_LOJA, A1_NOME


FROM SA1010

Nota: Existem vários casos de programadores que esquecem de


informar a clausula ALL, e acontece um grande problema que parece
estar faltando registros de dados nos programas.
1.8. SUB SELECTS

Sub-Selects é utilizado na clausula where onde pode ser utilizado para fazer relação
de verificação de um determinado dado da tabela original com várias linhas de uma
outra tabela sem obrigatoriamente ser parte integrante de um join.

 Ex. Select para retornar todos os clientes que compraram o produto


‘x’, utilizando operador IN

SELECT DISTINCT SA1.A1_NOME


FROM SA1990 SA1, SC5990 SC5
WHERE SA1.A1_FILIAL = ' '
AND SC5.C5_FILIAL = '01'
AND SC5.C5_CLIENTE = SA1.A1_COD
AND SC5.C5_LOJACLI = SA1.A1_LOJA
AND SC5.C5_NUM IN ( SELECT C6_NUM
FROM SC6990 SC6
WHERE SC6.FILIAL = ‘ ’

16
SQL Básico

AND SC6.C6_NUM =
SC5.C5_NUM
AND SC6.C6_PRODUTO = ‘X’
AND SC6.D_E_L_E_T_ <> ‘*’ )
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

 Ex. Select para retornar todos os clientes que compraram o produto


‘x’, utilizando operador EXISTS

SELECT DISTINCT SA1.A1_NOME


FROM SA1990 SA1, SC5990 SC5
WHERE SA1.A1_FILIAL = ' '
AND SC5.C5_FILIAL = '01'
AND SC5.C5_CLIENTE = SA1.A1_COD
AND SC5.C5_LOJACLI = SA1.A1_LOJA
AND EXISTS ( SELECT *
FROM SC6990 SC6
WHERE SC6.FILIAL = ‘ ’
AND SC6.C6_NUM = SC5.C5_NUM
AND SC6.C6_PRODUTO = ‘X’
AND SC6.D_E_L_E_T_ <> ‘*’ )
AND SC5.D_E_L_E_T_ <> '*'
AND SA1.D_E_L_E_T_ <> '*'

2. TCQuery

Executa uma Query no servidor e coloca seu retorno em uma WorkArea.


Importante:
Durante o processo de compilação, a sintaxe TCQUERY() é substituída pelas
expressão:
dbUseArea(.T.,"TOPCONN",TcGenQry(,,cQuery), “ALIAS” ,.T.,.F.)
Esta substituição é realizada conforme as definições do include TOPCONN.CH.
Desta forma é recomendável a utilização direta da sintaxe DbUseArea() +TcGeQry().

17
SQL Básico

Sintaxe: TCQUERY cSQLExpr ALIAS cAlias NEW VIA "TOPCONN"

Parâmetros:

cSQLExpr Expressão SQL a ser enviada ao servidor.


ALIAS cAlias Especifica um nome para a Work Area a ser aberta.
NEW Abre a tabela <cTable> na próxima Work Area disponível. Se esta
clausula não for especificada, <cTable> será na Work Area
corrente.
VIA Este parâmetro indica ao ADVPL que está Work Area será
"TOPCONN" gerenciada pelo TOPconnect.

Observações
A Work Area criada com o comando TCQUERY é READ-ONLY, portanto não é
permitido o uso de APPEND's ou REPLACE's.

O TOPConnect tem apenas um cursor para a Query executada portando apenas os


seguintes comandos são suportados em uma Work Area criada com TCQUERY:
 GO TOP - DbGoTop()
 GO BOTTOM - DbGoBottom()
 SKIP - DbSkip()
 Eof()
 Bof()
Ao executar uma Query que retorne um ou mais valores calculados, o nome dos
campos da WorkArea serão COLUMN1, COLUMN2... COLUMNn.

Exemplo:
//Abre a tabela de Clientes em uma nova WorkArea
cQuery := "SELECT a.codigo, b.nome FROM CLIENTES a, CLIDATA b "
cQuery += "WHERE a.CODIGO = b.CODIGO ORDER BY CODIGO,NOME "
TCQUERY cQuery ALIAS CLIENTES NEW VIA "TOPCONN"
dbGoTop()
While !Eof()
ALERT(CODIGO+"|"+NOME)
dbSkip()
end
cQuery := 'SELECT SUM(VALOR),SUM(SALDO) FROM CUSTOMER'
TCQUERY cQuery NEW VIA "TOPCONN"
ALERT(CValToChar(COLUMN1)+"|"+CValToChar(COLUMN2))
// COLUMN1 - Somatoria dos valores
// COLUMN2 - Somatoria dos saldos

Para saber mais funções auxiliares ao DBAccess acesse:


http://tdn.totvs.com/display/tec/DBAccess

18
SQL Básico

3. Embedded SQL

O objetivo do Embedded SQL é facilitar a escrita e leitura de queries. Para isso, foi
definida uma sintaxe para que se possa escrever a query diretamente no código
AdvPL, sem a necessidade de ficar concatenando pedaços de string para compor a
string final.
Disponibilidade do recurso
Este recurso está disponível nos produtos Microsiga Protheus 10 e 11.
A utilização do Embedded SQL divide-se em:
Compilação de código-fonte.
Execução de código-fonte.
Para compilar um código-fonte com o código escrito no formato Embedded, deve-se
utilizar o produto Microsiga Protheus, com build igual ou superior a 7.00.050721P, em
um ambiente com repositório para TOTVS | DBAccess (RPODB=TOP). A utilização
deste recurso, também depende da atualização da LIB.
Exemplo básico - Código-fonte atual
cQuery : 'SELECT SE2.E2_PREFIXO,SE2.E2_NUM '
cQuery += 'FROM '+RetSqlTable('SE2')+' SE2,'+RetSqlTable('QEK')+'
QEK '
cQuery += 'WHERE SE2.E2_FILIAL= '+xfilial('SE2')+' AND '
cQuery += 'SE2.E2_PREFIXO<> ''+cPrefixo+'' AND '
cQuery += 'SE2.D_E_L_E_T_ = ' ' '
cQuery += 'ORDER BY '+RetSqlOrder('SE2')
dbUseArea(.T.,'TOPCONN',TcGenQry(,,cQuery),'E2TEMP',.T.,.T.)
TCSetField('E2TEMP','E2_EMISSAO','D',8,0)

Exemplo básico - Utilizando Embedded SQL


BeginSql alias 'E2TEMP'
column E2_EMISSAO as Date

%noparser%

SELECT SE2.E2_PREFIXO,SE2.E2_NUM
FROM %table:SE2% SE2,%table:QEK% QEK
WHERE SE2.E2_FILIAL= %xfilial:SE2% AND
SE2.E2_PREFIXO<> %exp:cPrefixo% AND
SE2.%notDel%
ORDER BY %Order:SE2%
EndSql

Características operacionais - Sintaxe


 O bloco de código onde será escrito o comando SELECT, deve sempre ser
iniciado com BeginSQL Alias e finalizado com EndSQL.
 Partes do código-fonte que devem ser substituídos aparecem entre os sinais
de % (porcentagem). Essas expressões possuem tratamentos especiais em
momento de execução.

19
SQL Básico

 Qualquer instrução colocada entre BeginSQL ... EndSQL, que não seja uma
expressão %...%, será inserida na query que será enviada para o banco de
dados, de forma literal.
 Variáveis, expressões e funções aparecem iniciando com %exp:%.
 Em column deve-se especificar campos da query que são do tipo de dado
data, lógico ou numérico (DATE, LOGIC, NUMBER). Esta linha é trocada por
chamadas à função TCSetField().
 %noparser% indica que a query não deve passar pela função ChangeQuery()
antes de ser enviada ao banco de dados. Caso não especificado, o padrão é a
string da query ser passada automaticamente pela função ChangeQuery().
 %table:% é substituída por RetSqlName().
 %notDel% é substituída por D_E_L_E_T_=' '.
 %Order:% é substituída por SqlOrder (->(IndexKey())).

Há 3 opções para o %Order:

1º Opção:
%Order: % traduzido para SqlOrder(->(IndexKey()))

2º Opção:
%Order: , % traduzido para SqlOrder(->(IndexKey()))

3º Opção:
%Order: , % traduzido para SqlOrder(->(DBNickIndexKey()))
Limitação
Não é permitido incluir funções no meio do código embedded. Se precisar, o valor
deve ser guardado em uma variável antes do início do BeginSQL.
Exemplo
tam_cp := GetE2ValorSize()
BeginSql
alias 'E2TEMP'
column E2_EMISSAO as Date,
E2_VALOR as Numeric(tam_cp,2)
. . .
EndSql

Erros de compilação

20
SQL Básico

Caso seja utilizado algum argumento inválido para especificar as colunas ou erros de
sintaxe nas expressões que serão transformadas para montagem da query, a
compilação do código-fonte é interrompida com a ocorrência Syntax Error, informando
a linha em que a primeira ocorrência foi encontrada.

EndSQL (Error C2001 Syntax error:)


Caso a ocorrência de compilação aponte diretamente para a linha do código-fonte, em
que está escrita a instrução EndSQL, verifique se existe algum espaço em branco ou
tabulação, a partir do início da linha, antes da instrução EndSQL. A versão atual deste
ambiente não suporta esta declaração, exigindo que a instrução EndSQL seja alinhada
à esquerda do código-fonte, sem espaço ou tabulações.

Erros de execução
Query Argument Error: Alias [XXX] already in suse.
Caso a instrução BeginSQL especifique um alias que já esteja aberto (em uso), a
aplicação é abortada com ocorrência de erro fatal, informando em XXX o alias
utilizado.

Query Argument Error: Invalid Value Type [X]


Caso alguma expressão informada na query, através da tag %exp:...%, retorne um
valor do tipo diferente de C (Caracter), D (Data), N (Numérico) ou L (Lógico), a
aplicação é abortada com ocorrência de erro, em que o tipo do argumento inesperado
é apresentando em [X].

Type Mismach on +
Esta ocorrência, se reproduzida, informará na pilha de chamadas o número da linha do
código-fonte correspondente à instrução EndSQL. Essa ocorrência ocorre caso
alguma função intermediária do engine do Embedded SQL, excluíndo-se as funções
especificadas na query com a sintaxe %exp:...%, retornar um conteúdo não caractere
que será acrescentado na query. Esta ocorrência é mais dificil de localizar, sendo útil
nestes casos a análise do arquivo temporário gerado pelo TOTVS | Development
Studio, no momento da compilação.

Help NOFUNCW - Função __EXECSQL


Caso um código-fonte Embedded SQL seja executado em um repositório que não
tenha sido atualizado ou que não seja um repositório para o ambiente TOTVS
| DBAccess (RPODB=TOP), a aplicação exibirá essa ocorrência, indicando que a
função interna de execução da query não está presente no ambiente. Verifique se a
LIB está atualizada e se o RPO, em uso, pertence a um ambiente TOTVS | DBAccess.

Característica operacionais - Depuração

21
SQL Básico

Dada a montagem da query, não é possível depurar o bloco do código/codeblock


compreendido entre as intruções BeginSQL e EndSQL, não sendo considerados
pontos de parada de depuração (BreakPoints), caso colocados neste intervalo do
código. A colocação de pontos de parada deve ser realizada antes ou depois desse
bloco.

Função auxiliar - GetLastQuery()


Após a abertura do cursor, no alias especificado, a função GetLastQuery() retorna um
array, com 5 elementos, onde estão disponíveis as seguintes informações sobre a
query executada.
[1] cAlias - Alias usado para abrir o cursor.
[2] cQuery - Query executada.
[3] aCampos - Array de campos com critério de conversão especificados.
[4] lNoParser - Caso verdadeiro (.T.), não foi utilizada a função ChangeQuery() na
string original.
[5] nTimeSpend - Tempo, em segundos, utilizado para abertura do cursor.
Exemplo mais completo
AdvPL
BeginSql alias 'E2TEMP'
column E2_EMISSAO as Date,
column E2_VALOR as Numeric(tam_cp,2)
column QEK_SKLDOC As Logical

%noparser%

SELECT SE2.E2_PREFIXO,
SE2.E2_NUM,
SE2.E2_FORNECE,
SE2.E2_LOJA,
SE2.E2_VALOR,
SE2.D_E_L_E_T_ DEL1,
QEK.D_E_L_E_T_ DEL2 ,
QEK.QEK_SKLDOC,
SE2.R_E_C_N_O_ SE2RECNO
FROM
%table:SE2% SE2,%table:qeK% QEK
WHERE
SE2.E2_FILIAL= %xfilial:SE2% AND
qek.%notDel% and
SE2.E2_PREFIXO<> %exp:cPrefixo% AND
SE2.E2_NUM<> %exp:(cAlias)->M0_CODIGO% AND
SE2.E2_NUM<>45 AND
SE2.E2_FORNECE=%exp:Space(Len(SE2->E2_FORNECE))% AND
SE2.E2_EMISSAO<>%exp:MV_PAR06% AND
SE2.E2_LOJA<>%exp:MV_PAR05% AND
SE2.E2_VALOR<>%exp:MV_PAR04% AND
qek.QEK_SKLDOC<>%exp:MV_PAR03% And
SE2.%notDel%
ORDER BY %Order:SE2,1%
EndSql

Código-fonte gerado pelo pré-compilador (PPO)

22
SQL Básico
__execSql('E2TEMP',' SELECT SE2.E2_PREFIXO,SE2.E2_NUM,
SE2.E2_FORNECE, SE2.E2_LOJA,SE2.E2_VALOR, SE2.D_E_L_E_T_ DEL1,
QEK.D_E_L_E_T_
DEL2 , QEK.QEK_SKLDOC, SE2.R_E_C_N_O_ SE2RECNO FROM
'+RetSqlName('SE2')+' SE2, '+RetSqlName('QEK')+' QEK WHERE
SE2.E2_FILIAL= '' +xFilial
('SE2')+'' AND qek.D_E_L_E_T_= ' ' and SE2.E2_PREFIXO<>
'+___SQLGetValue(CPREFIXO)+' AND SE2.E2_NUM<>
'+___SQLGetValue((CALIAS)
->M0_CODIGO)+' AND SE2.E2_NUM<>45 AND SE2.E2_FORNECE=
'+___SQLGetValue(SPACE(LEN(SE2->E2_FORNECE)))+' AND SE2.E2_EMISSAO<>
'+___SQLGetValue(MV_PAR06)+' AND SE2.E2_LOJA<>
'+___SQLGetValue(MV_PAR05)+' AND SE2.E2_VALOR<>
'+___SQLGetValue(MV_PAR04)+' AND
qek.QEK_SKLDOC<> '+___SQLGetValue(MV_PAR03)+' And SE2.D_E_L_E_T_= '
' ORDER BY '+
SqlOrder(SE2->(IndexKey(1))),{{'E2_EMISSAO','D',8,0},
{'E2_VALOR','N',tam_cp,2},{'QEK_SKLDOC','L',1,0}},.T.)

Link TDN: http://tdn.totvs.com/display/tec/Embedded+SQL+-+Facilitador+de+queries

23

Você também pode gostar