O SQL Server é um sistema de banco de dados relacional criado pela Microsoft. Sua primeira versão foi publicada em 1989.
Para saber mais sobre os tipos de banco de dados, acesse aqui: Tipos de banco de dados
//TODO: Complementar
//TODO: Complementar
Se não tiver um banco de dados SQL Server para utilizar (por exemplo da empresa que você estiver trabalhando), você pode instalar uma versão gratuita no seu computador.
Será necessário ter um computador com os seguintes requisitos mínimos:
Faça o download do SQL Server 2019 Express no site: https://www.microsoft.com/en-us/Download/details.aspx?id=101064
Depois, execute a instalação:
















Para economizar memória ao iniciar o Windows o serviço do SQL Server está marcado para não iniciar junto com o Windows.
Toda vez que você for utilizar o SQL Server, você precisa inicia-lo, para isso faça o seguinte:

Faça a instalação do SQL Server Management Studio (SSMS) no site da Microsoft e realize a instalação: https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms


Abra o SQL Server Management Studio:
(iniciar / SQL Server Management Studio)

Para conectar, utilize:

Então, clique no botão “New query”

//TODO: Complementar
Inicie o SQL Server Management Studio:

Para conectar, utilize:
Abra uma nova query:

Faça o download do banco de dados de exemplo AdventureWorks: https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorks-oltp-install-script.zip
Descompacte o arquivo em uma pasta do seu computador, por exemplo: C:\temp\AdventureWorks-oltp-install-script
Abra o arquivo: instawdb.sql

Altere no script o caminho onde você baixou os arquivos:


Habilite o SQLCMD Mode:

Execute o script:

Deve ser exibida mensagem de sucesso:

Atualize a lista de bancos de dados:

Expanda a lista do banco recém criado:

Agora, você pode executar uma query para consultar dados de uma das tabelas, por exemplo:
SELECT * FROM Sales.Customer

E execute precionando F5, ou clicando no botão executar:

Inicie o SQL Server Management Studio:

Para conectar, utilize:
Crie o novo banco de dados:


Abra uma nova query:

Para criar uma tabela com 3 registros, digite:
CREATE TABLE Book (
	BookId	INT,
	Title	VARCHAR(100) NOT NULL,
	Author	VARCHAR(100) NOT NULL,
	CONSTRAINT PK_Book PRIMARY KEY (BookId)
)
go
INSERT INTO Book (BookId, Title, Author) VALUES (1, 'Clean Code', 'Robert C. Martin')
INSERT INTO Book (BookId, Title, Author) VALUES (2, 'Domain-Driven Design', 'Eric Evans')
INSERT INTO Book (BookId, Title, Author) VALUES (3, 'Implementing Domain-Driven Design', 'Vaughn Vernon')
go
Então, execute pressionando F5, ou clicando no botão Executar.
Para pesquisar todos os registros da tabela, digite o seguinte:
SELECT * FROM Book

//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
//TODO: Complementar
Para imprimir mensagens durante a execução de um comando utilize o comando print
PRINT Mensagem para ser exibida
Utilizar “Print” para imprimir mensagens quando uma operação muito longa está sendo executada, nem sempre imprime os resultados no Sql Management Studio. Utilizar um RAISERROR, no lugar do print, como no comando abaixo força que todas as mensagens do buffer sejam instantaneamente exibidas
DECLARE @message VARCHAR(1000)
SET @message = 'Message...'
RAISERROR(@message, 0, 1) WITH NOWAITPara que uma coluna seja do tipo auto incremento no SQL Server utilizar o atributo “Identity” ao criar a coluna
CREATE TABLE [User] (
	UserID		INT		IDENTITY	NOT NULL
	, Email		VARCHAR(200)		NOT NULL
	, CONSTRAINT PK_User PRIMARY KEY (UserID)
)SET IDENTITY_INSERT [User] ON
INSERT INTO [User] (UserID, Email) VALUES (1, 'teste@teste.com.br')
SET IDENTITY_INSERT [User] OFFDBCC CHECKIDENT('[User]', RESEED, 0)INSERT INTO [User] (Email) VALUES ('teste2@teste.com.br')
DECLARE @id INT
SELECT @id = CONVERT(INT, SCOPE_IDENTITY())NOTAS:
DROP INDEX UNIQUE_Supplier_Name ON SupplierCREATE UNIQUE INDEX UNIQUE_Supplier_Name ON Supplier (ReferenceName)CREATE UNIQUE NONCLUSTERED INDEX UNIQUE__fi_pdv_tb_Coupon__ds_offline_id
ON fi_pdv_tb_Coupon(id_omega, ds_offline_id)
WHERE ds_offline_id IS NOT NULLDECLARE @productID int
DECLARE cursor1 CURSOR FOR
SELECT ProductID FROM Product (NOLOCK)
OPEN cursor1
FETCH NEXT FROM cursor1 INTO
	@productID
