Como não se atrasar para uma reunião – com o Zoom

Nessa época de pandemia estamos tendo que nos reinventar em muitas coisas que não dávamos importância, que eram tratadas como corriqueiras e bla bla bla… essa história triste todos já sabemos, estamos vivendo ela…

Quem tem criança sabe como está “interessante” ajustar a rotina para acompanhar os estudos, terem aulas online não significa facilidade para os pais, cada um tem seu horário, aulas em horários diferentes e esperar que a criança entenda que ela tem que entrar no link certo para a aula certa, dependendo da idade, pode ser complicado as vezes eles ainda nem sabem os dias da semana.

No nosso caso, a escola manda um arquivo pdf com uma grade para a semana, o mesmo link do zoom para as aulas recorrentes e links destintos para aulas “complementares”, o problema fica que a cada semana eles alteram o horário de inicio das aulas, essa falta de constante complica em se ajustar ao quadro de aula, como temos 2 peças raras e cada um tem uma agenda de inicio de aula diferente com quadro de aulas diferente no inicio da manhã fica uma correria em abrir o link para um em um computador e esperar até a hora do outro para abrir o link para o outro em outro computador, sair de uma “aula” para abrir o link para a outra e ter certeza que abriu o da semana certa no dia certo.

Com essa enrolação de contexto, agora vem a solução, afinal a TI veio para resolver problemas que não tínhamos que ela mesma causou.

O script abaixo ainda é um protótipo, basicamente é um powershell para ler a URL da reunião do Zoom, converter para um padrão usado pelo cliente do Zoom e criar uma tarefa no “Agendador de Tarefas” para que no horário específico ele abra o Zoom e entre na reunião automaticamente.

Como as aulas recorrentes acontecem com o mesmo link de reunião não tive que me importar em conseguir colocar várias execuções para a mesma tarefa do agendador, fica mais prático para organização, eu poderia ter seguido a mesma lógica para as aulas adicionais, mas ficaria um serviço mau feito.

As aulas adicionais são tratadas como tarefas individuais no agendador.

* Comentário 1: eu poderia ter feito um replace mais simples e direto, mas preferi serializar para ficar mais didático.

* Comentário 2: Esse script funciona no Windows 8 para cima, para o Windows 7 estou trabalhando nas modificações de agendamento, pois no 7 os comandos no powershell são diferentes.

* Comentário 3: No “Agendador de Tarefas” crie um diretório chamado “Aulas”, fica mais fácil de organizar

$aula = "Aula Filho 0"

#Aula Recorrente
$url = "https://escola.zoom.us/j/3456031299?pwd=UUIzTxxxTASDFNMSjHHanpJVkhCZ007"
$dataSeg = "2020-07-27 8:50 AM"
$dataTer = "2020-07-28 9:50 AM"
$dataQua1 = "2020-07-29 8:50 AM"
$dataQua2 = "2020-07-29 10:27 AM"
$dataQui = "2020-07-30 9:50 AM"
$dataSex = "2020-07-31 9:50 AM"

#Aula Inglês
$urlIng = "https://escola.zoom.us/j/93298210546?pwd=Y1B6UGhKT2493057djGTDLceVp4Zz09"
$dataIng = "2020-07-29 9:44 AM"
$aulaIng = "Aula Ingles"

#Aula Música
$urlMusica = "9h00 às 9h40 https://escola.zoom.us/j/37400021157?pwd=OOOcjyys076hWENGQUJ3YjVpdz09"
$dataMusica = "2020-07-30 8:50 AM"
$aulaMusica = "Aula Musica"

#Aula Educação Física
$urlEdF = "https://escola.zoom.us/j/93048619154?pwd=TkYzSk5XMdnttha8654j2XTlEzQT09"
$dataEdF = "2020-07-31 8:50 AM"
$aulaEdF = "Aula Ed. Fisica"


#caminho do binário do Zoom
$caminho = "%APPDATA%\Zoom\bin\Zoom.exe"

