Só tenho uma coisa pra dizer…
| SQL Server 2008 Microsoft Certified Master: Knowledge Exam PATH ITTS INFORMATION TECHNOLOGY E TELECOM SERVICE XD4LAM50D9 |
Microsoft (088-970) |
Passed 17-Sep-2014 11:59 PM |
agora que venha o LAB…
Só tenho uma coisa pra dizer…
| SQL Server 2008 Microsoft Certified Master: Knowledge Exam PATH ITTS INFORMATION TECHNOLOGY E TELECOM SERVICE XD4LAM50D9 |
Microsoft (088-970) |
Passed 17-Sep-2014 11:59 PM |
agora que venha o LAB…
Esse script é uma modificação de um script do simple-talk apenas adicionar a opção de função para facilitar a vida
o importante para este script funcionar é:
#https://www.simple-talk.com/sql/database-administration/automated-script-generation-with-powershell-and-smo/
function global:Script-DBObjectsIntoFolders([string]$server, [string]$dbname, [string]$DirectoryToSave){
# set "Option Explicit" to catch subtle errors
set-psdebug -strict
$DirectoryToSaveTo=$DirectoryToSave # local directory to save build-scripts to
$servername=$server # server name and instance
$Database=$dbname # the database to copy from
$ErrorActionPreference = "stop" # you can opt to stagger on, bleeding, if an error occurs
Trap {
# Handle the error
$err = $_.Exception
write-host $err.Message
while( $err.InnerException ) {
$err = $err.InnerException
write-host $err.Message
};
# End the script.
break
}
# Load SMO assembly, and if we're running SQL 2008 DLLs load the SMOExtended and SQLWMIManagement libraries
$v = [System.Reflection.Assembly]::LoadWithPartialName( 'Microsoft.SqlServer.SMO')
if ((($v.FullName.Split(','))[1].Split('='))[1].Split('.')[0] -ne '9') {
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMOExtended') | out-null
}
$My='Microsoft.SqlServer.Management.Smo'
$s = new-object ("$My.Server") $ServerName # get the server.
$Server=$s.netname -replace '[\\\/\:\.]',' ' # remove characters that can cause problems
$instance = $s.instanceName -replace '[\\\/\:\.]',' ' # ditto
$DatabaseName =$database -replace '[\\\/\:\.]',' ' # ditto
$DirectoryToSaveTo=$DirectoryToSaveTo+$Server+'\'+$Instance+'\' # database scripts are local on client
if (!( Test-Path -path "$DirectoryToSaveTo" )) # create it if not existing
{$progress ="attempting to create directory $DirectoryToSaveTo"
Try { New-Item "$DirectoryToSaveTo" -type directory | out-null }
Catch [system.exception]{
Write-Error "error while $progress. $_"
return
}
}
<# now we will use the canteen system of SMO to specify what we want from the script. It is best to have a list of the defaults to hand and just override the defaults where necessary, but there is a chance that a later revision of SMO could change the defaults, so beware! #>
$CreationScriptOptions = new-object ("$My.ScriptingOptions")
$CreationScriptOptions.ExtendedProperties= $true # yes, we want these
$CreationScriptOptions.DRIAll= $true # and all the constraints
$CreationScriptOptions.Indexes= $true # Yup, these would be nice
$CreationScriptOptions.Triggers= $true # This should be included when scripting a database
$CreationScriptOptions.ScriptBatchTerminator = $true # this only goes to the file
$CreationScriptOptions.Filename = "$($DirectoryToSaveTo)$($DatabaseName)_Build.sql";
# we have to write to a file to get the GOs
$CreationScriptOptions.IncludeHeaders = $true; # of course
$CreationScriptOptions.ToFileOnly = $true # no need of string output as well
$CreationScriptOptions.IncludeIfNotExists = $true # not necessary but it means the script can be more versatile
$transfer = new-object ("$My.Transfer") $s.Databases[$Database]
$transfer.options=$CreationScriptOptions # tell the transfer object of our preferences
$scripter = new-object ("$My.Scripter") $s # script out the database creation
$scripter.options=$CreationScriptOptions # with the same options
$scripter.Script($s.Databases[$Database]) # do it
"USE $Database" | Out-File -Append -FilePath "$($DirectoryToSaveTo)$($DatabaseName)_Build.sql"
"GO" | Out-File -Append -FilePath "$($DirectoryToSaveTo)$($DatabaseName)_Build.sql"
# add the database object build script
$transfer.options.AppendToFile=$true
$transfer.options.ScriptDrops=$true
$transfer.EnumScriptTransfer()
$transfer.options.ScriptDrops=$false
$transfer.EnumScriptTransfer()
"All written to $($DirectoryToSaveTo)$($DatabaseName)_Build.sql"
}
Teremos um grande evento da comunidade SQL no Brasil…. o SQL Saturday #245…
O SQL Saturday é totalmente gratuito e focado em SQL Server, um dia inteiro de palestras técnicas. No momento o evento encontra-se com o Call for Speakers aberto, ou seja, recebendo inúmeras propostas de palestras, tendo até agora já recebido propostas de palestrantes de vários locais do Brasil e inclusive de outros países !!!
Trata-se da 2a edição do evento, que ocorreu com muito sucesso em abril de 2012, contando na época com mais de 300 participantes.
SQL Saturday é uma marca de eventos já conhecida mundialmente pela alta qualidade técnica. A marca pertence a uma organização chamada SQL PASS, cujo trabalho envolve apoiar grupos de usuários de SQL Server – denominados de PASS Chapter – por todo o mundo.
O SQL PASS cede a marca, bem como algumas ferramentas on-line, patrocinio e orientação para que o PASS Chapter da região realize o evento. No Rio de Janeiro o evento está sendo realizado pelo PASS Chapter devSQL, o mais antigo PASS Chapter do Brasil, liderado por Dennes Torres (t | b).
As inscrições para o evento estão abertas e, como citado antes, é totalmente gratuito. Trata-se do 2o evento realizado no Brasil. O primeiro, realizado em São Paulo por outro PASS Chapter, ficou totalmente lotado antes mesmo da grade de palestras ser definida.
Evento : SQL Saturday #245 – Rio de Janeiro
Data : 31/08
Horário : Abertura as 08:00hs, inicio das palestras as 09:00hs até as 18hs
Local : Universidade Veiga de Almeida
Endereço : Rua Ibituruna, 108, tijuca, próximo a estação São Cristóvão do metrô
Site do Evento : http://www.sqlsaturday.com/245/eventhome.aspx
Vamos estressar um pouco de memória?
Seguindo a mesma idéia do post anterior, esse script em powershell server para estressar memória, gerando alocação em variável de letras ‘a’ em blocos de 128MB.
Dependendo da sua configuração, isso pode gerar grande stress de disco na unidade onde o page file está alocado…
$mem_total =[int](
Get-WMIObject -class Win32_PhysicalMemory |
Measure-Object -Property capacity -Sum |
ForEach-Object {[math]::round(($_.Sum / 1GB - 2),2)}) #memoria total da maquina –2GB
$mem_stress = @()
$mem_loop = $mem_total * 8 #multiplica pq o tamanho da alocacao e 128mb
$i = 0
while ($i -le $mem_loop)
{
$mem_stress + ("a" * 128MB)
Start-Sleep -s 1
write-host $i
$i++
}
Basicamente não precisa deixar rodar até o final,,, apenas comece e pare a execução,,,
na pior das situações você terá que finalizar o processo do powershell pelo gerenciador de tarefas,,,
sempre lembrando,,, quer emoção? faça em produção,,,, depois não reclama se alguém brigar com você… ![]()
Acho que uma das piores coisas é chegar em um cliente e ver que ele tem recurso de Hardware mas alguém fez a infelicidade de instalar o SQL x86 ao invés de instalar a opção x64…
Isso porque o cara tem que escolher explicitamente a instalação x86,,,
Aí você pergunta para o infeliz o motivo da escolha e ele responde que ou não sabe a diferença, ou que como o sistema dele é todo x86 ele instalou o banco desta forma para manter compatibilidade…
bom,,, não importa qual a desculpa,,, tem uma forma de alterar a instalação feita e converter o executável do serviço de x86 para x64,,,
para SER BEM CLARO não faça isso no seu ambiente de produção SEM TESTAR antes,,, é por sua total conta e risco…
vamos usar o powershell para executar uma chave encriptada,,, essa chave vai alterar algumas informações de chaves de registro que o executável do serviço do SQL utiliza para carregar os binários para o SQLOS .
$Key = (1..16)
$chave = ('76492d1116743f0423413b16050a5345MgB8ADYANwBTAEIAegBrADQASwBQAFEAKwBjAEUAMABaAE0AdgBiAFIARABMAEEAPQA9AHwANwAyADIANQBkADMANABjADUAYQAwAGUAMgAxADEAYQA1AGQAYQAyADIANAAwADYAYwAyADIAMQAwADIAZQA5AGMAOAA2ADAAZgA0ADIAOABlAGIAYwBlADEAYQA1AGIAZQBhADcAYgA5ADEAZAA3AGIAYQA4ADQAYwA3ADMAYQA=')
$chave1 = convertto-securestring $chave -key $key
Start-Sleep -s 5
$a = new-object -comobject wscript.shell
$b = $a.popup([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($chave1)),0,”Conversao de x32 para x64”,1)
(new-object -com SAPI.SpVoice).speak($chave1)
Boas modificações !!!
Algumas vezes procurando por erros nos eventos de sistema, já me deparei com uma mensagem de informação bem estranha:
MSSQLSERVER Information System Event 17055 <SQL server Instance Name > “The description for Event ID ( 17055 ) in Source ( MSSQLSERVER ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: 18265, Log backed up: Database: Database Name, creation date(time): 2012/07/11(09:38:17), first LSN: 720:282:1, last LSN: 720:282:1, number of dump devices: 1, device information: (FILE=1, TYPE=DISK: {‘\\ServerLog02\BACKUP\Backup123.TRN’}).
Eu sei que não é um erro de backup, se procurar os MSDB ou no job de backup não tem nenhum erro na geração do arquivo e o arquivo está no devido local.
Isso acontece porque o Event Viewer não consegue interpretar a mensagem colocada pelo SQL nos registros de eventos… A causa mais provável é que o caminho da biblioteca que passa a informação de como o Event Viewer deve interpretar a informação gravada está no lugar errado…
Como fazer para corrigir isso? até que é bem simples…
Isso se aplica a SQL 2000, 2005 e 2008,, ainda não tive esse tipo de problema com o 2012
Comecei alguns desafios com a equipe de banco da empresa pedindo algumas soluções para um problema…
Semana passada eles tinham que entregar um código que mostra-se uma tabuada… mas haviam algumas premissas:
O pessoal se empenhou e vieram com códigos interessantes…
um deles foi:
DECLARE @InicNum int, @FimcNum int SET @InicNum = 5 SET @FimcNum = 7 ;WITH numeros AS ( SELECT number AS N FROM master..spt_values WHERE type = 'P' AND number BETWEEN CAST(@InicNum AS varchar) AND CAST(@FimcNum AS varchar) ), F1 AS( select number as N from spt_values where type = 'P' AND number BETWEEN 1 AND 10 ), produto AS ( SELECT M = n2.N, F = n1.N, P = n1.N * n2.N FROM F1 n1 CROSS JOIN numeros n2 ) SELECT cast(M as varchar(2)) + ' x ' + cast(F as varchar(2)) + ' = ' + cast(P as varchar(3)) FROM produto order by M
outra opção:
DECLARE @CALC1 INT, @CALC2 INT DECLARE @NUM1 VARCHAR(500), @NUM2 VARCHAR(500) , @RESTO VARCHAR(500), @LINHA NVARCHAR(500) SET @CALC1 = 1 WHILE @CALC1 <= 10 -- AQUI BEGIN SET @LINHA = @CALC1 SELECT '" TABUADA DO ' + CONVERT(VARCHAR(15),@LINHA) + ' "' SET @CALC2 = 1 WHILE @CALC2 <= 10 -- BEGIN SET @NUM1 = @CALC1 SET @NUM2 = @CALC2 SET @RESTO = @CALC1 * @CALC2 SELECT @NUM1 + 'X' + @NUM2 + ' = ' + @RESTO AS 'TABUDA' SET @CALC2 = @CALC2 + 1 END SET @CALC1 = @CALC1 + 1 END
Mais uma…
SET nocount on go declare @i int set @i = 3 declare @f int set @f = 20 declare @1 int set @1 = 1 declare @2 int set @2 = 2 declare @3 int set @3 = 3 declare @4 int set @4 = 4 declare @5 int set @5 = 5 declare @6 int set @6 = 6 declare @7 int set @7 = 7 declare @8 int set @8 = 8 declare @9 int set @9 = 9 declare @10 int set @10 = 10 WHILE @i <= @f BEGIN BEGIN SELECT convert(varchar(2),@1)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) SELECT convert(varchar(2),@2)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) SELECT convert(varchar(2),@3)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) SELECT convert(varchar(2),@4)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) SELECT convert(varchar(2),@5)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) SELECT convert(varchar(2),@6)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) SELECT convert(varchar(2),@7)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) SELECT convert(varchar(2),@8)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) SELECT convert(varchar(2),@9)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) SELECT convert(varchar(2),@10)+'x'+convert(varchar(20),@i)+'='+convert(varchar(20),@i) END SET @i = @i + 1 END
E a última…
declare @i int declare @y int declare @num varchar(max) declare @num2 varchar(max) declare @res varchar(max) -- Atribui @y = Tabuada começa do 1 - set @y=1 -- Enquanto @y menor ou igual a 10, vai ate tabuada do 10 - while @y<=10 -- Inicio 1 begin -- Atribui @i = 1 começa com x 1, no caso 1 x 1 ou então(@y x @i ) set @i=1 -- Enquanto @i menor ou igual a 10 - vai ate x 10 while @i<=10 -- Inicio 2 begin -- Atribui @num = @i set @num = @i; -- Atribui @num2 = @y set @num2 = @y; -- Atribui @res = @y * @i set @res = @y*@i -- Mostrando o Resultado da tabuada concatenando os resultados - print @num2+'x'+@num+'='+@res -- Atribui @s a ele mesmo + 1, 'próximo valor de @s' - soma para ir ao próximo numero - set @i=@i+1 -- Inicio 2 end -- Atribui @y a ele mesmo + 1, 'próximo valor de @y' - soma para ir a proxima tabuada - set @y=@y+1 -- Imprime enter e '---------' enter - só o espaçamento entre tabuadas print Char(13)+'----'+Char(13) -- Fim Inicio 1 end
Montei um script de powershell que cria uma tela para facilitar a exportação de caixas de email do exchange 2010 para PST.
Ele é bem simples,,, Antes de carregar essa tela, ele vai tentar localizar seu servidor de Exchange, vai baixar o módulo EMS para sua maquina e ai ele libera o acesso a tela acima… (o processo de baixar o EMS pode demorar um pouco)
Para localizar alguma caixa utilize o campo “Localizar” e não esqueça de colocar um * (asterisco) e depois clique em “Localizar”
Na Grid abaixo ele vai mostrar todos os resultados para sua busca, selecione a caixa que você quer exportar.
No campo salvar você pode:
Clique em “Exportar”.
Detalhe muito importante:
| [PS] C:\Get-MailboxExportRequest | Get-MailboxExportRequestStatistics |
Para essa versão é isso,,, o download está no Skydrive.
O código ficou assim:
#Generated Form Function function GenerateForm { ######################################################################## # Generated On: 10/05/2012 12:16 # Generated By: Ricardo Leka # Site: http://leka.com.br # Twitter: @bigleka # Versao: 0.5 ######################################################################## #region Import the Assemblies [reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null #endregion #---------------------------------------------- # User Generated Script #---------------------------------------------- function Get-ExchangeServerInSite { $ADSite = [System.DirectoryServices.ActiveDirectory.ActiveDirectorySite] $siteDN = $ADSite::GetComputerSite().GetDirectoryEntry().distinguishedName $configNC=([ADSI]"LDAP://RootDse").configurationNamingContext $search = new-object DirectoryServices.DirectorySearcher([ADSI]"LDAP://$configNC") $objectClass = "objectClass=msExchExchangeServer" $version = "versionNumber>=1937801568" $site = "msExchServerSite=$siteDN" $search.Filter = "(&($objectClass)($version)($site))" $search.PageSize=1000 [void] $search.PropertiesToLoad.Add("name") [void] $search.PropertiesToLoad.Add("msexchcurrentserverroles") [void] $search.PropertiesToLoad.Add("networkaddress") $search.FindAll() | %{ New-Object PSObject -Property @{ Name = $_.Properties.name[0] FQDN = $_.Properties.networkaddress | %{if ($_ -match "ncacn_ip_tcp") {$_.split(":")[1]}} Roles = $_.Properties.msexchcurrentserverroles[0] } } } function Import-EMS { $servers = New-Object System.Collections.ArrayList Get-ExchangeServerInSite | %{ [void]$servers.Add(($_.fqdn)) } #select a random server from the current site if($servers.count -gt 1) { $random = Get-Random -Minimum 0 -Maximum $servers.count $fqdn = $servers[$random] } else { $fqdn = $servers[0] } try { $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$fqdn/PowerShell/" -Authentication Kerberos Import-PSSession $session } catch { [System.Windows.Forms.MessageBox]::Show( $_.Exception.Message, "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error ) } } $FormEvent_Load={ #TODO: Place custom script here if(!(get-command get-mailbox -EA 0)) { if(Get-PSSnapin -Registered "Microsoft.Exchange.Management.PowerShell.E2010" -EA 0) { Add-PSSnapin "Microsoft.Exchange.Management.PowerShell.E2010" } else { $message = [System.Windows.Forms.MessageBox]::Show( "Vou importar o EMS do Exchange. Espere... isso pode demorar um pouco.", "Conectando ao Exchange", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information ) Import-EMS } } } #region Generated Form Objects $form1 = New-Object System.Windows.Forms.Form $groupBox2 = New-Object System.Windows.Forms.GroupBox $statusbar1 = New-Object System.Windows.Forms.StatusBar $button3 = New-Object System.Windows.Forms.Button $button2 = New-Object System.Windows.Forms.Button $textBox2 = New-Object System.Windows.Forms.TextBox $groupBox1 = New-Object System.Windows.Forms.GroupBox $textBox1 = New-Object System.Windows.Forms.TextBox $button1 = New-Object System.Windows.Forms.Button $dataGridView1 = New-Object System.Windows.Forms.DataGridView $saveFileDialog1 = New-Object System.Windows.Forms.SaveFileDialog $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState #endregion Generated Form Objects #---------------------------------------------- #Generated Event Script Blocks #---------------------------------------------- #Provide Custom Code for events specified in PrimalForms. $button3_OnClick= { #TODO: Place custom script here if($textbox2.Text -eq "") { [System.Windows.Forms.MessageBox]::Show( "Voce precisa selecionar onde salvar...", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error ) } else { try { New-MailboxExportRequest -Mailbox $dataGridView1.SelectedCells[0].Value.ToString() -FilePath $textbox2.Text -ErrorAction Stop [System.Windows.Forms.MessageBox]::Show( "A exportacao foi colocada em fila com sucesso.", "exportacao", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Information ) $textbox2.Text = "" } catch { [System.Windows.Forms.MessageBox]::Show( $_.Exception.Message, "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error ) } } } $button2_OnClick= { #TODO: Place custom script here try { if($saveFileDialog1.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { $textbox2.Text = $saveFileDialog1.FileName.ToString() } } catch { [System.Windows.Forms.MessageBox]::Show( $_.Exception.Message, "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error ) } } $handler_saveFileDialog1_FileOk= { #TODO: Place custom script here } $handler_button1_Click= { #TODO: Place custom script here $textbox2.Text = "" $statusbar1.Text = "Status: Procurando..." try { $mailboxes = New-Object System.Collections.ArrayList if(!($textbox1.Text)) { $mailboxInfo = Get-Mailbox -resultsize unlimited -ErrorAction Stop | select Name,Alias,PrimarySMTPAddress,DistinguishedName } else { $mailboxInfo = Get-Mailbox $textbox1.Text -resultsize unlimited -ErrorAction Stop | select Name,Alias,PrimarySMTPAddress,DistinguishedName } if($mailboxInfo.count) { $mailboxes.AddRange($mailboxInfo) } else { $mailboxes.Add($mailboxInfo) } $datagridview1.DataSource = $mailboxes $form1.refresh() $statusbar1.Text = "" } catch { [System.Windows.Forms.MessageBox]::Show( $_.Exception.Message, "Erro", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error ) $statusbar1.Text = "" } } $OnLoadForm_StateCorrection= {#Correct the initial state of the form to prevent the .Net maximized form issue $form1.WindowState = $InitialFormWindowState } #---------------------------------------------- #region Generated Form Code $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 325 $System_Drawing_Size.Width = 631 $form1.ClientSize = $System_Drawing_Size $form1.DataBindings.DefaultDataSourceUpdateMode = 0 $form1.FormBorderStyle = 1 $form1.Name = "form1" $form1.Text = "Exportar para PST" # statusbar1 $statusbar1.Size = New-Object System.Drawing.Size(551,22) $statusbar1.TabIndex = 3 $statusbar1.Location = New-Object System.Drawing.Point(0,364) $statusbar1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation $statusbar1.Name = "statusbar1" $groupBox2.DataBindings.DefaultDataSourceUpdateMode = 0 $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 24 $System_Drawing_Point.Y = 237 $groupBox2.Location = $System_Drawing_Point $groupBox2.Name = "groupBox2" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 49 $System_Drawing_Size.Width = 577 $groupBox2.Size = $System_Drawing_Size $groupBox2.TabIndex = 4 $groupBox2.TabStop = $False $groupBox2.Text = "Salvar" $form1.Controls.Add($statusbar1) $form1.Controls.Add($groupBox2) $button3.DataBindings.DefaultDataSourceUpdateMode = 0 $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 496 $System_Drawing_Point.Y = 20 $button3.Location = $System_Drawing_Point $button3.Name = "button3" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 23 $System_Drawing_Size.Width = 75 $button3.Size = $System_Drawing_Size $button3.TabIndex = 2 $button3.Text = "Exportar" $button3.UseVisualStyleBackColor = $True $button3.add_Click($button3_OnClick) $groupBox2.Controls.Add($button3) $button2.DataBindings.DefaultDataSourceUpdateMode = 0 $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 319 $System_Drawing_Point.Y = 19 $button2.Location = $System_Drawing_Point $button2.Name = "button2" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 23 $System_Drawing_Size.Width = 33 $button2.Size = $System_Drawing_Size $button2.TabIndex = 1 $button2.Text = "..." $button2.UseVisualStyleBackColor = $True $button2.add_Click($button2_OnClick) $groupBox2.Controls.Add($button2) $textBox2.DataBindings.DefaultDataSourceUpdateMode = 0 $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 7 $System_Drawing_Point.Y = 20 $textBox2.Location = $System_Drawing_Point $textBox2.Name = "textBox2" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 20 $System_Drawing_Size.Width = 306 $textBox2.Size = $System_Drawing_Size $textBox2.TabIndex = 0 $groupBox2.Controls.Add($textBox2) $groupBox1.DataBindings.DefaultDataSourceUpdateMode = 0 $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 24 $System_Drawing_Point.Y = 13 $groupBox1.Location = $System_Drawing_Point $groupBox1.Name = "groupBox2" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 218 $System_Drawing_Size.Width = 577 $groupBox1.Size = $System_Drawing_Size $groupBox1.TabIndex = 3 $groupBox1.TabStop = $False $groupBox1.Text = "Localizar" $form1.Controls.Add($groupBox1) $textBox1.DataBindings.DefaultDataSourceUpdateMode = 0 $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 7 $System_Drawing_Point.Y = 20 $textBox1.Location = $System_Drawing_Point $textBox1.Name = "textBox1" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 20 $System_Drawing_Size.Width = 306 $textBox1.Size = $System_Drawing_Size $textBox1.TabIndex = 2 $groupBox1.Controls.Add($textBox1) $button1.DataBindings.DefaultDataSourceUpdateMode = 0 $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 463 $System_Drawing_Point.Y = 20 $button1.Location = $System_Drawing_Point $button1.Name = "button1" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 23 $System_Drawing_Size.Width = 75 $button1.Size = $System_Drawing_Size $button1.TabIndex = 1 $button1.Text = "Localizar" $button1.UseVisualStyleBackColor = $True $button1.add_Click($handler_button1_Click) $groupBox1.Controls.Add($button1) $dataGridView1.DataBindings.DefaultDataSourceUpdateMode = 0 $datagridview1.ShowEditingIcon = $False $datagridview1.AllowUserToAddRows = $False $datagridview1.AutoSizeColumnsMode = [System.Windows.Forms.DataGridViewAutoSizeColumnsMode]::Fill $datagridview1.ColumnHeadersDefaultCellStyle = $System_Windows_Forms_DataGridViewCellStyle_22 $datagridview1.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Right $datagridview1.SelectionMode = [System.Windows.Forms.DataGridViewSelectionMode]::FullRowSelect $datagridview1.BackgroundColor = [System.Drawing.Color]::FromArgb(255,255,255,255) $datagridview1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation $System_Windows_Forms_DataGridViewCellStyle_23 = New-Object System.Windows.Forms.DataGridViewCellStyle $System_Windows_Forms_DataGridViewCellStyle_23.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleLeft $System_Windows_Forms_DataGridViewCellStyle_23.BackColor = [System.Drawing.Color]::FromArgb(255,212,208,200) $System_Windows_Forms_DataGridViewCellStyle_23.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,0,3,1) $System_Windows_Forms_DataGridViewCellStyle_23.ForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0) $System_Windows_Forms_DataGridViewCellStyle_23.SelectionBackColor = [System.Drawing.Color]::FromArgb(255,10,36,106) $System_Windows_Forms_DataGridViewCellStyle_23.SelectionForeColor = [System.Drawing.Color]::FromArgb(255,255,255,255) $System_Windows_Forms_DataGridViewCellStyle_23.WrapMode = [System.Windows.Forms.DataGridViewTriState]::True $datagridview1.RowHeadersDefaultCellStyle = $System_Windows_Forms_DataGridViewCellStyle_23 $System_Windows_Forms_DataGridViewCellStyle_24 = New-Object System.Windows.Forms.DataGridViewCellStyle $System_Windows_Forms_DataGridViewCellStyle_24.Alignment = [System.Windows.Forms.DataGridViewContentAlignment]::MiddleLeft $System_Windows_Forms_DataGridViewCellStyle_24.BackColor = [System.Drawing.Color]::FromArgb(255,255,255,255) $System_Windows_Forms_DataGridViewCellStyle_24.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",8.25,0,3,1) $System_Windows_Forms_DataGridViewCellStyle_24.ForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0) $System_Windows_Forms_DataGridViewCellStyle_24.SelectionBackColor = [System.Drawing.Color]::FromArgb(255,10,36,106) $System_Windows_Forms_DataGridViewCellStyle_24.SelectionForeColor = [System.Drawing.Color]::FromArgb(255,255,255,255) $System_Windows_Forms_DataGridViewCellStyle_24.WrapMode = [System.Windows.Forms.DataGridViewTriState]::False $datagridview1.DefaultCellStyle = $System_Windows_Forms_DataGridViewCellStyle_24 $datagridview1.Location = New-Object System.Drawing.Point(16,69) $datagridview1.AllowUserToResizeRows = $False $datagridview1.RowHeadersVisible = $False # $datagridview1.TabIndex = 2 $datagridview1.ReadOnly = $True $datagridview1.AllowUserToDeleteRows = $False $datagridview1.MultiSelect = $False $datagridview1.ColumnHeadersHeightSizeMode = [System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode]::AutoSize $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 6 $System_Drawing_Point.Y = 49 $dataGridView1.Location = $System_Drawing_Point $dataGridView1.Name = "dataGridView1" $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 163 $System_Drawing_Size.Width = 565 $dataGridView1.Size = $System_Drawing_Size $dataGridView1.TabIndex = 0 $groupBox1.Controls.Add($dataGridView1) $System_Drawing_Point = New-Object System.Drawing.Point $System_Drawing_Point.X = 24 $System_Drawing_Point.Y = 292 $System_Drawing_Size = New-Object System.Drawing.Size $System_Drawing_Size.Height = 23 $System_Drawing_Size.Width = 577 $savefiledialog1.Filter = "Arquivo PST (*.pst)|*.pst" $saveFileDialog1.DefaultExt = "PST" $saveFileDialog1.InitialDirectory = "c:\" $saveFileDialog1.ShowHelp = $True $saveFileDialog1.add_FileOk($handler_saveFileDialog1_FileOk) #endregion Generated Form Code #Save the initial state of the form $form1.add_Load($FormEvent_Load) $InitialFormWindowState = $form1.WindowState #Init the OnLoad event to correct the initial state of the form $form1.add_Load($OnLoadForm_StateCorrection) #Show the Form $form1.ShowDialog()| Out-Null } #End Function #Call the Function GenerateForm
Para a próxima versão:
Olá pessoal, complementando o Webcast que apresentei em 11/04 estou disponibilizando os arquivos SQL de exemplo, arquivo PPT e o Dashboard em Excel.
[slideshare id=12617869&doc=waitstatseextendedevents-120420080039-phpapp02]
SkyDrive – WT_EE.RAR / MIrror – WT_EE.RAR
Link para a gravação do Webcast.
Lembrete:
Bom, por enquanto é isso.
Como todo o bom DBA você tem um plano de manutenção configurado para seu ambiente SQL.
Você costuma fazer rebuild/reindex, update statistics, backup, garante que o HA está funcionado,,,
Você provavelmente deve ter a opção de “auto update statistics” habilitada em suas
bases e sabe como ela funciona,,, certo?
Bom,,, no bom e velho “by the book” o “auto update statistics” funciona assim:
Até aí nenhuma novidade certo? certo….
Com esse conceito em mente,,, imagine que você tem umas 40 tabelas com alguns 14.000.000 de registros cada, umas outras 200 tabelas com uns 30.000 registros cada,,, você sabe quem vai ser a próxima vítima do malévolo processo de “auto update statistics” ?
Acho que muito poucas pessoas tem a opção de “auto update statistics asynchronously” habilitada, então alguma query vai sofrer com a espera da atualização de uma estatística e alguém vai achar que é lentidão no sistema… ![]()
Então como monitorar a quantidade de alterações de uma tabela pra saber se ela está chegando aos malvados 20% +500 ?
Tá lá uma query:
/*SQL 2005*/ SELECT SO.NAME AS tableName, SC.NAME AS columnName, SSC.*, SSR.* FROM sys.sysrowsetcolumns SSC INNER JOIN sys.sysrowsets SSR ON SSC.rowsetID = SSR.rowsetID INNER JOIN sys.sysobjects SO ON SSR.idmajor = SO.id INNER JOIN sys.syscolumns SC on SSR.idmajor = SC.id AND SSC.rowsetcolid = SC.colid WHERE SO.xtype = 'U' ORDER BY so.name, sc.colid /*SQL 2008*/ SELECT SO.NAME AS tableName, SC.NAME AS columnName, SSC.*, SSR.* FROM sys.sysrscols SSC INNER JOIN sys.sysrowsets SSR ON SSC.rowsetID = SSR.rowsetID INNER JOIN sys.sysobjects SO ON SSR.idmajor = SO.id INNER JOIN sys.syscolumns SC on SSR.idmajor = SC.id AND SSC.rscolid = SC.colid WHERE SO.xtype = 'U' ORDER BY so.name, sc.colid
Não conseguiu executar??????? hehehehe ![]()
Precisa habilitar o DAC, as tabelas sysrscols, sysrowsetcolumns e sysrowsets só podem ser acessadas pelo DAC.
Outra coisa, não esqueça de mudar a base,,,
Mas até ai, o que tem de interessante no resultado?
O nome da tabela já sabemos, qual a coluna? grande coisa,,, o que importa é a coluna rcmodified e a coluna rcrows, quantidade de modificações e contagem de linhas respectivamente.
Agora sim,,, já começamos a ter alguma coisa legal…. mas tem como melhorar? sabemos as tabelas e as colunas… temos como saber quais as estatísticas que vão ser impactadas pela atualização? Claro…
/*SQL 2005*/ SELECT SO.NAME AS tableName, COL_NAME(sc.object_id, sc.column_id) AS columnName, A.name as stats_name, SSC.*, SSR.* FROM sys.sysrowsetcolumns SSC INNER JOIN sys.sysrowsets SSR ON SSC.rowsetID = SSR.rowsetID INNER JOIN sys.sysobjects SO ON SSR.idmajor = SO.id INNER JOIN sys.stats_columns SC on SSR.idmajor = SC.object_id AND SSC.rowsetcolid = SC.column_id INNER JOIN sys.stats as A ON A.object_id = SO.id WHERE SO.xtype = 'U' ORDER BY so.name, sc.column_id /*SQL 2008*/ SELECT SO.NAME AS tableName, COL_NAME(sc.object_id, sc.column_id) AS columnName, A.name as stats_name, SSC.*, SSR.* FROM sys.sysrscols SSC INNER JOIN sys.sysrowsets SSR ON SSC.rowsetID = SSR.rowsetID INNER JOIN sys.sysobjects SO ON SSR.idmajor = SO.id INNER JOIN sys.stats_columns SC on SSR.idmajor = SC.object_id AND SSC.rscolid = SC.column_id INNER JOIN sys.stats as A ON A.object_id = SO.id WHERE SO.xtype = 'U' ORDER BY so.name, sc.column_id
Isso é uma informação interessante,,, por que precisamos disso? Imagine uma tabela com alguns milhões de linhas, se a atualização de estatísticas ocorre apenas a cada 20%+500 modificações é bem provável que o intervalo entre uma atualização e a outra seja um pouco grande…
Aí você pergunta: mas eu faço rebuild dos meus índices com uma boa frequência e eu sei que, com esse processo, ele já faz a atualização das estatísticas, o que eu ganho com isso?
Ai eu respondo: Você pode ter estatísticas que são criadas automaticamente,,, lembra da opção do “auto create statistics” que costuma estar habilitada por padrão? da uma olhada na sua tabela, veja se existem estatísticas começando com _WA então,,, o rebuild de índices vai atualizas as estatísticas que ele utiliza e não todas as da tabela…
bom,,,, é isso,,, bom proveito…