WHILE @@FETCH_STATUS = 0
BEGIN
	PRINT '-- productID=' + convert(varchar(20), @productID)
	-- Executar aqui o que precisa ser executado
	FETCH NEXT FROM cursor1 INTO
		@productID
END
CLOSE cursor1
DEALLOCATE cursor1SELECT
	m.id,
	COUNT(1) OVER()
FROM
	Movie m
WHERE
	m.ChannelID = 1
ORDER BY
	m.Created
OFFSET @OFFSET ROWS FETCH NEXT @COUNT ROWS ONLYCREATE PROCEDURE dbo.BrandPagedList (
	@page int,
	@pageSize int
) AS
BEGIN
WITH ListResult AS
(
	SELECT
		br.BrandID
		, br.[Name]
		, ROW_NUMBER() OVER(ORDER BY br.[Name] ASC) AS rowNumber
	FROM
		Brand (NOLOCK) br
)
SELECT * , (SELECT MAX(rowNumber) FROM ListResult) as TotalRows FROM ListResult WHERE rowNumber BETWEEN ((@pageSize * (@page - 1)) + 1) AND (@pageSize * @page);BEGIN TRY
	BEGIN TRANSACTION
	PRINT '--BEGIN TRANSACTION'
	--Execute...
	COMMIT
	PRINT '--COMMIT'
END TRY
BEGIN CATCH
	DECLARE @errorMessage nvarchar(max), @errorSeverity int, @errorState int;
	SELECT
		@errorMessage = ERROR_MESSAGE() + ' Line ' + cast(ERROR_LINE() as nvarchar(5)),
		@errorSeverity = ERROR_SEVERITY(),
		@errorState = ERROR_STATE();
	PRINT '--ROLLBACK'
	ROLLBACK
	RAISERROR (@errorMessage, 16, -1);
	RETURN
END CATCHTODO: Incluir exemplos
IF EXISTS(SELECT * FROM sys.objects WHERE name = 'fnFirstMonthDay' AND type in ('FN', 'IF', 'TF', 'FS', 'FT'))
	DROP FUNCTION dbo.fnFirstMonthDay
go
CREATE FUNCTION dbo.fnFirstMonthDay(@date DATE) RETURNS DATE AS
BEGIN
	IF @date IS NULL
		RETURN NULL
	RETURN DATEADD(day, ((DATEPART(D, @date) -1) * -1), @date)
ENDIF EXISTS(SELECT * FROM sys.objects WHERE name = 'fnFirstWeekDay' AND type in ('FN', 'IF', 'TF', 'FS', 'FT'))
	DROP FUNCTION dbo.fnFirstWeekDay
go
CREATE FUNCTION dbo.fnFirstWeekDay(@date DATE) RETURNS DATE AS
BEGIN
	IF @date IS NULL
		RETURN NULL
	RETURN DATEADD(day, ((DATEPART(DW, @date) -1) * -1), @date)
ENDIF EXISTS(SELECT * FROM sys.objects WHERE name = 'fnGetNumericCharacters' AND type in ('FN', 'IF', 'TF', 'FS', 'FT'))
	DROP FUNCTION fnGetNumericCharacters
GO
CREATE FUNCTION dbo.fnGetNumericCharacters(@text VARCHAR(MAX)) RETURNS VARCHAR(MAX) AS
BEGIN
	IF @text IS NULL
		RETURN NULL
	DECLARE @index INT = PATINDEX('%[^0-9]%', @text)
	WHILE @index > 0
	BEGIN
		SET @text = STUFF(@text, @index, 1, '' )
		SET @index = PATINDEX('%[^0-9]%', @text )
	END
	IF len(@text) = 0
		RETURN NULL
	RETURN @text
END
GOIF EXISTS(SELECT * FROM sys.objects WHERE name = 'fnRemoveDiacritics' AND type in ('FN', 'IF', 'TF', 'FS', 'FT'))
	DROP FUNCTION dbo.fnRemoveDiacritics
