No meu último artigo, descrevi de forma aproximada como o SQL Standard difere do T-SQL e quem deve aprender qual. Agora eu gostaria de focar nas diferenças de sintaxe e ilustrar essas diferenças com exemplos. Se você acha que o T-SQL é uma extensão implementando todas as características do SQL padrão, você não está certo. Entretanto, no SQL Server, você encontrará quase todas as características do padrão SQL. Neste artigo, encontrará exemplos de algumas das diferenças de sintaxe entre SQL standard e Transact-SQL.
#1 Nomes de Objectos de Base de Dados
Em sistemas de base de dados relacionais, nomeamos tabelas, vistas e colunas, mas por vezes precisamos de usar o mesmo nome como palavra-chave ou usar caracteres especiais. Em SQL padrão, você pode colocar este tipo de nome entre aspas (“”), mas em T-SQL, você também pode colocá-lo entre parênteses (). Veja estes exemplos para o nome de uma tabela em T-SQL:
CREATE TABLE dbo.test."first name" ( Id INT, Name VARCHAR(100));CREATE TABLE dbo.test. ( Id INT, Name VARCHAR(100));
Apenas o primeiro delimitador (as aspas) para o nome especial também faz parte do padrão SQL.
O que é diferente numa instrução SELECT?
O padrão SQL não tem uma sintaxe para uma consulta que retorna valores ou valores provenientes de expressões sem referência a qualquer coluna de uma tabela, mas o MS SQL Server permite este tipo de expressão. Como? Você pode utilizar uma instrução SELECT sozinha com uma expressão ou com outros valores que não provenham de colunas da tabela. No T-SQL, parece com o exemplo abaixo:
SELECT 12/6 ;
Nesta expressão, não precisamos de uma tabela para avaliar 12 divididos por 6, portanto, a instrução FROM e o nome da tabela podem ser omitidos.
#3 Limiting Records in a Result Set
No padrão SQL, você pode limitar o número de registros nos resultados usando a sintaxe ilustrada abaixo:
SELECT * FROM tab FETCH FIRST 10 ROWS ONLY
T-SQL implementa esta sintaxe de uma maneira diferente. O exemplo abaixo mostra a sintaxe do MS SQL Server:
SELECT * FROM tab ORDER BY col1 DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY;
Como você observa, isto usa uma cláusula ORDER BY. Outra forma de seleccionar linhas, mas sem ORDER BY, é usando a cláusula TOP em T-SQL:
SELECT TOP 10 * FROM tab;
#4 Geração automática de valores
O padrão SQL permite que você crie colunas com valores gerados automaticamente. A sintaxe para fazer isto é mostrada abaixo:
CREATE TABLE tab (id DECIMAL GENERATED ALWAYS AS IDENTITY);
No T-SQL também podemos gerar valores automaticamente, mas desta forma:
CREATE TABLE tab (id INTEGER IDENTITY);
#5 Funções Matemáticas
As funções matemáticas comuns são parte do padrão SQL. Uma dessas funções matemáticas é o CEIL(x), que não encontramos no T-SQL. Em vez disso, o T-SQL fornece as seguintes funções não-padrão: SIGN(x), ROUND(x,) para arredondar o valor decimal x para o número de casas decimais, TRUNC(x) para truncatura para um determinado número de casas decimais, LOG(x) para retornar o logaritmo natural para um valor x, e RANDOM() para gerar números aleatórios. O número mais alto ou mais baixo de uma lista no padrão SQL é retornado pelas funções MAX(list) e MIN(list), mas no Transact-SQL, você usa as funções GREATEST(list) e LEAST(list).
T-SQL function ROUND:SELECT ROUND(col) FROM tab;
#6 Aggregate Functions
Nós encontramos outra diferença de sintaxe com as funções agregadas. As funções COUNT, SUM, e AVG levam todas um argumento relacionado a uma contagem. O T-SQL permite o uso de DISTINCT antes desses valores de argumento para que as linhas sejam contadas somente se os valores forem diferentes de outras linhas. O padrão SQL não permite o uso do DISTINCT nestas funções.
Standard SQL:SELECT COUNT(col) FROM tab;T-SQL:SELECT COUNT(col) FROM tab;SELECT COUNT(DISTINCT col) FROM tab;
Mas no T-SQL não encontramos uma função de covariância populacional: COVAR_POP(x,y), que é definido no padrão SQL.
#7 Recuperando Partes de Datas e Horas
A maioria dos sistemas de base de dados relacionais fornecem muitas funções para operar em datas e horas.
No SQL padrão, a função EXTRACT(YEAR FROM x) e funções similares para selecionar partes de datas são diferentes das funções T-SQL como YEAR(x) ou DATEPART(ano, x).
Há também uma diferença na obtenção da data e hora actuais. SQL padrão permite obter a data atual com a função CURRENT_DATE, mas no MS SQL Server, não há uma função similar, então temos que usar a função GETDATE como argumento na função CAST para converter para um tipo de dados DATE.
#8 Operating on Strings
Using functions to operate on strings também é diferente entre o padrão SQL e o T-SQL. A principal diferença é encontrada na remoção de espaços de fuga e de liderança de uma cadeia de caracteres. No SQL padrão, existe a função TRIM, mas no T-SQL, existem várias funções relacionadas: TRIM (remove trailing and leading spaces), LTRIM (remove leading spaces), e RTRIM (remove trailing spaces).
Uma outra função de string muito utilizada é SUBSTRING.
A sintaxe SQL padrão para a função SUBSTRING parece:
SUBSTRING(str FROM start )
mas em T-SQL, a sintaxe desta função parece:
SUBSTRING(str, start, length)
Existem razões às vezes para adicionar valores vindos de outras colunas e/ou strings adicionais. SQL padrão permite que a seguinte sintaxe faça isto:
Como você pode ver, esta sintaxe faz uso do operador || para adicionar uma string a outra.
Mas o operador equivalente em T-SQL é o caractere de mais. Veja este exemplo:
SELECT col1 + col2 FROM tab;
No SQL Server, também temos a possibilidade de usar a função CONCAT concatenando uma lista de strings:
SELECT CONCAT(col1, str1, col2, ...) FROM tab;
Também podemos repetir um caractere várias vezes. SQL padrão define a função REPEAT(str, n) para fazer isso. O Transact-SQL fornece a função REPLICATE. Por exemplo:
SELECT REPLICATE(str, x);
onde x indica quantas vezes repetir a string ou caractere.
#9 Operador de Desigualdade
Durante a filtragem de registos numa instrução SELECT, por vezes temos de utilizar um operador de desigualdade. SQL padrão define <> como este operador, enquanto T-SQL permite tanto o operador padrão como o != operador:
SELECT col3 FROM tab WHERE col1 != col2;
#10 ISNULL Função
Em T-SQL, temos a capacidade de substituir valores NULL vindos de uma coluna usando a função ISNULL. Esta é uma função que é específica para o T-SQL e não está no padrão SQL.
SELECT ISNULL(col1) FROM tab;
Que partes da sintaxe DML são diferentes?
No T-SQL, a sintaxe básica das consultas DELETE, UPDATE, e INSERT é a mesma do padrão SQL, mas as diferenças aparecem em consultas mais avançadas. Vamos olhar para elas.
#11 Palavra-chave OUTPUT
A palavra-chave OUTPUT ocorre nas instruções DELETE, UPDATE, e INSERT. Não está definida em SQL.
Usando T-SQL, podemos ver informação extra retornada por uma consulta. Retorna os valores antigos e novos em UPDATE ou os valores adicionados usando INSERT ou deletados usando DELETE. Para ver esta informação, temos de usar prefixos em INSERT, UPDATE, e DELETE.
UPDATE tab SET col='new value' OUTPUT Deleted.col, Inserted.col;
Vemos o resultado da alteração de registros com os valores anteriores e novos em uma coluna atualizada. O padrão SQL não suporta este recurso.
#12 Sintaxe para INSERT INTO … SELECT
Uma outra estrutura de uma consulta INSERT INTO é INSERT INTO … SELECT. T-SQL permite inserir dados de outra tabela em uma tabela de destino. Olhe para esta consulta:
INSERT INTO tab SELECT col1,col2,... FROM tab_source;
Não é uma característica padrão mas uma característica do SQL Server.
#13 Cláusula FROM no DELETE e UPDATE
SQL Server fornece uma sintaxe estendida do UPDATE e DELETE com cláusulas FROM. Você pode usar DELETE com FROM para usar as linhas de uma tabela para remover linhas correspondentes em outra tabela, referindo-se a uma chave primária e uma chave estrangeira. Da mesma forma, você pode usar UPDATE com FROM para atualizar linhas de uma tabela referindo-se às linhas de outra tabela usando valores comuns (chave primária em uma tabela e chave estrangeira na segunda, por exemplo, o mesmo nome da cidade). Aqui está um exemplo:
DELETE FROM BookFROM AuthorWHERE Author.Id=Book.AuthorId AND Author.Name IS NULL;
UPDATE BookSET Book.Price=Book.Price*0.2FROM AuthorWHERE Book.AuthorId=Author.Id AND Author.Id=12;
O padrão SQL não fornece esta sintaxe.
#14 INSERT, UPDATE, and DELETE With JOIN
Pode também usar INSERT, UPDATE, and DELETE usando JOIN para se ligar a outra tabela. Um exemplo disto é:
DELETE ItemOrder FROM ItemOrderJOIN Item ON ItemOrder.ItemId=Item.IdWHERE YEAR(Item.DeliveredDate) <= 2017;
Esta funcionalidade não está no padrão SQL.
Resumo
Este artigo não cobre todos os problemas sobre diferenças de sintaxe entre o padrão SQL e o T-SQL usando o sistema MS SQL Server. No entanto, este guia ajuda a apontar algumas características básicas características apenas do Transact-SQL e qual sintaxe SQL standard não é implementada pelo MS SQL Server.