#replace aula recorrente
$parte1 = $url -replace "\?", "&"
$parte2 = $parte1 -replace "/j/", "/join?action=join&confno="
#$parte3 = $parte2 -replace "https:", "%APPDATA%\Zoom\bin\Zoom.exe --url=zoommtg:"
$parte3 = $parte2 -replace "https:", " --url=zoommtg:"


#$parte3

#replace aula ingles
$parte1Ing = $urlIng -replace "\?", "&"
$parte2Ing = $parte1Ing -replace "/j/", "/join?action=join&confno="
$parte3Ing = $parte2Ing -replace "https:", " --url=zoommtg:"

#replace aula Musica
$parte1Musica = $urlMusica -replace "\?", "&"
$parte2Musica = $parte1Musica -replace "/j/", "/join?action=join&confno="
$parte3Musica = $parte2Musica -replace "https:", " --url=zoommtg:"

#replace aula Ed. Física
$parte1EdF = $urlEdF -replace "\?", "&"
$parte2EdF = $parte1EdF -replace "/j/", "/join?action=join&confno="
$parte3EdF = $parte2EdF -replace "https:", " --url=zoommtg:"


#w7
#Library\Microsoft\Windows\PowerShell\ScheduledJobs
#$trigger = New-JobTrigger -Once -At $dataSeg -At $dataTer -At $dataQua1 -At $dataQua2 -At $dataQui -At $dataSex
#Register-ScheduledJob -Name $aula -FilePath $caminho -ArgumentList $parte3 -Trigger $trigger 


#w8 +

#Cria o agendamento inicial para as aulas recorrentes 
$action = New-ScheduledTaskAction -Execute '%APPDATA%\Zoom\bin\Zoom.exe' -Argument $parte3

$trigger =  @(
            $(New-ScheduledTaskTrigger -Once -At $dataSeg),
            $(New-ScheduledTaskTrigger -Once -At $dataTer),
            $(New-ScheduledTaskTrigger -Once -At $dataQua1),
            $(New-ScheduledTaskTrigger -Once -At $dataQua2),
            $(New-ScheduledTaskTrigger -Once -At $dataQui),
            $(New-ScheduledTaskTrigger -Once -At $dataSex))

Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $aula -TaskPath "aulas"

#altera o agendamento para a adição das outras aulas
#ingles
$actionIng = New-ScheduledTaskAction -Execute '%APPDATA%\Zoom\bin\Zoom.exe' -Argument $parte3Ing
$triggerIng = New-ScheduledTaskTrigger -Once -At $dataIng
Register-ScheduledTask -Action $actionIng -Trigger $triggerIng -TaskName $aulaIng -TaskPath "aulas"


#Musica
$actionMusica = New-ScheduledTaskAction -Execute '%APPDATA%\Zoom\bin\Zoom.exe' -Argument $parte3Musica
$triggerMusica = New-ScheduledTaskTrigger -Once -At $dataMusica
Register-ScheduledTask -Action $actionMusica -Trigger $triggerMusica -TaskName $aulaMusica -TaskPath "aulas"

#Ed. Fisica
$actionEdF = New-ScheduledTaskAction -Execute '%APPDATA%\Zoom\bin\Zoom.exe' -Argument $parte3EdF
$triggerEdF = New-ScheduledTaskTrigger -Once -At $dataEdF
Register-ScheduledTask -Action $actionEdF -Trigger $triggerEdF -TaskName $aulaEdF -TaskPath "aulas"

Para uma imaginação mais fértil, da para usar isso para qualquer reunião com o Zoom #FicaDica

Para finalizar, quando não quiser mais as tarefas é só abrir o “Agendador de Tarefas” e apagar as tarefas

Não ganhou seus presentes de natal?

Não recebeu seus presentes de natal? então fala com o Grinch

Esse é a mesma coisa do post Feliz Natal em T-SQL, você precisa rodar em SQL 2008 ou superior… o arquivo com o código pode ser baixado aqui.