GO
CREATE FUNCTION dbo.fnRemoveDiacritics (@text VARCHAR(MAX))
RETURNS VARCHAR(MAX) AS
BEGIN
	SELECT @text = (@text collate SQL_Latin1_General_Cp1251_CS_AS)
    RETURN @text
ENDIF EXISTS(SELECT * FROM sys.objects where name = 'fnRemoveSpecialCharacters' AND type in ('FN', 'IF', 'TF', 'FS', 'FT'))
	DROP FUNCTION dbo.fnRemoveSpecialCharacters
GO
CREATE FUNCTION dbo.fnRemoveSpecialCharacters (@text VARCHAR(MAX), @allowSpaces BIT = 1)
RETURNS VARCHAR(MAX) AS
BEGIN
    DECLARE @matchExpression AS VARCHAR(100)
	IF @allowSpaces = 1
		SET @matchExpression = '%[^a-z0-9 ]%'
	ELSE
		SET @matchExpression = '%[^a-z0-9]%'
	WHILE PatIndex(@matchExpression, @text) > 0
        SET @text = Stuff(@text, PatIndex(@matchExpression, @text), 1, '')
    RETURN @text
END
GOIF EXISTS(SELECT name FROM sys.objects WHERE name = 'fnSplit' AND type in ('FN', 'IF', 'TF', 'FS', 'FT'))
	DROP FUNCTION dbo.fnSplit
GO
CREATE  FUNCTION dbo.fnSplit(@text VARCHAR(MAX), @separator VARCHAR(20) = ' ')
RETURNS @strings TABLE
(   
  position int IDENTITY PRIMARY KEY,
  value VARCHAR(MAX)
)
AS
BEGIN
DECLARE @index int = -1
WHILE (LEN(@text) > 0)
  BEGIN
    SET @index = CHARINDEX(@separator , @text)
    IF (@index = 0) AND (LEN(@text) > 0)
      BEGIN  
        INSERT INTO @strings VALUES (@text)
          BREAK
      END
    IF (@index > 1)
      BEGIN  
        INSERT INTO @strings VALUES (LEFT(@text, @index - 1))  
        SET @text = RIGHT(@text, (LEN(@text) - @index))
      END
    ELSE
      SET @text = RIGHT(@text, (LEN(@text) - @index))
    END
  RETURN
ENDSELECT
	a.ItemID,
	(SELECT
		STUFF(
				(SELECT ',' + CONVERT(VARCHAR(10), si.SupplierID) FROM SupplierItem si (NOLOCK) WHERE a.ItemID = si.ItemID AND si.Active = 1 FOR XML PATH(''))
			,1,1,'')
	) as SupplierIdList
FROM
	Item a (nolock)
WHERE
	a.ItemID in (303216, 5)IF EXISTS(SELECT name FROM sys.objects WHERE Name = 'fnPadString' AND type in ('FN', 'IF', 'TF', 'FS', 'FT'))
	DROP FUNCTION dbo.fnPadString
GO
CREATE FUNCTION dbo.fnPadString (@text VARCHAR(MAX), @padWith char(1), @length int) RETURNS VARCHAR(MAX) AS
BEGIN
DECLARE @ret VARCHAR(MAX)
SELECT @ret = ISNULL(REPLICATE(@padWith, @length - LEN(ISNULL(@text,0))), '') + @text
RETURN @ret
END
GO;WITH cte AS
(
	SELECT
		cp.id_omega
		, cp.id_coupon
		, cp.dt_coupon
		, cp.ts_control
		, cp.ds_offline_id
		, ROW_NUMBER() OVER(PARTITION BY cp.ds_offline_id ORDER BY cp.ds_offline_id) AS RowNumber
	FROM
		fi_pdv_tb_Coupon cp (nolock)
		INNER JOIN (
			SELECT id_omega, ds_offline_id, COUNT(ds_offline_id) as qtd FROM fi_pdv_tb_Coupon (NOLOCK) GROUP BY id_omega, ds_offline_id HAVING COUNT(ds_offline_id) > 1
		) b
		on cp.id_omega = b.id_omega
		and cp.ds_offline_id = b.ds_offline_id
)
UPDATE cte SET ds_offline_id = ds_offline_id + '_' + convert(varchar(10), RowNumber) where RowNumber > 1IF EXISTS(SELECT * FROM sys.objects WHERE name = 'fnGetUrl' AND type in ('FN', 'IF', 'TF', 'FS', 'FT'))
	DROP FUNCTION dbo.fnGetUrl
