Arquivo

Posts Tagged ‘T-SQL’

T-SQL: Importar dados do Excel e Access usando MDAC – ACE

1 de agosto de 2018 Deixe um comentário

O Microsoft SQL Server possue ferramentas para fazer o trabalho de importação e exportação de dados do Excel, Access entre outras fontes.

Porém, no meu caso desejo executar um script importação e/ou exportação.

Como fazer isso usando T-SQL?

Para isso é necessário ter instalado o Provider no servidor do SQL Server.

  • Microsoft.Jet.OLEDB.4.0 – depreciado
  • Microsoft.ACE.OLEDB.12.0
  • Microsoft.ACE.OLEDB.16.0

O Jet OLEDB foi depreciado, mas existem diversos códigos antigos de exemplos com ele. Podemos aproveitar esses códigos, substituindo pelo Microsft ACE OLEDB.

Office 2010 – ACE 12 – Microsoft Access Database Engine 2010 Redistributable

Office 2016 – ACE 16 – Microsoft Access Database Engine 2016 Redistributable

Para conferir a instalação entre no SQL Managment Studio – Server Objects – Linked Servers – Providers

SQLLinkedServerProvider001

-- Ativa Linked Server

sp_configure 'show advanced options', 1

GO

RECONFIGURE WITH OverRide

GO

sp_configure 'Ad Hoc Distributed Queries', 1

GO

RECONFIGURE WITH OverRide

GO

-- Ativa Permissão ao Provider versão ACE 12

EXEC sp_MSSet_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess',1

GO

EXEC sp_MSSet_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters',1

GO

Caso recebe algumas mensagem referente a permissão de acesso, ou erro de impossibilidade de criar linked server, leia Permissions needed to set up linked server with out-of-process provider

 

-- Ativa Permissão ao Provider versão ACE 16

EXEC sp_MSSet_oledb_prop N'Microsoft.ACE.OLEDB.16.0', N'AllowInProcess',1

GO

EXEC sp_MSSet_oledb_prop N'Microsoft.ACE.OLEDB.16.0', N'DynamicParameters',1

GO

-- Usa o Provider Jet ( Depeciado ) para acessar XLS

SELECT * FROM OPENDATASOURCE('Microsoft.Jet.OLEDB.4.0','Data Source=C:\Excel\File.xls; Extended Properties=Excel 5.0')...[Sheet1$]

GO

-- Usa o Provider ACE 12 para acessar XLS / XLSX

SELECT * FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0','Data Source=C:\ExcelFiles\File2003.xls; Extended Properties=Excel 8.0')...[Sheet1$]

GO

-- Usa o Provider ACE 16 para acessar XLS / XLSX

SELECT * FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.16.0','Data Source=C:\ExcelFiles\File2016.xlsx; Extended Properties=Excel 12.0')...[Sheet1$]

GO

Resultado

SQLfromExcelAccess

Importante!!!

O arquivo está na unidade “C:” local do SERVIDOR SQL Server.

Para abrir arquivo da rede, use o caminho COMPLETO, conforme abaixo:

SELECT * FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.12.0','Data Source=\\NomeDoPC\NomePastaCompartilhada\NomeArquivo.xlsx; Extended Properties=Excel 8.0')...[NomePlanilha$]
SELECT * FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.16.0','Data Source=\\NomeDoPC\NomePastaCompartilhada\NomeArquivo.xlsx; Extended Properties=Excel 12.0')...[NomePlanilha$]

fonte:

Query Excel file source through Linked Server

How to use Excel with SQL Server linked servers and distributed queries

Configuiring a Linked Microsoft Access Server on SQL 2005

Microsoft.Jet.OLEDB4.0 – 32bit and 64bit ( Deprecated )

Cannot create an instance of OLE DB provider Microsoft.Jet.OLEDB.4.0 for linked server null

Cannot create instance of “Microsoft.ACE.OLEDB.12.0” for linked server “(null)” on x64 Vista with x64 SQL Server 2008 – sp_MSSet_oledb_prop

How to Import and Export SQL Server data to an Excel file

T-SQL OpenDataSource on SQL Server 2017

Import data from Excel to SQL Server or Azure SQL Database

Permissions needed to set up linked server with out-of-process provider

SQL Server – Gerar um número randômico

13 de setembro de 2017 Deixe um comentário

Preciso gerar um volume de dados com valor inteiro e/ou decimal, para popular uma tabela no SQL Server. Não quero depender de ferramenta de terceiro para gerar os dados.

A solução foi fazer um script Gerar_Numero_Randomico.sql, que está disponível no meu GitHub.

Gera_NrRandomicoResult

Explicação dos comandos usados, abaixo:

1. Gerar um número randômico, ou seja, número aleatório. Exemplo: 1, 524, 6421, 60544, 40.

Para isso usarei a função NEWID() que cria um valor hexadecinal único do tipo uniqueidentifier.

SELECT NEWID() AS ID_Hex

 

2. Extrair o valor inteiro do ID_Hex, usando a função CHECKSUM().

SELECT

  A.ID_Hex,

  CHECKSUM(A.ID_Hex) AS Nr_Randomico,
FROM ( — Nr_Randomico baseado em um ID Hexadecimal
            SELECT NEWID() AS ID_Hex
          ) A

 

3. Criar o valor decimal, com 4 casas, dividindo o valor inteiro por 10000,0000 e convertendo o resultado da divisão usando a função CAST().

SELECT

  A.ID_Hex,

  CHECKSUM(A.ID_Hex) AS Nr_Randomico,

  CAST(CHECKSUM(ID_Hex) / 10000.0000 AS decimal(10,4)) AS Nr_Randomico_Decimal
FROM ( — Nr_Randomico baseado em um ID Hexadecimal
            SELECT NEWID() AS ID_Hex
          ) A

 

Com os três passos, obtemos o seguinte resultado:

ID_Hex Nr_Randomico Nr_Randomico_Decimal
4CBFDEC3-F57C-433D-B145-7959B570FBC0 -1216800284 -121680.0284

 

Podemos gerar novos valores inteiros e decimais, usando parte do Nr_Randomico_Decimal. Exemplo:

Nr_Randomico_Decimal Novos Valores Descrição do Valor
-121680.0284 -121680 Somente parte inteira
-121680.0284 0284 Somente parte decimal
-121680.0284 0.0284 1 dígito da parte inteira + parte decimal
-121680.0284 80.0284 2 dígitos da parte inteira + parte decimal
-121680.0284 680.0284 3 dígitos da parte inteira + parte decimal
-121680.0284 1680.0284 4 dígitos da parte inteira + parte decimal

 

4. Usarei a função PARSENAME() para obter a parte inteira do Nr_Randomico_Decimal.

PARSENAME(CAST(CHECKSUM(ID_Hex) / 10000.0000 AS decimal(10,4)) , 2) AS Parte_Inteiro

 

5. Usarei a função PARSENAME() para obter a parte decimal do Nr_Randomico_Decimal.

PARSENAME(CAST(CHECKSUM(ID_Hex) / 10000.0000 AS decimal(10,4)) , 1) AS Parte_Decimal

Note que a função PARSENAME() é composta por dois parâmetros o Objeto e Parte do Objeto que se deseja obter, sintaxe PARSENAME ( ‘object_name’ , object_piece ).

Como nosso objeto é o Número Decimal  -121680.0284, ele é composto por 2 partes interpretadas da direita para esquerda. Portanto:

Objeto Parte Resultado Descrição
-121680.0284 1 0284 Parte Decimal do Nr_Randomico_Decimal
-121680.0284 2 -121680 Parte Inteira do Nr_Randomico_Decimal

6. Já com a Parte Inteira, -121680, preciso extrair o 1 dígito, 2 digito, etc.

Para isso usarei a função RIGHT(), obtendo N caracteres da direita para esquerda.

Parte Inteira Resultado Sintaxe
-121680 0 RIGHT(‘-121680’, 1)
-121680 80 RIGHT(‘-121680’, 2)
-121680 680 RIGHT(‘-121680’, 3)
-121680 1680 RIGHT(‘-121680’, 4)

RIGHT(PARSENAME(CAST(CHECKSUM(ID_Hex) / 10000.0000 AS decimal(10,4)), 2), 1) AS Parte_Inteiro_1dig

7. Agora vamos somar a Parte Inteira N Digitos + Parte Decimal

Nr_Randomico_Decimal Inteira N Digitos Parte Decimal Novos Valores
-121680.0284 0 0284 0.0284
-121680.0284 80 0284 80.0284
-121680.0284 680 0284 680.0284
-121680.0284 1680 0284 1680.0284

 

8. Como repetir o comando SQL, várias vezes?

Até o passo sete, foi construído o comando SELECT… que retorna um número aleatório/rondômico.

Porém, precisamos executar o comando SELECT várias vezes e ir armazenando em uma tabela.

Para executar um comando N vezes, usarei o GO que é uma instrução sqlcmd, exemplo:

SELECT ‘A’, 1

GO 5

Será executado 5 vezes o comando SELECT ‘A’, 1

Dito isto, para gerar 5 números randômicos vamos colocar no final do comando SELECT, GO 5

SELECT

  A.ID_Hex,

……

GO 5