SELECT geometry::STGeomFromText('GEOMETRYCOLLECTION(
 POLYGON(
 (169 -166, 118 -152, 93 -154, 45 -192, 39 -208, 35 -233, 37 -262, 45 -289, 42 -328, 44 -347, 53 -376, 60 -359,
 64 -337, 63 -314, 59 -301, 48 -289, 50 -269, 54 -246, 60 -230, 72 -216, 57 -217, 73 -213, 68 -196, 75 -192,
 72 -197, 75 -213, 77 -198, 88 -180, 80 -198, 77 -214, 85 -245, 103 -248, 99 -245, 100 -242, 103 -240, 112 -240,
 104 -238, 106 -227, 116 -214, 129 -209, 139 -213, 134 -210, 142 -204, 150 -204, 143 -201, 147 -196, 154 -194,
 164 -196, 156 -193, 158 -185, 163 -177, 173 -174, 166 -174, 171 -165, 169 -166)
 ),
 POLYGON(
 (281 -177, 289 -176, 296 -179, 302 -182, 307 -187, 283 -426, 275 -494, 275 -534, 122 -534, 127 -509, 134 -508,
 135 -518, 143 -525, 155 -523, 158 -517, 166 -520, 176 -517, 181 -511, 190 -510, 196 -502, 196 -494, 202 -491,
 204 -483, 204 -480, 211 -474, 213 -462, 219 -455, 221 -449, 217 -439, 219 -431, 219 -422, 214 -413, 238 -382,
 243 -364, 243 -342, 249 -321, 257 -289, 271 -214, 281 -177)
 ),
 POLYGON(
 (122 -534, 127 -509, 120 -504, 116 -500, 116 -486, 112 -486, 106 -509, 104 -534, 122 -534)
 )
)', 0)

UNION ALL

SELECT geometry::STGeomFromText('GEOMETRYCOLLECTION(
 POLYGON(
 (190 -207, 201 -214, 209 -226, 212 -235, 214 -278, 219 -294, 234 -317, 241 -342, 242 -355, 241 -366, 239 -380,
 234 -388, 224 -400, 212 -413, 194 -435, 187 -446, 180 -459, 172 -467, 162 -471, 153 -470, 144 -464, 136 -453,
 125 -439, 117 -426, 102 -412, 88 -400, 73 -384, 70 -371, 68 -356, 71 -342, 76 -331, 82 -321, 90 -309, 92 -293,
 93 -282, 103 -280, 131 -256, 167 -217, 186 -204, 190 -207)
 ),
 POLYGON(
 (319 -40, 321 -57, 324 -79, 318 -84, 312 -84, 312 -91, 306 -104, 297 -105, 288 -110, 288 -90, 281 -78, 278 -59,
 295 -45, 309 -36, 314 -36, 319 -40)
 ),
 LINESTRING(
 309 -96, 304 -98,300 -98
 ),
 LINESTRING(
 311 -84, 304 -72, 303 -64, 304 -54
 ),
 LINESTRING(
 302 -68, 296 -66, 294 -59
 ),
 POLYGON(
 (319 -40, 328 -37, 344 -37, 349 -40, 348 -52, 344 -58, 332 -59, 321 -58, 319 -40)
 ),
 POLYGON(
 (322 -59, 343 -59, 346 -66, 344 -75, 338 -84, 331 -83, 323 -80, 322 -59)
 ),
 POLYGON(
 (323 -81, 327 -83, 338 -85, 337 -96, 332 -101, 325 -104, 317 -103, 311 -97, 312 -84, 318 -84, 323 -81)
 ),
 POLYGON(
 (306 -120, 307 -129, 311 -134, 312 -140, 309 -152, 308 -168, 296 -161, 286 -161, 284 -156, 288 -130,
 294 -128, 306 -120)
 ),
 POLYGON(
 (154 -472, 156 -476, 158 -485, 156 -491, 153 -498, 159 -487, 176 -474, 183 -464, 185 -453, 179 -460, 171 -467,
 165 -470, 155 -471, 154 -472)
 )
)', 0)

