há 22 horas
Atenção: Este script exclui registros permanentemente. Sempre realize um backup completo da base de dados antes de executar rotinas de exclusão em lote no seu banco de dados de produção.
Como Limpar Contas Fantasmas no SQL Server: Excluir Cadastros sem Personagens com Segurança
Com o passar do tempo, muitos servidores acumulam milhares de contas registradas que nunca sequer criaram um personagem ou entraram no jogo. Essas "contas fantasmas" ocupam espaço no banco de dados, inflacionam tabelas relacionais (MEMB_INFO, MEMB_STAT, VI_CURR_INFO, etc.) e bloqueiam logins que novos jogadores gostariam de utilizar.
Neste tutorial prático, você aprenderá a consultar e remover com total integridade referencial apenas as contas que não possuem nenhum personagem associado há mais de 30 dias.
1. Passo Crítico: Backup Preventivo
Execute uma cópia de segurança antes de realizar qualquer alteração estrutural:
USE [master]; GO BACKUP DATABASE [MuOnline] TO DISK = 'C:\Backups\MuOnline_Backup_Pre_GhostCleanup.bak' WITH FORMAT, INIT, COMPRESSION; GO
2. Consulta Prévia: Quantas Contas Serão Afetadas?
Antes de deletar, é uma boa prática auditar quantas contas atendem ao critério de exclusão (cadastradas há mais de 30 dias e sem nenhum personagem na tabela AccountCharacter):
USE [MuOnline];
GO
SELECT
M.memb___id,
M.memb_name,
M.mail_addr,
M.appl_days
FROM MEMB_INFO M
LEFT JOIN AccountCharacter A ON M.memb___id = A.Id
WHERE (A.GameID1 IS NULL OR A.GameID1 = '')
AND (A.GameID2 IS NULL OR A.GameID2 = '')
AND (A.GameID3 IS NULL OR A.GameID3 = '')
AND (A.GameID4 IS NULL OR A.GameID4 = '')
AND (A.GameID5 IS NULL OR A.GameID5 = '')
AND DATEDIFF(DAY, M.appl_days, GETDATE()) > 30;
GO
3. Script SQL de Exclusão Segura em Cascata
Para não deixar registros órfãos em tabelas auxiliares, a exclusão deve remover primeiro os vínculos nas tabelas complementares e, por fim, da tabela principal de contas (MEMB_INFO):
USE [MuOnline];
GO
-- 1. Cria tabela temporária com as contas fantasmas identificadas
IF OBJECT_ID('tempdb..#ContasFantasmas') IS NOT NULL
DROP TABLE #ContasFantasmas;
CREATE TABLE #ContasFantasmas (
memb___id VARCHAR(10) PRIMARY KEY
);
-- 2. Filtra contas criadas há mais de 30 dias sem nenhum personagem
INSERT INTO #ContasFantasmas (memb___id)
SELECT M.memb___id
FROM MEMB_INFO M
LEFT JOIN AccountCharacter A ON M.memb___id = A.Id
WHERE (A.GameID1 IS NULL OR A.GameID1 = '')
AND (A.GameID2 IS NULL OR A.GameID2 = '')
AND (A.GameID3 IS NULL OR A.GameID3 = '')
AND (A.GameID4 IS NULL OR A.GameID4 = '')
AND (A.GameID5 IS NULL OR A.GameID5 = '')
AND DATEDIFF(DAY, M.appl_days, GETDATE()) > 30;
-- 3. Exclusão em lote com integridade referencial
BEGIN TRANSACTION;
-- Remove dados de status e conexão
DELETE S
FROM MEMB_STAT S
INNER JOIN #ContasFantasmas F ON S.memb___id = F.memb___id;
-- Remove dados da AccountCharacter
DELETE A
FROM AccountCharacter A
INNER JOIN #ContasFantasmas F ON A.Id = F.memb___id;
-- Remove baús associados (se houver)
DELETE W
FROM warehouse W
INNER JOIN #ContasFantasmas F ON W.AccountID = F.memb___id;
-- Remove tabelas de sessão caso existam
IF OBJECT_ID('VI_CURR_INFO', 'U') IS NOT NULL
DELETE V FROM VI_CURR_INFO V INNER JOIN #ContasFantasmas F ON V.memb___id = F.memb___id;
-- Remove a conta da tabela principal MEMB_INFO
DELETE M
FROM MEMB_INFO M
INNER JOIN #ContasFantasmas F ON M.memb___id = F.memb___id;
COMMIT TRANSACTION;
-- 4. Limpa a tabela temporária
DROP TABLE #ContasFantasmas;
GO
4. O que este procedimento garante?
- Proteção a Jogadores Ativos: Apenas contas onde todos os slots de personagens (GameID1 a GameID5) estiverem vazios e com mais de 30 dias de criação são afetadas.
- Liberação de Logins: Logins curtos e procurados que foram criados e esquecidos voltam a ficar disponíveis para novos cadastros.
- Integridade Relacional: Remove dados residuais de baú e status antes de deletar a MEMB_INFO, evitando corrupção ou falhas de chave primária.