Artigos relacionados:
Exemplo de Deadlock no SQL Server
Monitorando Deadlocks do SQL Server com SMO
Arquivo da tag: Banco de dados
ADO.NET: Introdução
Com o advento Framework.Net, se possibilitou novos recursos de acessos a dados, de forma a facilitar do desenvolvimento até migração entre plataformas de SGDB.
O ADO.Net, principal recurso de acesso a banco de dados na plataforma .Net, se popularizou por sua arquitetura orientada a objeto e o suporte as principais plataforma de SGDB do mercado, como Oracle e SQL Server, além de suporte a OleDb e ODBC, que possibilitam a integração com Excel, DB2, Interbase, PostGree, Firebird e MySQL, sem a necessidade de utilizar qualquer componente de terceiros.
Também existem outros recursos desenvolvidos que estendem ou reimplementam a arquitetura de acessos a SGDB de forma especializada, como no caso da Oracle, do Firebird e do MySQL, que desenvolvem suas próprias extensões do ADO.Net, afim de atender necessidade específicas de suas plataformas. Em relação ao SQL Server, a Framework.Net possui outros recursos exclusivos para prover integração com CLR.
Existem duas formas básicas de trabalhar com o ADO.Net, por meio de classes conectadas e desconectadas.
As classes conectadas permitem o acesso ao SGBD, por meio do .Net Data Provider, que constitui basicamente das seguintes entidades:
Connection: Responsável pela conexão ao SGDB, esta classe varia SGDB para SGDB (ex. SQLConnection, OracleConnection, OleDbConnection e OdbcConnection), possuindo métodos e propriedades que facilitam criar a conexão com cada um dos SGDB.
Por questões de arquitetura, para exigir que a conexão se feche depois de realizada a operação é recomendado o uso do bloco “Using”, exemplo:
// Criando o objeto de conexão ao banco de dados
using (SqlConnection conn = new SqlConnection("string de conexão"))
{
// Chamando o método responsável pela abertura da conexão.
conn.Open();
}
Recomendável não utilizar nenhum retorno de métodos dentro de blocos “Using”:
// Criando o objeto de conexão ao banco de dados
using (SqlConnection conn = new SqlConnection("string de conexão"))
{
// Chamando o método responsável pela abertura da conexão.
conn.Open();
// Nunca faça isso:
return true;
}
String de conexão: É responsável por identificar o endereço do SGDB, formas de autenticação e configurações de acesso.
Em aplicações Web, normalmente esta string é armazenada no arquivo web.config ou aplicações Windows e Windows Mobile no arquivo app.config, por questões de reaproveitamento e para facilitar alterações. Exemplo:
<!--web.config-->
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="nome" connectionString="Data Source=in;Initial Catalog=db;User=us;Password=sn;"/>
</connectionStrings>
</configuration>
Método responsável por retornar a string de conexão do web.config, as vezes se faz necessário adicionar a referência a System.Configuration ao projeto.
ConfigurationManager.ConnectionStrings["nome"].ToString();
// Criando o objeto de conexão ao banco de dados
string connectionString = ConfigurationManager.ConnectionStrings["nome"].ToString()
using (SqlConnection conn = new SqlConnection(connectionString))
{
// Chamando o método responsável pela abertura da conexão.
conn.Open();
}
Também existem formas de gerar a connection string em tempo de execução.
(at. http://msdn.microsoft.com/en-us/library/ms254947(VS.80).aspx )
Alguns exemplos de string de conexão para SQL Server e outros bancos de dados:
https://sqlfromhell.wordpress.com/2009/08/04/connection-strings/
http://msdn.microsoft.com/en-us/library/ms254500.aspx
Command: Depois de estabelecida a conexão com o SGDB, esta classe é o responsável por executar comandos e consultas no banco de dados. Seus objetos podem ser instanciado da forma tradicional por meio de um construtor ou chamando o método CreateCommand de objetos de conexão.Exemplo:
using (SqlConnection conn= new SqlConnection(""))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
}
}
Ou
using (SqlConnection conn= new SqlConnection(""))
{
using (SqlCommand cmd = conn.CreateCommand())
{
}
}
Estes comandos podem ser comandos em SQL, nomes de StoredProcedures ou nomes de tabelas, para define qual o tipo comando é possível definir por meio do enumerador CommandType. Ex.:
// Para comandos SQL
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM tabela";
// Para stored procedure
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "SpTabelaSel";
// Para tabela
cmd.CommandType = CommandType.TableDirect;
cmd.CommandText = "tabela";
Parâmetros: É a forma ideal de passar valores para comandos SQL e Stored Procedures. São eficazes para combater possíveis ataques de “SQL-Injection”. Exemplos:
//Forma de errada de passar valores para os comandos
cmd.CommandText = "INSERT INTO tabela (valor1) VALUES " + valor + ")";
//Utilizando parâmetros para inserir dados
cmd.CommandText = "INSERT INTO tabela (valor1) VALUES (@nome_parametro)";
cmd.Parameters.Add(new SqlParameter("@nome_parametro", valor);
//Utilizando parâmetros para excluir
cmd.CommandText = "DELETE FROM tabela WHERE valor1 = @nome_parametro";
cmd.Parameters.Add(new SqlParameter("@nome_parametro", valor);
//Utilizando parâmetros para alterar
cmd.CommandText = "UPDATE tabela SET valor1 = @nome_parametro1 WHERE valor2 = @nome_parametro2";
cmd.Parameters.Add(new SqlParameter("@nome_parametro1", valor1);
cmd.Parameters.Add(new SqlParameter("@nome_parametro2", valor2);
//Utilizando parâmetros para consultas
cmd.CommandText = "SELECT * FROM tabela WHERE valor1 = @nome_parametro";
cmd.Parameters.Add(new SqlParameter("@nome_parametro", valor);
//Utilizando parâmetros para StoreProcedures
cmd.CommandText = " SpTabelaSel";
cmd.Parameters.Add(new SqlParameter("@nome_parametro", valor);
A forma ideal de criar parâmetros é definir o tipo, tamanho e valor de forma separada.
//Forma ideal de criar um parâmetro
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@nome_parametro";
parameter.SqlDbType = SqlDbType.VarChar;
parameter.Size = 90;
parameter.Value = valor;
ou
SqlParameter parameter = new SqlParameter("@nome_parametro", SqlDbType.VarChar, 90);
parameter.Value = valor;
Métodos de execução: Para comandos que não são esperados retornos é recomendado o uso do método ExecuteNonQuery, cujo o retorno é um inteiro especificando o número de linhas afetadas. Exemplo:
cmd.CommandText = "INSERT INTO tabela (coluna) VALUES ('valor')";
cmd.ExecuteNonQuery();
Para comandos que se espera uma única célula, exemplo a execução das funções SQL, COUNT, SUM, MAX, MIN ou qualquer outra consulta que ternar somente um valor, é recomendado o uso do método ExecuteScalar. Exemplo:
cmd.CommandText = "SELECT COUNT(*) FROM tabela";
int count = (int)cmd.ExecuteScalar();
Alterando as portas de conexão do SQL Server
Atenção
Migramos este artigo para o novo site:
http://www.sqlfromhell.com/alterando-as-portas-de-conexao-do-sql-server/
Trabalhando com datas – Cálculos com meses
É muito comum aparecer no dia a dia, muitas necessidades estranhas para trabalhar com SQL, principalmente quando se trabalha com os campos de data. Mas a sensação de superar obstáculos somente pode ter sentido com estes pequenos e mirabolantes desafios aparecem, e a vontade de dar um jeitinho no SQL começa aparecer.
Para enterrar o tópico “Trabalhando com datas”, segue dois desafios legais que já encontrei.
Retornando o primeiro dia da mês:
DECLARE @DATA DATETIME
SET @DATA = GETDATE()
SELECT CONVERT(VARCHAR, @DATA - DAY(@DATA) + 1, 103) as PrimeiroDiaDoMes
Ou
SELECT CONVERT(VARCHAR, @DATA - DATEPART(DAY, @DATA) + 1, 103) as PrimeiroDiaDoMes
Retornando o número da semana do mês:
DECLARE @DATA DATETIME
SET @DATA = GETDATE()
SELECT DATEPART(WK, @DATA) - DATEPART(WK, @DATA - DAY(@DATA) + 1) + 1 as SemanaDoMes
Ou
SELECT DATEPART(WEEK, @DATA) - DATEPART(WEEK, @DATA - DATEPART(DAY, @DATA) + 1) + 1 as SemanaDoMes
Valeu Maikel pelo desafio e por liberar que fosse postado!
O Profissional de Banco de Dados
A área de banco de dados é um ramo da tecnologia de informação muito pouco explorado em comparação da necessidade das empresas de soluções.
Considero o profissional de banco de dados um especialista em infra-estrutura, em desenvolvimento e/ou em negócios, que possui capacidade de prover serviços de qualidade na área de banco de dados. Desta forma o fato dele ter conhecimento de banco de dados somente é um diferencial competitivo entre os vários outros profissionais da área de tecnologia da informação.
Existem tentativas de categorizar os profissionais de banco de dados, basicamente divididos nas categorias de Administrador de Banco de dados (Database Administrador), Desenvolvedor de Banco de dados (Database Developer) e Profissional em Business Intelligence, mas todas são somente formas das empresas conseguirem entender qual “DBA” precisam contratar.
O profissional em banco de dados não pode ser somente DBA ou desenvolvedor ou somente o cara do BI. Na verdade ele precisa ser um profissional “Google” (“Wikipédia” ou “Yahoo” ou “Bing” se preferir), pois as organizações estão sedentas de profissionais capacitados e elas não importam muito com qual o nome do cargo dele, mas sim “como ele pode me auxiliar na minha estratégia?”. Este auxílio pode ser uma solução maravilhosa com a qual a empresa pode ganhar (ou não perder) dinheiro ou o simples fato de ter este profissional tudo na empresa estará funcionando perfeitamente.
E respondendo a pergunta “Qual é a minha visão do mercado para o DBA hoje em dia?” que recebi do Anderson, existem muitas oportunidades de trabalho na área de TI, principalmente para profissionais de banco de dados, só que para preencher estas vagas é necessário provar sua aptidão para ocupá-la, então se qualifique e aproveite sempre a oportunidade de aprender mais! Pessoalmente gosto muito deste ramo e vejo nele muitas oportunidades de crescimento.
Como eu disse “conhecer de banco de dados somente é um diferencial competitivo”, logo é possível aumentar o impacto deste diferencial, com trabalho, estudos, treinamentos e dedicação, mas não deve se esquecer de temperar com um pouco de “Google” e aprender também sobre o que esta além do banco de dados.
Obrigado pelas críticas e sugestões que tenho recebido!
Artigos relevantes:
http://imasters.uol.com.br/artigo/10797/bancodedados/quer_um_emprego_como_dba/
http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!299.entry
http://gustavomaiaaguiar.spaces.live.com/blog/cns!F4F5C630410B9865!136.entry
http://imasters.uol.com.br/artigo/13518/oracle/que_tipo_de_dba_e_voce/
(Profissional Google para eles quer dizer outra coisa…rsss)
Trabalhando com datas – Lista de meses e dias da semana
Pessoal, no último post relacionei funções para trabalhar com campos do tipo data, acabei recebendo um bom feedback e algumas perguntas sobre como relacionar todos os meses ou dias da semana por meio de query. Para responder estas perguntas, relacionei formas de gerar listas com os meses e dias da semana por meio de CTE.
Nestas duas primeiras queries, faço uso de um CTE recursivo básico, com as funções DATENAME e DATEADD e a instrução SET LANGUAGE para definir o idioma ‘Brasileiro’. Estas queries são bem mais simples e tornam mais fácil trazer novos campos.
Tips:
1: Os campos de data quando somados a tipos inteiros, adicionam o valor dos inteiros em dias.
2: A função DATEADD simplifica a adição de outros quantitativos como meses, horas e anos.
3: O inteiro ‘0’ (zero) quando convertido para data se torna ‘1900-01-01 00:00:00.000’, uma segunda-feira.
4: O inteiro ‘-1’ quando convertido para data se torna ‘1899-12-31 00:00:00.000’, um domingo.
Gerando uma lista de meses:
SET LANGUAGE 'Brazilian'
;WITH Meses AS
(
SELECT 1 AS IdMes, DATENAME(MONTH, 0) AS NomeMes
UNION ALL
SELECT IdMes + 1, DATENAME(MONTH, DATEADD(MONTH, IdMes, 0))
FROM Meses
WHERE IdMes < 12
)
SELECT * FROM Meses
Gerando uma lista de dias da semana começando pelo domingo:
SET LANGUAGE 'Brazilian'
;WITH DiaSemana AS
(
SELECT 1 AS idDSe, DATENAME(WEEKDAY, -1) AS nomeDSe
UNION ALL
SELECT idDSe + 1, DATENAME(WEEKDAY, idDSe -1)
FROM DiaSemana
WHERE idDSe < 7
)
SELECT idDSe, nomeDSe FROM DiaSemana
Ou pela Segunda-Feira:
SET LANGUAGE 'Brazilian'
;WITH DiaSemana AS
(
SELECT 1 AS idDSe, DATENAME(WEEKDAY, 0) AS nomeDSe
UNION ALL
SELECT idDSe + 1, DATENAME(WEEKDAY, idDSe)
FROM DiaSemana
WHERE idDSe < 7
)
SELECT idDSe, nomeDSe FROM DiaSemana
Nas duas próximas queries, avanço um pouco a complexidade das CTEs, utilizando a view syslanguage e uma CTE de Split que modifiquei do site do Zavaschi. Elas realmente se diferenciam pelo campo utilizado da syslanguages facilitando alterações neste sentido.
Gerando uma lista dos meses:
DECLARE @Texto VARCHAR(8000),
@Delimitador CHAR
SET @Texto = (SELECT months FROM sys.syslanguages WHERE alias = 'Brazilian')
SET @Delimitador = ','
;WITH _SPLIT(ID, _INDEX, _LENGTH) AS
(
SELECT
1,
1,
CHARINDEX(@Delimitador, @Texto + @Delimitador)
UNION ALL
SELECT
ID + 1,
_LENGTH + 1,
CHARINDEX(@Delimitador, @Texto + @Delimitador, _LENGTH + 1)
FROM _SPLIT
WHERE CHARINDEX(@Delimitador, @Texto + @Delimitador, _LENGTH + 1) <> 0
)
, Meses (idMes, nomeMes) AS
(
SELECT
ID,
SUBSTRING(@Texto, _INDEX, _LENGTH - _INDEX)
FROM _SPLIT
)
SELECT idMes, nomeMes FROM Meses
Gerando uma lista de dias da semana:
DECLARE @Texto VARCHAR(8000),
@Delimitador CHAR
SET @Texto = (SELECT days FROM sys.syslanguages WHERE alias = 'Brazilian')
SET @Delimitador = ','
;WITH _SPLIT(ID, _INDEX, _LENGTH) AS
(
SELECT
1,
1,
CHARINDEX(@Delimitador, @Texto + @Delimitador)
UNION ALL
SELECT
ID + 1,
_LENGTH + 1,
CHARINDEX(@Delimitador, @Texto + @Delimitador, _LENGTH + 1)
FROM _SPLIT
WHERE CHARINDEX(@Delimitador, @Texto + @Delimitador, _LENGTH + 1) <> 0
)
, DiaSemana (idDSe, nomeDSe) AS
(
SELECT
ID,
SUBSTRING(@Texto, _INDEX, _LENGTH - _INDEX)
FROM _SPLIT
)
SELECT idDSe, nomeDSe FROM DiaSemana
Eu espero que elas respondam as necessidades que venham a aparecer!
Não se esqueçam de comentar!
Arquivo de log gigante?
Para quem sofre com este problema, a prática mais comum no SQL Server 2005 é utilizar o Backup Log Truncate em seguida Shrink (at. http://blog.sqlauthority.com/2006/12/30/sql-server-shrinking-truncate-log-file-log-full/ ), mas será que é realmente a melhor escolha a fazer? Será que não há um motivo para não haver isso no SQL Sever 2008? Será que não vale a pena mudar o Recovery Model do banco de dados para Simple?
Bem quer saber o jeito correto de para resolver o problema com o arquivo de log? Então dê uma boa lida nestes dois tópicos sobre o assunto, escritos pelo MVP Gustavo Maia Aguiar:
Piores Práticas – Utilizar o comando BACKUP LOG com a opção WITH TRUNCATE_ONLY – Parte I
Piores Práticas – Utilizar o comando BACKUP LOG com a opção WITH TRUNCATE_ONLY – Parte II
Já tive uns problemas legais com arquivo de log gigante, que nem com o método Truncate/Shrink deu jeito, mas sempre vale a pena verificar se o plano de manutenção do SQL Server não esta mal estruturado (já resolvi este problema assim), ou se tem replicações “mortas” no banco de dados (um dia, talvez eu entenda o que aconteceu e como resolvi o problema com replicações “mortas” e o arquivo de log, para poder escrever sobre).
Connection Strings
“Problemas com Connection Strings, nós temos a solução!”, isso parece bobagem, mas parece ser a idéia do site ConnectionStrings.com, achei que era brincadeira, mas é sério, eles ressucitaram até o Paradox e o Informix!!! Abaixo a lista de links para as connection strings: Continuar lendo
Queries para dicionário de dados – Step 2
Continuando o post de Dicionário de dados,
Desde versões antigas do SQL Server são encontradas system view que permitem de várias formas mapear as entidades do banco de dados, desde relacionar as colunas de uma determinada tabela até mapear relacionamentos, índices e arquivos de armazenamento do banco de dados.
Primeiramente, como encontrar os relacionamentos no SQL Server 2000 e superiores:
SELECT OBJECT_NAME(foreigns.rkeyid) Parent_Table, OBJECT_NAME(foreigns.fkeyid) Child_Table, OBJECT_NAME(foreigns.constid) Key_Name, parent_columns.name Parent_Col, child_columns.name Child_Col FROM sys.sysforeignkeys foreigns INNER JOIN sys.syscolumns parent_columns ON foreigns.fkeyid = parent_columns.id AND foreigns.fkey = parent_columns.colid INNER JOIN sys.syscolumns child_columns ON foreigns.rkeyid = child_columns.id AND foreigns.rkey = child_columns.colid ORDER BY Parent_Table, Child_Table
A mesma funcionalidade no SQL Server 2005/2008:
SELECT OBJECT_NAME(foreigns_columns.[referenced_object_id]) Parent_Table, OBJECT_NAME(foreigns_columns.[parent_object_id]) Child_Table, OBJECT_NAME(foreigns_columns.[constraint_object_id]) Key_Name, parent_columns.name Parent_Col, child_columns.name Child_KeyCol FROM sys.foreign_key_columns foreigns_columns INNER JOIN sys.columns parent_columns ON parent_columns.[object_id] = foreigns_columns.[parent_object_id] AND parent_columns.[column_id] = foreigns_columns.[parent_column_id] INNER JOIN sys.columns child_columns ON child_columns.[object_id] = foreigns_columns.[referenced_object_id] AND child_columns.[column_id] = foreigns_columns.[referenced_column_id] ORDER BY Parent_Table, Child_Table
A mesma funcionalidade sem o uso da função “OBJECT_NAME”:
SELECT parent.name Parent_Table, child.name Child_Table, foreigns.name FKey_Name, parent_columns.name Parent_Col, child_columns.name Child_Col FROM sys.tables parent INNER JOIN sys.foreign_keys foreigns ON parent.[object_id] = foreigns.[referenced_object_id] INNER JOIN sys.tables child ON child.[object_id] = foreigns.[parent_object_id] INNER JOIN sys.foreign_key_columns foreigns_columns ON foreigns_columns.[constraint_object_id] = foreigns.[object_id] INNER JOIN sys.columns parent_columns ON parent_columns.[object_id] = foreigns_columns.[parent_object_id] AND parent_columns.[column_id] = foreigns_columns.[parent_column_id] INNER JOIN sys.columns child_columns ON child_columns.[object_id] = foreigns_columns.[referenced_object_id] AND child_columns.[column_id] = foreigns_columns.[referenced_column_id] ORDER BY Parent_Table, Child_Table
Agora, para qualquer banco de dados ANSI (MySQL, SQL Server, SQL Lite, PostgreSQL, Oracle), utilizando as system views do INFORMATION_SCHEMA:
SELECT KU.TABLE_NAME Parent_Table, KU2.TABLE_NAME Child_Table, FK.CONSTRAINT_NAME FKey_Name, KU.COLUMN_NAME Parent_Col, KU2.COLUMN_NAME Child_Col FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS FK INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KU ON KU.CONSTRAINT_NAME = FK.CONSTRAINT_NAME INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KU2 ON KU2.CONSTRAINT_NAME = FK.UNIQUE_CONSTRAINT_NAME AND KU.ORDINAL_POSITION = KU2.ORDINAL_POSITION
Queries para dicionário de dados – Step 1
Olá pessoal,
Uma coisa complicada quando se modela ou dá suporte a um bancos de dados, é entender a sua estrutura, para isso pensa-se em documentá-los com o Diagrama de Modelo de Entidades e Relacionamentos (DER ou MER) e/ou com o Dicionário de Dados (DD).
Na categoria Visio do Blog (at. https://sqlfromhell.wordpress.com/category/visio/ ) existe uma série de post descrevendo como fazer o Diagrama de Modelo de Entidades e Relacionamentos (DER ou MER), e no próprio Visio também pode ser feito o Dicionário de Dados (DD).
Como nem todos utilizam ou têm acesso ao Visio, neste post vou relacionar as queries utilizadas para consultar a relação de Tabelas, Colunas e Tipos de dados existentes no SQL Server 2000 ao 2008, que são úteis para realizar outras atividades, como “geradores de código” e “relatórios dinâmicos”.
Primeiramente, para relacionar as tabelas do SQL Server podemos fazer uso de system views para SQL Server 2005 e superiores:
SELECT * FROM sys.tables
ou para SQL Server 2000 e superiores:
SELECT * FROM sysobjects WHERE xtype LIKE 'U'
Para relacionar as tabelas e suas respectivas colunas para SQL Server 2005 e superiores:
SELECT T.name as Tabela, C.name as Coluna FROM sys.tables T INNER JOIN sys.columns C ON C.object_id = T.object_id
ou para SQL Server 2000 e superiores:
SELECT T.name as Tabela, C.name as Coluna FROM sysobjects T INNER JOIN syscolumns C ON T.id = C.id AND T.xtype LIKE 'U' -- Verifica se o tipo de objeto é uma tabela
Agora uma query from hell para relacionar as colunas ao seus respectivos tipos para SQL Server 2005 e superiores:
SELECT T.name as Tabela, C.name as Coluna, TY.name as Tipo, C.max_length, -- Tamanho em bytes, para nvarchar normalmente se divide este valor por 2 C.precision, -- Para tipos numeric e decimal (tamanho) C.scale -- Para tipos numeric e decimal (números após a virgula) FROM sys.columns C INNER JOIN sys.tables T ON T.object_id = C.object_id INNER JOIN sys.types TY ON TY.user_type_id = C.user_type_id ORDER BY T.name, C.name
ou para SQL Server 2000 e superiores:
SELECT T.name as Tabela, C.name as Coluna, TY.name as Tipo, C.length, -- Tamanho em bytes, para nvarchar normalmente se divide este valor por 2 ou utiliza a 'prec' C.prec, -- Para tipos numeric e decimal (tamanho) C.scale -- Para tipos numeric e decimal (números após a virgula) FROM syscolumns C INNER JOIN sysobjects T ON T.id = C.id AND T.xtype LIKE 'U' -- Verifica se o tipo de objeto é uma tabela INNER JOIN systypes TY ON C.usertype = TY.usertype AND C.xtype = TY.xtype ORDER BY T.name, C.name
Agora, para qualquer banco de dados ANSI (MySQL, SQL Server, SQL Lite, PostgreSQL, Oracle), utilizando as system views do INFORMATION_SCHEMA, relacionando as colunas e seus respectivos tipos e tabelas:
SELECT TABLE_NAME as Tabela, COLUMN_NAME as Coluna, DATA_TYPE as Tipo, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE FROM INFORMATION_SCHEMA.COLUMNS ORDER BY Tabela, Coluna
ou somente as tabelas:
SELECT TABLE_NAME as Tabela FROM INFORMATION_SCHEMA.TABLES ORDER BY Tabela
Pessoal até o próximo post!