UNION ALL

SELECT geometry::STGeomFromText('GEOMETRYCOLLECTION(
 POLYGON(
 (171 -165, 179 -159, 185 -160, 182 -157, 190 -147, 202 -144, 211 -148, 214 -157, 206 -168, 215 -160, 221 -168,
 221 -175, 206 -184, 221 -178, 229 -186, 228 -192, 221 -197, 228 -197, 231 -205, 225 -212, 218 -211, 222 -216,
 219 -226, 211 -231, 204 -218, 191 -208, 201 -205, 191 -205, 178 -209, 167 -218, 144 -242, 128 -260, 111 -274,
 98 -282, 85 -283, 95 -284, 91 -299, 81 -299, 74 -294, 67 -294, 60 -290, 59 -284, 61 -279, 54 -268, 58 -258,
 66 -253, 74 -253, 77 -257, 77 -252, 85 -245, 103 -248, 99 -245, 100 -242, 103 -240, 112 -240, 104 -238, 106 -227,
 116 -214, 129 -209, 139 -213, 134 -210, 142 -204, 150 -204, 143 -201, 147 -196, 154 -194, 164 -196, 156 -193,
 158 -185, 163 -177, 173 -174, 166 -174, 171 -165)
 ),
 POLYGON(
 (122 -435, 114 -439, 108 -445, 106 -456, 111 -460, 118 -455, 112 -465, 109 -473, 109 -482, 115 -486, 122 -479,
 116 -489, 116 -497, 119 -503, 125 -507, 132 -508, 136 -504, 134 -515, 140 -522, 152 -524, 158 -517, 158 -510,
 160 -517, 170 -519, 178 -514, 181 -507, 184 -510, 193 -509, 196 -501, 195 -493, 200 -493, 204 -486, 200 -475,
 205 -478, 210 -472, 213 -466, 212 -461, 209 -457, 214 -459, 218 -457, 220 -450, 215 -440, 218 -434, 218 -423,
 214 -417, 208 -417, 196 -434, 185 -453, 183 -465, 176 -474, 160 -486, 156 -491, 153 -498, 155 -490, 158 -484,
 155 -476, 153 -472, 146 -466, 139 -457, 122 -435)
 ),
 POLYGON(
 (271 -152, 280 -153, 285 -158, 286 -161, 289 -160, 296 -160, 304 -165, 310 -172, 319 -172, 325 -176, 327 -180,
 326 -187, 320 -192, 319 -198, 315 -202, 307 -203, 307 -188, 300 -182, 290 -178, 282 -176, 278 -185, 266 -185,
 263 -181, 264 -177, 269 -175, 262 -176, 258 -171, 259 -166, 262 -164, 269 -165, 264 -162, 265 -157, 271 -152)
 )
)', 0)

UNION ALL

SELECT geometry::STGeomFromText('GEOMETRYCOLLECTION(
 POLYGON(
 (316 0, 329 0, 324 -39, 318 -40, 314 -36, 316 0)
 ),
 POLYGON(
 (303 0, 316 0, 315 -36, 304 -40, 303 0)
 ),
 POLYGON(
 (307 -104, 311 -98, 321 -105, 332 -105, 340 -108, 346 -117, 345 -124, 347 -129, 344 -131, 343 -126, 338 -125, 330 -122,
 324 -117, 328 -122, 326 -128, 323 -132, 318 -134, 317 -139, 312 -133, 307 -130, 306 -124, 308 -119, 311 -112, 306 -119,
 301 -124, 293 -128, 288 -128, 288 -132, 284 -127, 283 -122, 284 -114, 291 -108, 301 -104, 307 -104)
 )
)', 0)

UNION ALL