go
CREATE FUNCTION dbo.fnGetUrl(@text varchar(200)) RETURNS VARCHAR(200) AS
BEGIN
	--remove
	SET @text = replace(@text, '&', '')
	SET @text = replace(@text, '.', '')
	SET @text = replace(@text, '(', '')
	SET @text = replace(@text, ')', '')
	SET @text = replace(@text, '''', '')
	SET @text = replace(@text, '"', '')
	SET @text = replace(@text, '%', '')
	SET @text = replace(@text, '$', '')
	SET @text = replace(@text, '+', '')
	--separador
	SET @text = replace(@text, ' e ', '-')
	SET @text = replace(@text, ',', '-')
	SET @text = replace(@text, ' - ', '-')
	SET @text = replace(@text, '/', '-')
	SET @text = replace(@text, '\', '-')
	SET @text = replace(@text, ' ', '-')
	SET @text = replace(@text, '--', '-')
	--remove acentuação
	SELECT @text = @text Collate SQL_Latin1_General_CP1253_CI_AI
	SET @text = ltrim(rtrim(lower(@text)))
	RETURN @text
END
GOA cross join that does not have a WHERE clause produces the Cartesian product of the tables involved in the join
SELECT
	p.BusinessEntityID, t.Name AS Territory
FROM
	Sales.SalesPerson p
CROSS JOIN
	Sales.SalesTerritory t
ORDER BY
	p.BusinessEntityID;--drop table [Local]
CREATE TABLE [Local]
	(LocalID int not null,
	LocalPaiID int null,
	Nome varchar(50) not null)
go
INSERT INTO [Local] values (100, null, 'Bloco 1');
	INSERT INTO [Local] values (110, 100, 'Prédio 1');
			INSERT INTO [Local] values (111, 110, '1º Andar');
			INSERT INTO [Local] values (112, 110, '2º Andar');
			INSERT INTO [Local] values (113, 110, '3º Andar');
			INSERT INTO [Local] values (114, 110, '4º Andar');
	INSERT INTO [Local] values (120, 100, 'Prédio 2');
			INSERT INTO [Local] values (121, 120, '1º Andar');
			INSERT INTO [Local] values (122, 120, '2º Andar');
			INSERT INTO [Local] values (123, 120, '3º Andar');
	INSERT INTO [Local] values (12, 100, 'Prédio 3');
INSERT INTO [Local] values (200, null, 'Bloco 2');
	INSERT INTO [Local] values (210, 200, 'Prédio 1');
	INSERT INTO [Local] values (220, 200, 'Prédio 2');
	INSERT INTO [Local] values (230, 200, 'Prédio 3');
INSERT INTO [Local] values (300, null, 'Bloco 3');
go
WITH Loc AS
		(SELECT 1 as Nivel, l.LocalID, l.Nome, CONVERT(VARCHAR(1000), l.Nome) as CaminhoCompleto FROM [Local] l (NOLOCK) WHERE l.LocalPaiID IS NULL
		UNION ALL
		SELECT Nivel+1, l.LocalID, l.Nome, CONVERT(VARCHAR(1000), Loc.CaminhoCompleto + ' / ' + l.Nome) as CaminhoCompleto
		FROM [Local] l (NOLOCK)
		INNER JOIN Loc on l.LocalPaiID = Loc.LocalID
		WHERE l.LocalPaiID is not null
		)
	SELECT LocalID, Nome, CaminhoCompleto FROM Loc;
goIF EXISTS(SELECT name FROM sys.objects WHERE Name = 'fn_Local_Caminho_Completo' AND type in ('FN', 'IF', 'TF', 'FS', 'FT'))
	DROP FUNCTION dbo.fn_Local_Caminho_Completo
GO
CREATE FUNCTION dbo.fn_Local_Caminho_Completo(@LocalID int)
returns VARCHAR(1000)
AS
BEGIN
	DECLARE @caminho varchar(1000);
	WITH Loc AS
		(SELECT l.LocalID, l.LocalPaiID, l.Nome, CONVERT(VARCHAR(1000), l.Nome) as CaminhoCompleto FROM [Local] l (NOLOCK) WHERE l.LocalID = @LocalID
		UNION ALL
		SELECT l.LocalID, l.LocalPaiID, l.Nome, CONVERT(VARCHAR(1000), l.Nome + ' / ' + Loc.CaminhoCompleto) as CaminhoCompleto
		FROM [Local] l (NOLOCK)
		INNER JOIN Loc on l.LocalID = Loc.LocalPaiID
	)
	SELECT @caminho = CaminhoCompleto FROM Loc WHERE LocalPaiID IS NULL
	return @caminho;
END
go
ALTER TABLE [Local] ADD CaminhoCompleto AS dbo.fn_Local_Caminho_Completo(LocalID);
go
select * from [Local];
goIF EXISTS(SELECT * FROM sys.procedures WHERE name = 'OrderInsert')
	DROP PROCEDURE OrderInsert
go
IF EXISTS(SELECT name FROM sys.types WHERE is_user_defined = 1 AND is_table_type = 1 AND name = 'OrderInsert_OrderItemTableType')
	DROP TYPE dbo.OrderInsert_OrderItemTableType
GO
CREATE TYPE OrderInsert_OrderItemTableType AS TABLE (
	  ItemID INT
	, Quantity INT
)
GO
IF EXISTS(SELECT * FROM sys.procedures WHERE name = 'OrderInsert')
	DROP PROCEDURE dbo.OrderInsert
GO
CREATE PROCEDURE dbo.OrderInsert (
	  @clientID INT
	, @totalValue DECIMAL(15,2)
	, @orderItems OrderInsert_OrderItemTableType READONLY
)
as
BEGIN
INSERT INTO [Order] (
	  ClientID
	, TotalValue
)
VALUES (
	@clientID
	, @totalValue
)
DECLARE @orderID INT
SET @orderID = CONVERT(INT, SCOPE_IDENTITY())
INSERT INTO OrderItem (
	OrderID
	, ItemID
	, Quantity
)
SELECT
	@orderID
	, ItemID
	, Quantity
FROM
	@orderItems
SELECT @orderID as id
END
goRetorna a classificação de cada linha na partição de um conjunto de resultados. A classificação de uma linha é um mais o número de classificações que vêm antes da linha em questão.
USE AdventureWorks2012;  
GO  
SELECT
	i.ProductID
	, p.Name
	, i.LocationID
	, i.Quantity  
  , RANK() OVER(PARTITION BY i.LocationID ORDER BY i.Quantity DESC) AS Rank  
FROM
	Production.ProductInventory AS i   
	INNER JOIN Production.Product AS p   
		ON i.ProductID = p.ProductID  
WHERE
	i.LocationID BETWEEN 3 AND 4  
ORDER BY
	i.LocationID;  ProductID   Name                   LocationID   Quantity Rank  
----------- ---------------------- ------------ -------- ----  
494         Paint - Silver         3            49       1  
495         Paint - Blue           3            49       1  
493         Paint - Red            3            41       3  
496         Paint - Yellow         3            30       4  
492         Paint - Black          3            17       5  
495         Paint - Blue           4            35       1  
496         Paint - Yellow         4            25       2  
493         Paint - Red            4            24       3  
492         Paint - Black          4            14       4  
494         Paint - Silver         4            12       5  
Esta função retorna a posição de cada linha dentro de uma partição do conjunto de resultados, sem nenhum intervalo nos valores de classificação. A classificação de uma linha é um mais o número de valores de classificação distintos que vêm antes da linha em questão.
USE AdventureWorks2012;  
GO
SELECT
	TOP(10) BusinessEntityID
	, Rate
	, DENSE_RANK() OVER (ORDER BY Rate DESC) AS RankBySalary  
FROM
	HumanResources.EmployeePayHistory;BusinessEntityID Rate                  RankBySalary  
---------------- --------------------- --------------------  
1                125.50                1  
25               84.1346               2  
273              72.1154               3  
2                63.4615               4  
234              60.0962               5  
263              50.4808               6  
7                50.4808               6  
234              48.5577               7  
285              48.101                8  
274              48.101                8  
TODO: Adicionar texto de como os isolations levels funcionam
CREATE PROCEDURE dbo.QueueGetNext (
	@queueOperationId INT = null) as
BEGIN
	DECLARE @queueId VARCHAR(36) = NULL
	SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
	BEGIN TRANSACTION
		SELECT TOP 1
			@queueId = QueueId
		FROM
			[Queue] WITH (UPDLOCK)
		WHERE
			QueueStatusId = 1 --Incluido
			AND (@queueOperationId IS NULL OR QueueOperationId = @queueOperationId)
		ORDER BY
			RequestDate ASC
		--Atualiza
		UPDATE
			[Queue]
		SET
			QueueStatusId = 2 --Processando
		WHERE
			QueueId = @queueId
	COMMIT TRANSACTION
	SELECT * FROM [Queue] WHERE QueueId = @queueId
END