01 dezembro 2014

Job de backup para SQL 2000

Olá pessoal,

Esse job faz o backup automático do banco de dados as 17:00 H todos os dias, sobrescrevendo o que existir na pasta.


USE [msdb]

Go
IF  EXISTS (SELECT job_id FROM msdb.dbo.sysjobs_view WHERE name = N'BKP17')

EXEC msdb.dbo.sp_delete_job @job_name=N'BKP17'
Go

BEGIN TRANSACTION

DECLARE @ReturnCode INT

SELECT @ReturnCode = 0

IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)

BEGIN

EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END

DECLARE @jobId BINARY(16)

EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'BKP17',

@enabled=1,

@notify_level_eventlog=2,

@notify_level_email=0,

@notify_level_netsend=0,

@notify_level_page=0,

@delete_level=0,

@description=N'No description available.',

@category_name=N'[Uncategorized (Local)]',

@owner_login_name=N'sa', @job_id = @jobId OUTPUT

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Step 1',

@step_id=1,

@cmdexec_success_code=0,

@on_success_action=1,

@on_success_step_id=0,

@on_fail_action=2,

@on_fail_step_id=0,

@retry_attempts=0,

@retry_interval=0,

@os_run_priority=0,

@subsystem=N'TSQL',

@command=N'BACKUP DATABASE [NomedoSeuBancoDados] TO  DISK = N''C:\BKP17'' WITH  INIT ,  NOUNLOAD ,  NAME = N''BKP17'',  NOSKIP ,  STATS = 10,  NOFORMAT , PASSWORD = N''''',

@database_name=N'master',

@flags=0

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'Schedule 1',

@enabled=1,

@freq_type=4,

@freq_interval=1,

@freq_subday_type=1,

@freq_subday_interval=0,

@freq_relative_interval=0,

@freq_recurrence_factor=0,

@active_start_date=20070101,

@active_end_date=99991231,

@active_start_time=170000,

@active_end_time=235959

IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'

IF (@@ERROR <> 0 OR @ReturnCode<> 0) GOTO QuitWithRollback

COMMIT TRANSACTION

GOTO EndSave

QuitWithRollback:

IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION

EndSave:

Go
Observação: Não testei com outras versões a partir do SQL2000.

14 agosto 2014

SQL- Dicas de Performance e boas práticas

Uma consulta mal elaborada pode afetar bastante a performance no seu banco de dados. Já vi consultas que não utilizam  as boas práticas, são funcionais para poucos registros, mas quando se trata de ambiente de produção onde as quantidades de registros são maiores, elas podem fazer a diferença.

Vou deixar algumas dicas que utilizo em minhas consultas:

Evite:
-  SELECT * FROM TABELA, pois cria uma sobrecarga maior sobre a tabela, entrada/saída e largura de banda na rede do servidor. É melhor especificar os campos que irá utilizar.
- Cursores.
- Evite funções como LOWER ou UPPER para comparar texto, pois não são necessárias para o SQL.
- Evite executar cálculos matemáticos na cláusula WHERE. Se possível, envie esses cálculos já prontos da aplicação.
- Evite usar gatilhos como as TRIGGERs. Use-os apenas como último recurso.
- Evite usar funções ou não exagere no uso delas.

Prefira:
- Essa dica é muito importante,seguir  a ordem de performance dos operadores nos filtros WHERE :
1º (=),2º (>, >=, <, <=),3º(LIKE),4º(<>).
- As consultas com a condição WHERE conectadas por operadores AND são avaliadas da esquerda para a direita. Então, caso uma das operações seja falsa, não importam as demais: a linha será rejeitada. Logo, é melhor colocar as colunas com maior probabilidade de serem falsas no começo do WHERE e poupar processamento nesses casos.
- Prefira manter a integridade do banco com CONSTRAINTs. 
- As colunas que que mais utiliza nas condições do WHERE e JOIN , índices nas tabelas.
- Para apagar todas as linhas de uma tabela, prefira o comando TRUNCATE TABLE ao invés de DELETE.
- Sempre restrinja a quantidade de linhas e colunas retornadas em suas consultas economizando o disco, memória e rede do servidor.Tente filtrar corretamente na cláusula WHERE.
- Quando o retorno for de muitos registros utilize o comando TOP (TOP 1, TOP 10, TOP 1000 etc...).
- Tente trocar o operador IN ou NOT IN por EXISTS ou NOT EXISTS, quando for possível, pois os operadores IN criam uma sobrecarga maior no banco de dados.
- Substituir o IN por BETWEEN.
- Às vezes é melhor usar várias consultas unidas com UNION ALL do que uma consulta com vários OR em sua cláusula WHERE.
- Quando existir uma cláusula HAVING, é melhor fazer a maior parte da filtragem possível na WHERE e deixar a HAVING mais enxuta possível.
- Caso haja a necessidade de retornar alguns dados da consulta o mais rápido possível, mesmo que não seja o resultado total, pode-se usar a opção FAST.
- Se possível, prefira usar UNION ALL ao invés de UNION. O UNION elimina as duplicatas, mas isso exige um processamento maior.
- Prefira usar tabelas variáveis do que tabelas temporárias.
- Se uma tabela tem uma chave primária IDENTITY e sofre muitas inserções simultâneas, faça seu índice na chave primária ser não-clusterizado para evitar gargalos de performance.
- Toda tabela relacional deveria ter uma chave primária. Salvo exceções, claro, como modelagens de data warehouses e semelhantes.
- Use (NOLOCK) após os nomes de tabelas, até mesmo nos Joins. É importante, pois alguns processos são feitos por transações que bloqueiam as tabelas até serem finalizados, com (NOLOCK) as tabelas não são travadas, impedido uma lentidão em sua consulta.
- Prefira o LIKE ao invés do SUBSTRING.
-Tente acessar tabelas grandes apenas 1 vez na sua consulta
- Para lógicas muito extensas, prefira STORED PROCEDUREs.

Atente-se:
- Muitos problemas de performance que vi  em bancos de dados estavam relacionados a produtos cartesianos. Ocorrem quando fazemos algo de errado nos relacionamentos dos Joins ou Where.
- Verifique se as VIEWs, são realmente úteis. Caso não sejam, prefira consultar diretamente as tabelas.
- Em consultas muito frequentes, tente utilizar STORED PROCEDURE. Normalmente a performance melhora isso se deve à otimizações no plano de execução dos procedimentos armazenados.
- Verifique se o servidor não está com pouco espaço em disco. Recomendo pelo menos sempre 30% do disco livre.

Quem tiver algo a acrescentar ou a corrigir deixe um comentário aqui !!!

Fonte de pesquisa:
http://www.linhadecodigo.com.br/artigo/62/aumente-a-performance-do-sql-server.aspx
http://b.erickmendonca.com.br/post/48801937309/melhorando-a-performance-de-consultas-no-sql-server
http://www.infoworld.com/d/data-management/7-performance-tips-faster-sql-queries-262

04 agosto 2014

Teste rápido de envio de e-mail em C#

Olá pessoal, aqui segue um teste rápido de envio de e-mail.
Vamos lá para iniciar abrir uma console no Visual Studio C# e copiar e colar o código. Não se esqueça de fazer as alterações dos parâmetros de configurações, conforme eu explico no código.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Mail;
using System.Net.Mime;
using System.Net;
using System.Net.Configuration;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            MailMessage mailMessage = new MailMessage();
            //Remetente
            mailMessage.From =
                new MailAddress("emailremetente@gmail.com", "Aline");
            //Destinatário
            mailMessage.To.Add("emaildodestinatario@yahoo.com.br");
            mailMessage.Subject = "Assunto da mensagem";
            mailMessage.Body = "Mensagem do Corpo";
            //Para anexar 
            Attachment anexado = new Attachment("C:\\caminhodaimagemouarquivo.png", MediaTypeNames.Application.Octet);
            //Podem ser adicionados mais de um anexo 
mailMessage.Attachments.Add(anexado);
           

            mailMessage.IsBodyHtml = true;
            mailMessage.Priority = MailPriority.Normal;

            System.Net.Mail.SmtpClient smtpClient = new System.Net.Mail.SmtpClient("smtp.gmail.com",587);

            smtpClient.EnableSsl = true;
            smtpClient.Timeout = 50000;
            smtpClient.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
            //Email de envio 
            smtpClient.Credentials = new System.Net.NetworkCredential("seuemail@gmail.com", "suasenha");

            smtpClient.Send(mailMessage);
            smtpClient.Dispose();
         }

    }
}

Nesse exemplo estou utilizando o gmail, mas poderia se qualquer outro servidor. Vou deixar um link de sugestão para verificações das configurações de outros servidores https://br.answers.yahoo.com/question/index?qid=20130617110756AAdOm2G
Para verificar se há bloqueio nas portas
http://www.yougetsignal.com/tools/open-ports/

09 abril 2013

SQL- Como criar variáveis tipo tabela

Seja bem vindo,

Nesse post vou falar um pouco sobre uma situação onde eu precisei utilizar uma variável do tipo tabela.
Uma variável do tipo tabela é como uma variável do tipo varchar, int, char entre outros, mas com uma diferença nós criamos o tipo que será uma tabela, são utilizadas para armazenamento temporário de dados.

Problema: Precisei passar uma lista de códigos em string dessa forma '1,2,3' para um parâmetro e criar um filtro para que o meu retorno de registros fosse de acordo com eles.

                               

Solução: Criei um Tipo Tabela e depois declarei uma variável desse mesmo tipo na minha procedure.

Para criar o Tipo Tabela gerar o script de acordo com o seu contexto.

CREATE TYPE dbo.GrupoType AS TABLE (       
IDGRUPO INT NOT NULL        
PRIMARY KEY (IDGRUPO) 
) 
GO

Ele será exibido dentro de Tipos de Tabela Definidos pelo Usuário:



Logo após criei a procedure para fazer a chamada.

Declarei a variável  dessa forma: Declare @GrupoPessoa as GrupoType  
A seguir faço um While para inserir os valores do parâmetro @ListaGrupo  nessa variável do tipo tabela de forma que para cada linha seja adicionado um valor.
E por ultimo faço o filtro usando uma subquery com o select da variável tabela já populada.

CREATE PROCEDURE P_RELATORIO   
@LISTAGRUPO as varchar(max)  
  
AS  
DECLARE @GRUPOPESSOA GRUPOType  
DECLARE @RESULTADOGRUPO VARCHAR(MAX)    
  
 ---Insere em uma variável do tipo tabela os valores EX: '1,2,3'  
 -----------------------------------------------    
 IF LEFT(@LISTAGRUPO, 1)<> ','    
  BEGIN    
   SET @LISTAGRUPO = @LISTAGRUPO  + ','    
  END    
 WHILE charindex(',', @LISTAGRUPO)<> 0    
  BEGIN    
   SET @RESULTADOGRUPO  = ltrim(rtrim(substring(@LISTAGRUPO , 1 ,  
    charindex(',', @LISTAGRUPO)- 1)))    
   SET @LISTAGRUPO = ltrim(rtrim(right(@LISTAGRUPO ,  
   len(@LISTAGRUPO )- charindex(',', @LISTAGRUPO))))    
   INSERT INTO  @GRUPOPESSOA(IDGRUPO) VALUES (@RESULTADOGRUPO )    
  END      
-----------------------------------------------------  
--a variável @GRUPOPESSOA foi populada com os valores 1,2,3  
  
SELECT pes_CPF AS CPF,  
    pes_Nome AS NOME,  
    pes_CodigoGrupo AS CODGRUPO  
FROM PessoaFisica   
WHERE (pes_CodigoGrupo IN (SELECT IDGRUPO FROM @GRUPOPESSOA) OR @LISTAGRUPO IS NULL)    
  


Resultado:




Notas:
Aprendi fazer dessa forma, mas descobri que existem outras formas também.
Não consegui utilizar na versão SQL Server 9.0.4053, então atualizei para a versão  SQL Server 10.50.2500.