SELECT geometry::STGeomFromText('GEOMETRYCOLLECTION(
 POLYGON(
 (151 -306, 146 -311, 135 -316, 125 -318, 116 -317, 110 -312, 106 -306, 119 -303, 136 -300, 151 -306)
 ),
 POLYGON(
 (137 -303, 144 -304, 146 -307, 144 -310, 138 -312, 133 -309, 132 -305, 137 -303)
 ),
 POLYGON(
 (161 -302, 165 -296, 178 -288, 188 -286, 203 -289, 205 -294, 204 -305, 202 -307, 182 -312, 171 -310, 164 -306,
 161 -302)
 ),
 POLYGON(
 (184 -291, 185 -296, 184 -301, 176 -306, 173 -304, 170 -300, 172 -293, 179 -290, 184 -291)
 )
)', 0)

UNION ALL

SELECT geometry::STGeomFromText('GEOMETRYCOLLECTION(
 POLYGON(
 (143 -439, 142 -434, 148 -425, 155 -420, 162 -418, 168 -418, 180 -427, 183 -432, 183 -435, 181 -436, 176 -430,
 168 -427, 159 -424, 149 -426, 143 -433, 143 -439)
 ),
 LINESTRING(
 161 -424, 160 -419
 ),
 LINESTRING(
 173 -422, 176 -430
 )
)', 0)

UNION ALL

SELECT geometry::STGeomFromText('GEOMETRYCOLLECTION(
 LINESTRING(
 151 -326, 147 -331, 147 -335, 157 -333, 160 -336, 164 -338, 168 -335, 171 -334, 180 -335, 179 -330, 174 -328
 ),
 LINESTRING(
 146 -332, 136 -344, 132 -357, 130 -373, 132 -396, 136 -410, 137 -419
 ),
 LINESTRING(
 168 -338, 170 -344, 171 -351, 167 -391
 ),
 LINESTRING(
 181 -333, 187 -342, 188 -351, 192 -375, 191 -401, 190 -417, 190 -440, 186 -443, 182 -445, 179 -443, 175 -438
 ),
 LINESTRING(
 138 -436, 140 -442, 143 -446, 153 -436, 157 -431, 160 -432
 ),
 LINESTRING(
 150 -413, 153 -410, 157 -407, 164 -404, 173 -406, 176 -410
 ),
 LINESTRING(
 139 -446, 148 -457, 152 -460, 157 -462, 162 -463, 168 -462, 175 -457, 180 -447
 ),
 LINESTRING(
 126 -352, 121 -357, 117 -368, 116 -376, 117 -390, 121 -402, 135 -437
 ),
 LINESTRING(
 105 -396, 113 -412, 118 -425
 ),
 LINESTRING(
 216 -388, 214 -403, 208 -416
 ),
 LINESTRING(
 198 -360, 202 -370, 202 -382, 200 -403, 194 -434
 ),
 LINESTRING(
 175 -316, 181 -317, 193 -316, 205 -313
 ),
 LINESTRING(
 177 -318, 189 -323, 199 -323, 214 -316
 ),
 LINESTRING(
 174 -320, 186 -330, 199 -334, 213 -330, 220 -321
 ),
 LINESTRING(
 157 -326, 162 -322, 171 -323
 ),
 LINESTRING(
 155 -320, 161 -317, 167 -318
 ),
 LINESTRING(
 154 -316, 160 -312
 ),
 LINESTRING(
 106 -318, 110 -321, 121 -326, 132 -323, 148 -313
 ),
 LINESTRING(
 99 -324, 108 -334, 119 -335, 137 -325, 150 -312
 ),
 LINESTRING(
 94 -335, 100 -344, 111 -345, 123 -339, 137 -330, 147 -321, 153 -311
 ),
 LINESTRING(
 105 -307, 88 -304
 ),
 LINESTRING(
 106 -309, 94 -313
 ),
 LINESTRING(
 207 -294, 221 -295
 ),
 LINESTRING(
 205 -291, 219 -289
 ),
 LINESTRING(
 206 -290, 205 -283, 202 -281
 ),
 LINESTRING(
 158 -298, 158 -284, 160 -278
 ),
 LINESTRING(
 158 -284, 154 -263
 ),
 LINESTRING(
 154 -258, 152 -244
 ),
 LINESTRING(
 151 -272, 148 -266, 144 -261, 138 -257
 ),
 LINESTRING(
 153 -291, 149 -282, 140 -271, 130 -265
 ),
 LINESTRING(
 158 -264, 161 -250, 165 -241, 170 -235, 175 -233
 ),
 LINESTRING(
 169 -266, 173 -254, 178 -244, 182 -237
 ),
 LINESTRING(
 196 -244, 204 -220
 ),
 LINESTRING(
 167 -292, 198 -242
 ),
 LINESTRING(
 168 -291, 199 -241
 ),
 LINESTRING(
 169 -290, 201 -240
 ),
 LINESTRING(
 170 -289, 202 -240
 ),
 LINESTRING(
 171 -289, 204 -242
 ),
 LINESTRING(
 172 -288, 205 -244
 ),
 LINESTRING(
 173 -288, 210 -250
 ),
 LINESTRING(
 175 -287, 212 -252
 ),
 LINESTRING(
 178 -286, 217 -254
 ),
 LINESTRING(
 152 -306, 119 -288, 101 -293
 ),
 LINESTRING(
 153 -306, 119 -287, 102 -291
 ),
 LINESTRING(
 153 -306, 119 -286, 102 -287
 ),
 LINESTRING(
 153 -306, 120 -284, 103 -286
 ),
 LINESTRING(
 154 -305, 121 -282, 104 -283
 ),
 LINESTRING(
 156 -304, 121 -280, 104 -283
 )
)', 0);

