User Function ExJobXPT() Local lRetJob := .F. // Tenta obter acesso exclusivo pra gravar a variável global While !( GlbLock() ) Sleep(5) End While //Define e seta o valor nas variáveis globais PutGlbValue("lRetExec", lRetJob ) PutGlbValue("cTexto", "Teste" ) //Libera o acesso excluvivo a pilha de variáveis globais GlbUnlock() //Executa rotina em uma nova Thread StartJob("U_ExecXPTO",GetEnvServer(),.T.) // Le os valores gravado pela função onde a váriavel global foi alterada. lRetJob := GetGlbValue("lRetExec") If lRetJob Conount(GetGlbValue("cTexto")) Else Conount("Retornou Falso") EndIf Return
// Função executada em um botão do menu do protheus User Function ProcInic() Public cHoraIni := TIME() // Seu Código Return // Função executada em um outro botão do menu do protheus User Function ProcFim() Local cDifTime := ElapTime ( cHoraIni, TIME() ) If cDifTime > "00:03:00" Alert("O tempo de execução entre a função inicial e final demorou mais de 3 minutos.") EndIf Return
#Include "Protheus.ch" Static nVar := 0 User Function Pai() nVar += 10 conOut("Pai") conOut(nVar) Filho() // Muito importante limpar o valor da váriavel static ao concluir sua utilização nVar := 0 Return Static Function Filho() nVar += 10 conOut("Filho") conOut(nVar) Neto() Return Static Function Neto() nVar += 10 conOut("Neto") conOut(nVar) ReturnMuito importante lembrar a necessidade de limpar a variável ao final de sua utilização, pois se as funções foram executadas novamente sem essa limpeza pode acarretar em valores errôneos.
User Function Pai() Filho() If Type("cNome") == "C" conOut(cNome) Else conOut("Variável não definida") EndIf Return Static Function Filho() Private cNome := "Paulo" Neto() conOut("Filho") conOut(cNome) Return Static Function Neto() conOut("Neto") If Type("cNome") == "C" conOut(cNome) EndIf Return
User Function Pai() Local cVarNome := "Paulo" conOut(cVarNome) Filho() Return Static Function Filho() Local cVarNome := "Henrique" conOut(cVarNome) ReturnUm detalhe muito importante do escopo de variáveis é que elas podem ser subsistidas por uma variável de escopo menor caso a mesma seja declarada dentro do local utilizado, por exemplo. Se eu possuir uma variável Public cXPTO com o valor “A” já declarado e dentro de uma novo fonte eu declarar uma variável Static cXPTO com o valor “B” as duas variáveis existirão, mas o sistema vai priorizar o escopo mais baixo para a utilização no processamento corrente. Esta sequência hierárquica de escopo é : Public > Static > Private > Local . O escopo Global não entra nessa hierarquia pois o mesmo é definido e acessado de forma diferente dos outros. É isso pessoal, espero que ajude muito vocês e se tiveram alguma dúvida só deixar nos comentários.
Para você que tem dificuldade de concentração no momento de trabalho, assim como eu, vou dar algumas dicas que vão ajudar muito na sua capacidade de concentração, criativa e cognitiva.
Veja essas dicas:
No meu caso, sempre que preciso fazer tarefas onde preciso de foco total, eu coloco uma playlist de Rock que eu mesmo montei. Dessa forma tiro totalmente o som externo, as conversas e distrações que tiram meu foco.
Pode ser o tipo de música que você preferir, no meu caso foi o bom e velho Rock And Roll .
Vou deixar minha playlist do Spotify aqui caso alguém queira fazer as “Pedras rolarem”.
Uma dica muito importante, para você que acaba se perdendo no tempo, ou se aguem te chama a todo momento, é utilizar uma agenda para organizar suas tarefas.
Pode ser um agenda de papel (raiz) ou algo mais moderno como utilizar a agenda do Google Calendar ou qualquer agenda virtual, o importante é se organizar.
Tenha uma forma de organizar a ordem das suas tarefas, assim você não esquece de nenhuma e vai ter uma produtividade muito maior.
Existem diversas ferramentas e metodologias para isso.
Uma metodologia muito útil para isso é o Scrum que foi desenvolvido para gerenciar projetos, organizar tarefas e agilizar processos. Para mim ele é muito mais que uma ferramenta de trabalho e pode ser empregado em todas as áreas da sua vida.
Uma ferramenta bem bacana que uso para organizar minhas tarefas é o Trello. Essa ferramenta te ajuda a organizar suas tarefas em card’s e dividi-las em etapas de processo.
É muito importante fazer pausas durante o expediente. Nenhuma mente é produtiva 100% do tempo, e sem as pausas nossa mente e nosso corpo pode chegar a uma exaustão e comprometer a qualidade do seu trabalho.
Então, faça pausa para tomar um café, distrair a cabeça ou até mesmo bater um papo com algum colega de trabalho.
É isso mesmo, as vezes desviar o foco te ajuda a ter foco no momento correto !!!
Essas são as minhas dicas para que seu trabalho seja mais produtivo e com uma melhor qualidade.
Muitas vezes sentimos uma performance terrível em nosso banco de dados.
Um dos fatores que pode fazer isso acontecer é a defasagem dos índices das tabelas de nosso banco.
Isso acontece devido a grande quantidade de manipulações dos dados, principalmente com os comandos Insert e Delete.
Para isso podemos criar um script para reorganizar, e dependendo dos casos recriar os índices do nosso SQL Server…
Essas ações melhoram o desempenho do banco.
Vou explicar os passos para montar esse Script que vai te ajudar muito.
Primeiramente, vamos criar algumas variáveis de controle que serão utilizadas no momento da leitura dos índices…
DECLARE @tableName nvarchar(500) DECLARE @indexName nvarchar(500) DECLARE @percentFragment decimal(11,2) DECLARE @page_count int
Na sequência vamos definir nosso Cursor, que servirá para armazenar a lista de índices que iremos realizar a manutenção.
Dentro da criação do cursor, escrevemos um comando Select que vai cruzar dados entre a tabela de status dos índices (sys.dm_db_index_physical_stats), a tebela de tabelas(sys.tables), a tabela de Schemas(sys.schemas) e a tabela de Índices(sys.indexes).
Definimos um parâmetro de busca de fragmentação onde o % de fragmentação for maior que 5% e a quantidade de páginas do índice for maior que 10.
Com isso começamos a pegar os índices que já começam a apresentar lentidão nas consultas…
DECLARE FragmentedTableList cursor for SELECT dbtables.[name] AS 'Table', dbindexes.[name] AS 'Index', indexstats.avg_fragmentation_in_percent, indexstats.page_count FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS indexstats INNER JOIN sys.tables dbtables ON dbtables.[object_id] = indexstats.[object_id] INNER JOIN sys.schemas dbschemas ON dbtables.[schema_id] = dbschemas.[schema_id] INNER JOIN sys.indexes dbindexes ON dbindexes.[object_id] = indexstats.[object_id] AND indexstats.index_id = dbindexes.index_id AND dbindexes.[name] IS NOT NULL WHERE indexstats.database_id = DB_ID() AND indexstats.avg_fragmentation_in_percent > 05 AND indexstats.page_count > 10 ORDER BY indexstats.page_count DESC, indexstats.avg_fragmentation_in_percent DESC OPEN FragmentedTableList
Por último, vamos abri o cursor, fazer a leitura dos índices e executar as devidas manutenção:
Quando o percentual de fragmentação estiver entre 5% e 30%, vamos realizar o reorganize do índice, ou seja, vamos reorganizar este índice.
Agora, se o percentual for maior que 30% vamos realizar o rebuild do índice, ou seja, realizar a reconstrução do mesmo, pois a defasagem do mesmo já esta bem critica.
FETCH NEXT FROM FragmentedTableList INTO @tableName, @indexName, @percentFragment, @page_count WHILE @@FETCH_STATUS = 0 BEGIN PRINT 'Processando ' + @indexName + ' na tabela ' + @tableName + ' com ' + CAST(@percentFragment AS NVARCHAR(50)) + '% fragmentado' IF(@percentFragment BETWEEN 05 AND 30) BEGIN EXEC( 'ALTER INDEX ' + @indexName + ' ON ' + @tableName + ' REORGANIZE;') PRINT 'Concluindo a reorganização do índice ' + @indexName + ' da tabela ' + @tableName END ELSE IF (@percentFragment > 30) BEGIN EXEC( 'ALTER INDEX ' + @indexName + ' ON ' + @tableName + ' REBUILD; ') PRINT 'Concluindo a recriação do índice ' + @indexName + 'da tabela ' + @tableName END FETCH NEXT FROM FragmentedTableList INTO @tableName, @indexName, @percentFragment,@page_count END CLOSE FragmentedTableList DEALLOCATE FragmentedTableList
Agora vejam o exemplo completo do nosso script:
DECLARE @tableName nvarchar(500) DECLARE @indexName nvarchar(500) DECLARE @percentFragment decimal(11,2) DECLARE @page_count int DECLARE FragmentedTableList cursor for SELECT dbtables.[name] AS 'Table', dbindexes.[name] AS 'Index', indexstats.avg_fragmentation_in_percent, indexstats.page_count FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS indexstats INNER JOIN sys.tables dbtables ON dbtables.[object_id] = indexstats.[object_id] INNER JOIN sys.schemas dbschemas ON dbtables.[schema_id] = dbschemas.[schema_id] INNER JOIN sys.indexes dbindexes ON dbindexes.[object_id] = indexstats.[object_id] AND indexstats.index_id = dbindexes.index_id AND dbindexes.[name] IS NOT NULL WHERE indexstats.database_id = DB_ID() AND indexstats.avg_fragmentation_in_percent > 05 AND indexstats.page_count > 10 ORDER BY indexstats.page_count DESC, indexstats.avg_fragmentation_in_percent DESC OPEN FragmentedTableList FETCH NEXT FROM FragmentedTableList INTO @tableName, @indexName, @percentFragment, @page_count WHILE @@FETCH_STATUS = 0 BEGIN PRINT 'Processando ' + @indexName + ' na tabela ' + @tableName + ' com ' + CAST(@percentFragment AS NVARCHAR(50)) + '% fragmentado' IF(@percentFragment BETWEEN 05 AND 30) BEGIN EXEC( 'ALTER INDEX ' + @indexName + ' ON ' + @tableName + ' REORGANIZE;') PRINT 'Concluindo a reorganização do índice ' + @indexName + ' da tabela ' + @tableName END ELSE IF (@percentFragment > 30) BEGIN EXEC( 'ALTER INDEX ' + @indexName + ' ON ' + @tableName + ' REBUILD; ') PRINT 'Concluindo a recriação do índice ' + @indexName + 'da tabela ' + @tableName END FETCH NEXT FROM FragmentedTableList INTO @tableName, @indexName, @percentFragment,@page_count END CLOSE FragmentedTableList DEALLOCATE FragmentedTableList
Agora o mesmo pode ser executado periodicamente, ajudando a melhorar a performance do banco de dados.
Espero que gostem!!!
Fala pessoal, tudo bem ??
Hoje vamos começar a construir o nosso primeiro banco de dados, utilizando o Microsoft SQL Server e a linguagem SQL.
Para isso, vamos entender um conceito bem bacana que utilizaremos no nosso exemplo de hoje.
Para pensarmos em um Filegroup de uma forma didática, podemos imagina-lo como um conjunto de pastas, onde cada pasta seria um Filegroup.
Em cada um desses Filesgroup’s possuímos documentos muito importantes que são frequentemente requisitados…
Se imaginarmos que duas pessoas precisem de documentos que estão em uma única pasta, será necessário que uma das pessoas fique esperando a outra terminar para utilizar a pasta e o documento.
No caso do banco de dados é parecido porem teremos problemas quando houver um grande numero de acessos a tabelas que estão no mesmo Filegroup, gerando uma lentidão e uma má performance do banco de dados.
Para que isso seja evitado, podemos dividir as tabelas mais acessadas em Filegroup’s diferentes, o que evitaria essa concorrência no acesso aos dados.
Para a criação do nosso primeiro banco de dados eu vou utilizar a plataforma do Microsoft SQL Server
Nele vamos clicar no botão New Query ou Nova Consulta.
Neste momento teremos nosso espaço de edição, dentro da ferramenta da Microsoft.
E agora começamos nossos comandos.
As clausulas iniciais do nosso comando de criação é o CREATE DATABASE com o nome do nosso banco de dados na sequencia.
Logo em seguida definimos o Filegroup principal utilizando a clausula ON PRIMARY a mesma recebera as informações referentes ao Filegroup primário.
Na clausula NAME definimos o nome que nosso Filegroup vai receber .
Já na clausula FILENAME definimos o caminho e o nome do arquivo físico referente ao Filegroup lembrando que para múltiplos Filegroup’s é interessante dividir em discos diferentes para melhorar a performance de acesso as tabelas que serão divididas entre eles.
Nas clausulas SIZE e MAXSIZE definimos os tamanhos iniciais e maximos que nossos Filegroup’s poderão atingir. Se você deseja ter um banco de dados escalável e sem problema de alocação de espaço no HD pode definir o tamanho no MAXSIZE como UNLIMITED ou seja Ilimitado.
A clausula FILEGROWTH define o percentual ou tamanho de crescimento após o tamanho máximo do banco atingido atingido, por exemplo ele cresce de 20% em 20%.
Para criar os demais Filegroup’s devemos utilizar a clausula FILEGROUP seguida do nome do Filegroup, lembrando que para os Filegroup’s secundários devemos utilizar utilizar a extensão “.NDF” que é referente a SecoNdary Data Files.
Por último temos o Filegroup de log, este grupo de arquivo armazenará os log’s de transações e o mesmo pode ser utilizado em eventuais recuperações do banco de dados.
Para criar este Filegroup utilizamos as clausulas LOG ON , lembrando que para o Filegroup de log devemos utilizar utilizar a extensão “.LDF” que é referente a Log Data File.
Abaixo temos um exemplo de criação de banco de dados, utilizando os comandos a cima.
CREATE DATABASE MERCADOPH ON PRIMARY( NAME = N'MERCADOPH', FILENAME = N'D:\BD\MERCADOPH.mdf' , SIZE = 6000KB , MAXSIZE = UNLIMITED, FILEGROWTH = 20% ), FILEGROUP MERCADOPHSEC( NAME = N'MERCADOPH_SEC', FILENAME = N'F:\BD\MERCADOPH_SEC.ndf' , SIZE = 6000KB ,MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'MERCADOPH_LOG', FILENAME = N'D:\BD\MERCADOPH_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10% ) GO
Pronto, com isso criamos nosso primeiro banco de dados.
Fiquem de olho porque vem mais coisa boa por ia.
Oi pessoal…
Hoje vou escrever aqui sobre o que é o tão poderoso e incrível SQL.
Bom na verdade SQL é uma linguagem, que significa Structured Query Language, ou Linguagem de Consulta Estruturada.
E para que serve esse negócio ???
A mais simples das explicações é : “Para você conseguir consultar e manipular dados contidos em um banco de dados…”
E o que é um banco de dados ?
Na verdade podemos imaginar um banco de dados como se fosse um banco onde guardamos nosso dinheiro.
Só que no lugar do dinheiro temos os dados que queremos armazenar.
E o mantemos seguros para serem acessados no momento em que precisarmos deles.
O Banco de dados consiste de alguns elementos principais:
Nas tabelas armazenaremos nossos registros, onde cada registro contem um conjunto de campos com seus respectivos dados, e os índices servem para conseguirmos encontrar os registros de uma forma mais rápida dentro da tabela.
Já as chaves servem para realizar junções entre tabelas, para assim conseguirmos cruzar informações.
Levando para a nossa analogia com o Banco de dinheiro :
Pode ser uma analogia simples mas desta forma já começamos a pensar de uma forma estruturada de como seria um banco de dados.
Existem vários tipos de bancos de dados no mercado, e cada um com suas características especificas.
Nos meus post’s vou utilizar mais o Microsoft SQL Server, porem como meu conteúdo é SQL a maioria das coisas que vou falar aqui poderão ser aplicadas em qualquer banco.
Agora que já temos o conceito básico do que é um Banco de Dados, vamos conhecer um pouquinho da divisão do que é a Linguagem SQL.
Apesar de ser uma única linguagem, ela é dividida em 3 partes principais(existem mais 2 partes que explicarei com mais calma em outro post):
DDL – Data Definition Language ou Linguagem de Definição de Dados: Apesar do nome esta parte da linguagem não tem interação com os dados e sim com a estrutura do banco de dados, como por exemplo comandos para criação, alteração e exclusão de tabelas, campos e índices.
Exemplos de comandos: CREATE, o ALTER e o DROP.
DML – Data Manipulation Language, ou Linguagem de Manipulação de Dados: Esta sim é a parte da linguagem que possui os comandos para manipulação dos dados, como por exemplo inclusão, alteração ou exclusão de dados.
Exemplos de comandos: INSERT, UPDATE e DELETE.
DQL – Data Query Language, ou Linguagem de Consulta de Dados: Esta parte da linguagem se destina a consulta de dados e é a que vamos utilizar a maior parte do tempo, mas não quer dizer que você só precisa conhecer ela, ate porque se não conhecer as outras não vai precisar utilizar essa.
Exemplos de comandos: SELECT, FROM, WHERE, ORDER BY e GROUP BY.
Os junção de vários destes comandos é chamada de Query, que serão utilizados para realizarmos todas as nossas manipulações dentro dos bancos de dados.
Nos próximos post’s vou começar a entrar melhor na linguagem SQL na prática e vamos fazer exemplos juntos.
Fiquem de olho no canal para alguns videos sobre os assuntos.
Espero que tenham gostado e até a próxima !!!