António Rocha Nuno Melo e Castro
! Transact-SQL (T-SQL) Extensão ao SQL Permite controlo do fluxo de execução Permite comandos DDL (contrariamente ao PLSQL) T-SQL combina: poder de manipulação de dados do SQL com poder de processamento das linguagens procedimentais
#$%#$ Variáveis Tipos de dados escalares Controlo do fluxo de execução Funções integradas Gestão de cursores Processamento de excepções Código armazenado na base de dados "
'%( A unidade de programação é semelhante ao já visto para PL/SQL, podendo ter: Blocos de código sem nome scripts. Normalmente são construídos dinamicamente e executados apenas uma vez. Blocos com nome Procedures e functions - são guardados na BD. Este blocos normalmente não são alterados depois de construídos e são executados várias vezes. Os subprogramas são executados explicitamente via uma chamada a um procedure ou function. Triggers: São também guardados na BD. Este blocos normalmente não são alterados depois de construídos e são executados várias vezes. Os Triggers são executados implicitamente quando acontecem determinados eventos na BD (Insert, Update e Delete) &
'%( DECLARE --Definição de variáveis. BEGIN --Acções executáveis END Contrariamente ao PL/SQL, não existe propriamente o conceito de bloco. Um bloco em T/-SQL é um script. Os elementos BEGIN e END não são obrigatórios e delimitam o conjunto de acções a efectuar. Como não existe o conceito de bloco, DECLARE não define uma secção de declaração de variáveis. É opcional e é utilizada para definir objectos de T-SQL, tais como as variáveis. É possível também ter tratamento de excepções, e definir acções a tomar quando estas ocorrem. Contrariamente ao PL/SQL não é necessário terminar as instruções com ponto e vírgula. )
*+ Syntax DECLARE DECLARE { @local_variable [AS] data_type, [ n] } Declare @DataNasc DATETIME, @idade NUMERIC(2), @nome VARCHAR(50), @Controlador NUMERIC(2), @valido BIT
*+,$ Contrariamente ao PL/SQL, o T-SQL não permite no momento da definição: Inicializar Ter defaults Constantes Definir tipos de dados com base no tipo de outras variáveis Definir tipos de dados com base na estrutura de uma tabela
%-,%$(.%$ O T-SQL tem o conceito de variáveis globais: Não podem ser definidas pelo utilizador, são do sistema Distinguem-se das locais por terem no início os símbolos @@. Ex. SELECT @@VERSION
Muito semelhante ao já visto para o PL/SQL: As instruções podem, se necessário, passar de uma linha para a outra, mas as palavras-chave não podem ser divididas. As unidades léxicas (identificadores, operadores, etc) podem ser separadas por um ou mais espaços ou por outros limitadores que não se confundam com a unidade léxica. Não se podem usar palavras reservadas como identificadores, excepto se entre aspas. Os identificadores têm que começar por uma letra e as variáveis locais por @. Os valores literais do tipo caracter ou data têm que ser indicados entre plicas. Os comentários podem ser incluídos entre os símbolos /* e */ quando o comentário engloba várias linhas, ou então após - quando o comentário é apenas uma linha. /
0$.-$%#$ + - * / IS NULL, LIKE, BETWEEN, IN, =, >, <, <>,!=, ^=, <=, >= = + NOT AND OR Adição Subtracção Multiplicação Divisão Comparação Atribuição Concatenação Negação lógica Conjunção Disjunção
%1%$ ( ) ; [] : -- /* */ Expressão ou lista Expressão ou lista Fim de instrução Cadeia de caracteres Identificador Etiqueta Comentário Comentário Comentário
*1%$.2#$ Contrariamente ao PL/SQL o domínio de Y estende-se desde a sua definição até ao final. Não existindo o conceito de bloco, não é possível declarar variáveis com o mesmo nome dentro do mesmo script (mesmo estando declaradas antes de BEGIN END)
$ $# 3 IF-ELSE IF condition1 statement1 ELSE IF condition2 statement2 Para colocar mais do que uma instrução dentro do IF, é ncessário usar o Begin / End IF condition1 begin statement11 statement12 end ELSE IF condition2 statement2 "
0 $1$#4#56 BEGIN...END BREAK GOTO label IF...ELSE RETURN WHILE Other Transact-SQL statements that can be used with control-of-flow language statements are: /*...*/ (Comment) -- (Comment) CASE Keyword DECLARE local_variable Defines a statement block. Exits the innermost WHILE loop. Continues processing at the statement following the label as defined by label. Defines conditional, and optionally, alternate execution when a condition is FALSE. Exits unconditionally. Repeats statements while a specific condition is TRUE. EXECUTE PRINT RAISERROR Description &
# %. %!,$,%-,%$ DECLARE @VNome varchar(50), @VPosto varchar(50) BEGIN SELECT @VNome = Nome, @ VPosto = Posto FROM Empregado WHERE NumEmp = 5 END Caso a query retorne mais do que um registo as variáveis ficam com o valor do último registo seleccionado (não dá erro). Este comando é feito no PL/SQL com o INTO. )
$ Os registos retornados por uma instrução SQL podem ser manipulados através de um cursor. Um cursor é semelhante a uma lista de valores, sendo possível percorrer e posicionar em qualquer um dos registos. Os cursores são semelhantes aos já vistos para o PL/SQL. No entanto o T-SQL tem muito menos possibilidades de tratamento.
$$ #$$%# O processo típico da utilização de um cursor é : 1. Declarar variáveis para guardar os valores retornados pelo cursor 2. Declarar um cursor com o comando Declare e associar-lhe um Select 3. Usar o comando Open para executar o Select e abrir o cursor 4. Utilizar instruções de posicionamento do cursor - Fetch 5. Fechar o cursor com a instrução Close, para libertar a memória dos resultados do cursor, e possivelmente utilizar a instrução Deallocate se não for necessário usar novamente o cursor. @@Fetch_Status - Permite testar o status do fetch, se diferente de zero, ocorreu um erro.
$ 7$$%#%1 Utilizar instruções de posicionamento do cursor Fetch First - Avança para o primeiro registo do cursor. Fetch Next - Avança para o registo seguinte. Fetch Prior - Avança para o registo anterior. Fetch Last - Avança para o último registo do cursor. Fetch Absolute n - Avança para posição n do cursor. Fetch Relative n - Avança n registos a partir do registo actual do cursor. Para utilizar os comandos de fetch (à excepção do Next) é necessário declarar um cursor do tipo SCROLL.
$ $89 Syntax básica: DECLARE cursor_name CURSOR [FORWARD_ONLY SCROLL] [LOCAL GLOBAL] FOR select_statement [FOR UPDATE [OF column_name [,...n]]] Para abrir OPEN nome_cursor Buscar valores FETCH NEXT FROM nome_cursor INTO lista_variaveis Para fechar CLOSE nome_cursor Para retirar o Declare DEALLOCATE nome_cursor /
$ 91 DECLARE Cursor_Cli CURSOR FOR SELECT ClienteID, Nome FROM Clientes Declare @Cli int, @Nome varchar(50) OPEN Cursor_Cli FETCH NEXT FROM Cursor_Cli INTO @Cli, @Nome WHILE @@FETCH_STATUS = 0 BEGIN PRINT @Cli PRINT @Nome FETCH NEXT FROM Cursor_Cli INTO @Cli, @Nome END CLOSE Cursor_Cli DEALLOCATE Cursor_Cli
+%. $# $$%1#%$ Atributos de cursores implícitos: retornam informação sobre o resultado da última instrução INSERT, DELETE, UPDATE ou SELECT executada. São acedidos através de variáveis globais: @@ROWCOUNT retorna o número de registos afectados por uma instrução INSERT, DELETE, UPDATE ou SELECT @@ERROR o número do erro da última instrução executada, ou zero se não existir.
# Sintaxe básica: CREATE PROC[EDURE] procedure_name [;number] [ {@parameter data_type} [VARYING] [= default] [OUTPUT] ] [,...n] AS sql_statement [...n]
# 91 CREATE PROC Cli @CodCli int=null, @InicioNome Varchar(40) AS BEGIN SELECT * FROM CLIENTES WHERE ClienteID > @CodCli AND Nome LIKE (@InicioNome+'%') END Para invocar a procedure EXEC Cli 2, 'A' OU EXEC Cli @InicioNome = 'A', @CodCli=2 "
# 91 ALTER PROC Cli @CodCli int, @InicioNome Varchar(40), @TotalReg int OUTPUT AS BEGIN SELECT @TotalReg = COUNT(*) FROM CLIENTES WHERE ClienteID > @CodCli AND Nome LIKE (@InicioNome+'%') END Para invocar a procedure DECLARE @Tot int EXEC Cli 1, 'A', @TotalReg = @Tot OUTPUT PRINT 'Numero de registos = ' + cast(@tot AS Varchar(10)) &
3 #%$ A utilização de funções é vantajosa em determinadas circunstâncias : Podem ser utilizados para encapsular e centralizar a lógica das regras de negócio. Podem ser utilizadas numa query, contrariamente as Stored procedures e podem ser passados parâmetros, contrariamente às Views. Nos casos em que o resultado é uma tabela, esta pode ser usado na cláusula FROM como uma tabela normal. Nas situações em que o resultado é um único valor, as funções podem ser usadas na cláusula SELECT como uma função normal do SQL. Pode ser usada, por exemplo, para cálculos de valores ou formatação. )
3 #%$ No T-SQL existem 3 tipos de funções: 1. Scalar Functions - São funções que retornam unicamente um valor. Exemplo: CREATE FUNCTION QtStock (@Qt Smallint) RETURNS Smallint AS BEGIN IF @QT<0 SET @Qt = 0 RETURN @Qt END Para invocar : SELECT dbo.qtstock(-3)
3 #%$ 2. Inline Table - São funções que têm como resultado uma tabela de valores que é resultado de uma única instrução de select. Exemplo: CREATE FUNCTION AnivMes (@Mes Tinyint) RETURNS TABLE AS RETURN (SELECT ClienteID, Nome FROM Clientes WHERE Month(DataNasc) = @Mes) Para invocar: SELECT Nome From AnivMes(1)
3 #%$ 3. Multi-statement Table - São funções que retornam tabelas definidas e trabalhadas pelo utilizador. Exemplo: CREATE FUNCTION ArtVendasAno (@Ano Int) RETURNS @VAno TABLE (ArtigoID int, Descricao Nvarchar(40), Vendas Int) AS BEGIN INSERT @VAno SELECT ArtigoID, Descricao, (Select SUM(Quant) FROM Facts, linhasfact WHERE LinhasFact.ArtigoID = Artigos.ArtigoID AND LinhasFact.FactID = Facts.FactID AND @Ano = YEAR(Data)) FROM Artigos RETURN END Para invocar: SELECT * FROM ArtVendasAno(2006) WHERE Vendas > 1