Se deu tudo certo,, você deve conseguir ver uma imagem assim:

Malditos SQL Aliases

Estava em um cliente montando uma estratégia para migração de 2 instâncias de SQL 2000 para uma única instância de SQL 2005… até aí tranquilo,,, certo?

Listamos os linked servers, jobs, usuários e senhas, bases, collation,,, etc,,, tudo quase pronto pra migração….

Ai, lembrei de um detalhe… algumas bases estavam em uma instância default do SQL,,, e vamos migrar todas para um SQL em uma instância,,, ai vem o problema:

  1. Aplicações antigas
  2. Algumas não possuem código fonte
  3. Outras precisam de projeto para alterar o fonte
  4. Muitas estações com o aplicativo
  5. etc..

Legal,,, iai? Só criar o SQL Aliases (Iniciar>Executar>Cliconfg)? boa,,, pena que tem que criar em maquina a maquina,,, Redirecionar DNS? até funcionaria se o outro SQL não tivesse instância. Poderíamos alterar o DNS e “adicionar o servidor” com o sp_addserver (sp_addserver ‘nome_do_host’, local, duplicate_ok) o problema é que a instância tem que escutar a 1433, até ai nenhum grande problema, adiciona como porta secundária.

como fazer o deploy de aliases rápido? Policy… cria uma chave de registro e adiciona o aliases…

  • “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo”
  • Nome:”Nome_do_alias”
  • Tipo: Sequencia
  • Valor: “DBMSSOCN,ServidorX\Instancia,1433”

Outra forma, utilizar um “proxy” de SQL,,, tipo F5, Green SQL,,,

Migração do blog

Estou migrando meu blog para o wordpress por questões de recursos,,, a versão anterior é legal, mas o projeto foi descartado pelo desenvolvedor em 2005.
Como o código é em italiano, isso não ajuda em tentar entender algumas coisas,,,
Já o wordpress tem algumas facilidades bem interessantes,,, integra como o Windows Live Writer, android, iphone,,,, 😀
É possível acessar pelo mobile e ele tem uma interface específica pra ele,,, muito legal…
Vamos testando e se não der certo volto pra versão antiga…

MCM SQL Server 2008 – E lá vamos nós…