9. Criar uma Tabela para armazenar os 5 números gerados no passo oito.

No passo anterior, vimos que o comando SELECT foi executado 5 vezes. Isso gerou 5 resultados em resultset diferentes e não uma tabela contendo 5 registros.

Para resolver isso, podemos criar uma Tabela para receber os valores gerados.

Normalmente, usamos a função CREATE TABLE().

Mas, neste exemplo não quero definir cada campo ao criar a tabela de resultado e sim aproveitar o resultado do SELEC para criar a estruturar da #Tabela_NrRandomico que receberá os números randômicos gerados.

Para isso usarei a função TOP() em conjunto com a cláusula INTO do SELECT.

SELECT TOP 0, *

INTO #Tabela_NrRandomico

FROM (

SELECT

  A.ID_Hex,

……

) Gerar_NrRandomico

No comando acima o TOP 0 (zero), * do PRIMEIRO SELECT não retorna nenhum valor, porém captura toda estrutura de campos do resultado gerado pelo SEGUNDO SELECT A.ID_HEX.

Já o INTO #Tabela_NrRandomico do PRIMEIRO SELECT, cria a tabela #Tabela_NrRandomico baseado no resultado capturado.

Atenção o # não é erro de digitação, ele significa que será criar uma tabela temporária que ao fechar a conexão com o banco de dados é eliminada, automaticamente.

Para criar uma tabela real, portanto permanente. Retire o #, INTO Tabela_NrRandomico.

 

10. Inserir na tabela #Tabela_NrRandomico os 5 números gerados no passo oito.

Para isso usarei o INSERT INTO com valores gerados no SELECT

INSERT INTO #Tabela_NrRandomico
SELECT *
FROM (

SELECT

  A.ID_Hex,

……

) Gerar_NrRandomico

GO 5

11. Vamos exibir o resultado da #Tabela_NrRandomico

SELECT * FROM #Tabela_NrRandomico
GO

12. Excluir a tabela #Tabela_NrRandomico, usando o DROP TABLE.

Para que ao executar o script várias vezes não exiba o erro de tabela já existente, pois ela é sempre criada no passo nove.

DROP TABLE #Tabela_NrRandomico
GO

Com os 12 passos, obtemos o seguinte resultado:

ID_Hex Nr_Randomico Nr_Randomico_Decimal
4CBFDEC3-F57C-433D-B145-7959B570FBC0 -1216800284 -121680.0284
0509C7E0-AEC0-4B6C-8DDF-A26142156E59 -1025729740 -102572.9740
539E79E8-12CC-45AE-9E38-2CBECE009464 718090630 71809.0630
38268135-CDCC-43B0-B8D2-68C67C3D0D14 -2028602481 -202860.2481
C0743028-43C9-43BE-93AC-5C39455BEA5C 779214164 77921.4164

… mais outras colunas com os novos valores Inteiro_1_Decimal, Inteiro_N_Decimal.

 

Fonte:

https://stackoverflow.com/questions/3418606/sql-how-do-i-get-only-the-numbers-after-the-decimal

https://stackoverflow.com/questions/16412231/how-to-get-2-digits-after-decimal-point-in-tsql

https://stackoverflow.com/questions/1045138/how-do-i-generate-random-number-for-each-row-in-a-tsql-select

SQL Server – Resolver Erro de Divisão por Zero

16 de janeiro de 2015 Deixe um comentário

Use o código de exemplo, abaixo.

 

PRINT ‘=============================’
PRINT ‘Variáveis’
PRINT ‘=============================’
declare @dividend float =2
declare @divisor float = 0

 

PRINT ‘=============================’
PRINT ‘Problema – Erro’
PRINT ‘=============================’
SELECT Dividendo = @dividend
     , Divisor   = @divisor
     , Resultado = @dividend/@divisor

 

PRINT ‘=============================’
PRINT ‘Solução 1’
PRINT ‘=============================’
SELECT COALESCE(@dividend / NULLIF(@divisor,0), 0)

SELECT Dividendo = @dividend
     , Divisor   = @divisor
     , Resultado = COALESCE(@dividend / NULLIF(@divisor,0), 0)

SQL – Tipos de Objeto

9 de janeiro de 2015 Deixe um comentário

Como saber quais são todas tabelas do banco de dados?

Como saber quais são todas trigger do banco de dados?

Como saber quais são todas constraint do banco de dados?

Para responder perguntas como essa, encontrei a seguinte resposta e resolvi divulgar.

No banco de dados, execute o comando:

SELECT DISTINCT [Type], Type_Desc FROM Sys.Objects ORDER BY [Type]

O resultado será:

SQL_Tipos_de_Objeto

 

A lista completa de tipos, está no site da Microsoft.