Recebi o link para acesso ao sharepoint da Microsoft com informações sobre as pessoas que vão fazer o curso junto comigo e acesso ao material dos dias de treinamento,,, tem muita coisa interessante,,,
Hoje ja é o último dia aqui na empresa já providenciei minha mensagem de férias para o email, vai fica uma coisa +/- assim:
“Olá, não estarei disponível durante os dias 29/04 até 28/05 devido a um treinamento. NÃO estarei lendo emails nesse período e apagarei todos os emails recebidos durante ele, caso haja necessidade de contato falar com XXX ou YYY”
Eu seu que é uma mensagem meio pesada, mas é o únido jeito de ter o foco suficiente para esse curso, afinal, é caro e tenho que ficar concentrado nele…

Movimentar arquivos de Bancos de Dados

Nesse post vou falar como movimentar os arquivos de um banco de dados de uma unidade/diretório para outra unidade/diretório.

Ai você pensa:

“Pra que? Já sei como faz isso. Não tem nenhuma novidade.” ou

“Aaahh,,, isso é facil, uso o bom e velho backup/restore ou o detach/attach…”

Isso é verdade, não tem nenhuma grande novidade em fazer a movimentação mas, ai vem a parte divertida, pra que fazer do método fácil se podemos fazer do método interessante?

1.- Backup/Restore

Se executarmos o bom e velho backup/restore, no momento do restore podemos alterar o caminho onde os arquivos irão ser gravados, isso é simples.

Apenas precisaremos executar o processo de backup que, dependendo do tamanho da base, pode demorar alguns minutos ou até umas horas. Além de ter que ter um espaço para armazenar o backup ou executá-lo através de uma unidade de backup.

2.- Detach/Attach

Usando o Detach ganhamos algum tempo, você vai apenas mover os arquivos de log e dados para outro lugar e anexar a base novamente.

O problema disso é se você usar o Service Broker ou até o Mirror, você terá que refazer o processo.

3.- Alter Database (o “método interessante”)

Esse “método” a seguir cria uma procedure para executar a movimentação do banco para outro local usando o Alter database, mas é possível executá-lo em diversos bancos como vou demonstrar:

Vamos criar 2 bases de dados para testar:

create database banco1

create database banco2

Agora execute o scritp abaixo para criar a procedure que irá executar a movimentação dos arquivos:

IF ( OBJECT_ID(‘dbo.sp_MoveDatabase’) IS NOT NULL )
begin
DROP PROCEDURE dbo.sp_MoveDatabase
end
GO

create procedure sp_MoveDatabase

@NewDataFolder nvarchar(1000),
@NewLogFolder nvarchar(1000),
@DbList nvarchar(4000)

as
Begin
declare @DbTable table (lkey int identity (1,1) primary key, dbname nvarchar(100))
declare @FileTable table (lkey int identity (1,1) primary key, [name]nvarchar(100), physical_name nvarchar(1000), [type] int )
declare @sql nvarchar(4000)
declare @count int, @RowNum int
declare @DbName nvarchar(100)
declare @OldPath nvarchar(1000)
declare @Type int
declare @LogicalName nvarchar(100)
declare @ParmDefinition nvarchar(1000)
declare @FileName nvarchar(100)
declare @NewPath nvarchar(1000)
declare @ShowAdvOpt int
declare @XPCMD int

set nocount on;

if right(@DbList,1) = ‘,’

Begin
print ‘DbList must NOT end with “””‘
return

End
declare @MyString NVARCHAR(100)
declare @Pos INT
declare @NextPos INT
declare @String NVARCHAR(4000)
declare @Delimiter NVARCHAR(1)

set @String = @DbList
set @Delimiter = ‘,’
SET @String = @String + @Delimiter
SET @Pos = charindex(@Delimiter,@String)
WHILE (@pos <> 0)

BEGIN
SET @MyString = substring(@String,1,@Pos – 1)
insert into @DbTable (dbname) values (LTRIM(RTRIM(@MyString)))
SET @String = substring(@String,@pos+1,len(@String))
SET @pos = charindex(@Delimiter,@String)

END
set @ShowAdvOpt = cast(( select [value] from sys.configurations where [name] = ‘show advanced options’) as int)
set @XPCMD = cast(( select [value] from sys.configurations where [name] = ‘xp_cmdshell’) as int)
if right(@NewDataFolder,1)<> ‘\’ or right(@NewLogFolder,1)<>’\’

Begin
print ‘new path”s must end with \’
return
end
EXEC sp_configure ‘show advanced option’, ‘1’
RECONFIGURE

exec sp_configure ‘xp_cmdshell’ , ‘1’
RECONFIGURE

print ‘NewMdfFolder is ‘ + @NewDataFolder
print ‘NewLdfFolder is ‘ + @NewLogFolder

SET @RowNum = 1
SET @count = (select count(*) from @DbTable)
while @RowNum <= @count

Begin
select @DbName = DBName from @DbTable
where lKey = @RowNum
set @sql = ‘select name, physical_name, type from ‘ + @DbName + ‘.sys.database_files’
insert into @FileTable
exec sp_executesql @sql

— Derruba todas as conexoes configurando como single user with immediate
set @sql= ‘ALTER DATABASE [‘ + @DbName + ‘] SET SINGLE_USER WITH ROLLBACK IMMEDIATE’
print ”
print ‘Executando linha -‘ + @sql
exec sp_executesql @sql

— configura db off line
set @sql = ‘ALTER DATABASE [‘ + @DbName + ‘] SET OFFLINE;’
print ”
print ‘Executando linha – ‘ + @sql
exec sp_executesql @sql
select * from @FileTable
while @@rowcount > 0

begin
select top 1 @OldPath = physical_name, @Type = [type], @LogicalName = [name] from @FileTable

–move arquivos files
set @FileName = (SELECT REVERSE(SUBSTRING(REVERSE(@OldPath), 0, CHARINDEX(‘\’, REVERSE(@OldPath), 1))))
if @type = 0

begin
set @NewPath = @NewDataFolder + @FileName
end
else
begin

set @NewPath = @NewLogFolder + @FileName
end
set @Sql = ‘EXEC master..xp_cmdshell ”MOVE “‘ + @OldPath + ‘” “‘ + @NewPath +'””’
print ”
print ‘Executando linha -‘ + @sql
exec sp_executesql @sql

— altera caminho dos arquivos
set @sql = ‘ALTER DATABASE ‘ + @DbName + ‘ MODIFY FILE (NAME = ‘ + @LogicalName + ‘, FILENAME = “‘ + @NewPath + ‘”)’
exec sp_executesql @sql
delete from @FileTable where [name] = @LogicalName
select * from @FileTable
end –while

set @sql = ‘ALTER DATABASE [‘ + @DbName + ‘] SET ONLINE;’
print ”
print ‘Executing line -‘ + @sql
exec sp_executesql @sql
SET @RowNum = @RowNum + 1

— aceita multi user novamente.
set @sql= ‘ALTER DATABASE [‘ + @DbName + ‘] SET MULTI_USER’
print ”
print ‘Executing line -‘ + @sql
exec sp_executesql @sql
end
exec sp_configure ‘xp_cmdshell’ , @XPCMD

reconfigure
EXEC sp_configure ‘show advanced option’, @ShowAdvOpt

RECONFIGURE
End –procedure

** ATENÇÃO **

Os diretórios de destino já devem estar criados, caso você execute a procedure sem criar o destino o script vai alterar o caminho da base e não vai movimentar os arquivos e quando ela foi trazida online ela vai apresentar erro.

** ATENÇÃO 2 **

Esse script é do tipo “Vai filhão”, quando ele for executado todos os usuários conectados serão desconectados sem dó nem piedade, todas as transações que eles estiverem executando serão dropadas. As conexões apenas poderão ser reestabelecidas após o termino da movimentação.

Para executar a procedure execute-a da seguinte forma:

exec sp_MoveDatabase @NewDataFolder = ‘c:\teste\’, @NewLogFolder = ‘d:\teste\’, @sDbList = ‘banco1, banco2’

Se tudo der certo, as bases banco1 e banco2 estarão seus novos destinos.