Ago 08
Sérgio LourençoMS SQL
Num programa feito em VB6 que em determinada parte do código usava alguns ADODC (Active Data Objects Data Control), surgiu-me o seguinte erro: [DBNETLIB][ConnectionOpen (Invalid Connection()).] Ligação inválida. Esclarecedor…
Este erro dava quando um dos ADODC tentava estabelecer ligação com a base de dados em SQL Server 2000.
Um colega sugeriu se não seria devido ao facto de ter atingido o número máximo de ligações…BINGO!
No SQL Server há uma propriedade que é “Maximum number of concurrent connections” e este valor é o número máximo de conexões à base de dados que podem existir ao mesmo tempo, ainda que sejam todas provenientes do mesmo utilizador e/ou máquina.

No SQLExpress 2008 este valor vem a 0 (zero) por omissão sendo que assim permite um número ilimitado de conexões.
O que eu pretendia era alterar este valor no SQL Server 2000 por query sem ter que ir às configurações.
Eis como fazê-lo:
sp_configure 'show advanced options', 1
go
reconfigure
go
sp_configure 'user connections', 0--este é o valor máximo pretendido, coloquei zero porque quero que sejam ilimitadas
go
reconfigure
go
Fácil, não é?
Fev 03
Sérgio LourençoMS SQL
Por vezes quando estamos a desenvolver uma alteração numa aplicação já existente, há a necessidade de acrescentar, alterar ou até mesmo apagar colunas de uma tabela. Geralmente isso faz-se no arranque da aplicação numa qualquer rotina de actualização. A questão é, como controlamos se essa alteração já foi feita ou não na base de dados?
Há várias formas é certo mas pessoalmente discordo, sou contra, e abomino coisas como:
- Guardar numa tabela da base de dados uma flag boolean que indique se essa actualização já foi feita ou não (e quem controla se a flag já foi criada ou não?);
- Colocar um qualquer controlo para o caso de dar erro ao tentar fazer a actualização, o programa não crachar (e se o erro não for por já ter sido feita a alteração mas sim por um outro motivo qualquer?);
- Fazer update a um campo numa tabela que supostamente irá guardar a “versão da actualização”;
Pense comigo:
Temos tabelas e campos que são objectos numa base de dados. Estes objectos estão referenciados algures, certo? Estão nas tabelas “sysobjects” e “syscolumns”, não é?
Então porque não fazemos assim:
SELECT * FROM syscolumns
LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id
WHERE syscolumns.name = 'campo' AND sysobjects.name = 'tabela'
Se devolver algum registo é porque o campo existe e assim ficamos a saber que se pretendemos apagar este campo o drop não irá dar erro, se não devolver é porque não existe e é seguro criá-lo!
Ou por exemplo, se quisermos só alterar um campo que era smalldatetime e agora queremos que seja datetime:
SELECT * FROM syscolumns
LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id
WHERE syscolumns.name = 'campo' AND sysobjects.name = 'tabela' AND syscolumns.xtype = 61
Se devolver algum registo é porque o campo já está como datetime e não é preciso fazer mais nada, se não devolver nenhum registo é porque o campo ainda não é datetime e então podemos fazer o nosso alter column!
Ok, eu sei que isto obriga a que seja feita uma instrução para cada alteração enquanto que os outros métodos controlam-nas em “packs” mas um select não é assim tão lento quanto isso e além do mais podemos reduzir tudo (select + add / alter / drop) a uma só instrução:
IF NOT EXISTS
(SELECT autoval FROM syscolumns
LEFT JOIN sysobjects ON syscolumns.id = sysobjects.id
WHERE syscolumns.name = 'campo' AND sysobjects.name = 'tabela')
ALTER TABLE tabela ADD campo tinyint NOT NULL DEFAULT 1
Se conhecer algum método mais simples e mais eficaz do que este, por favor diga-me.
Até lá irei continuar a usá-lo.
Jan 10
Sérgio LourençoMS SQL
Por vezes criámos tabelas, na maioria secundárias, às quais atribuímos a propriedade de “identity” a um campo que irá funcionar como chave. Assim, não temos que nos preocupar com a numeração e consistência dessa mesma chave pois sempre que é acrescentado um novo registo, o engine do MS SQL trata de incrementar o contador e atribuir um novo valor a esse campo. Mas o que acontece quando queremos ser nós a atribuir esse valor? É simples, não nos é permitido.
Exemplo:
Esta é a nossa tabela…
CREATE TABLE [teste] (
[id] [int] identity (1, 1) NOT NULL,
[nome] [nvarchar] (255) NOT NULL,
constraint [pk_teste] PRIMARY KEY clustered
([id]) ON [PRIMARY]
) ON [PRIMARY]
…e este é o nosso insert, o qual não irá funcionar pois estámos a tentar atribuir um valor (3) a um campo que é identity (id).
INSERT INTO teste (id, nome) VALUES (3,’um texto qualquer’)
Para que o nosso insert funcione temos que em primeiro lugar activar o insert em identities…
SET identity_insert [teste] ON
…só depois fazemos o nosso insert…
INSERT INTO teste (id, nome) VALUES (1,’um texto qualquer’)
…e finalmente voltamos a desactivar o insert em identities.
SET identity_insert [teste] off
Resumindo:
SET identity_insert [teste] ON
INSERT INTO teste (id, nome) VALUES (1,’um texto qualquer’)
SET identity_insert [teste] off
Ter em atenção que o facto de termos colocado um valor manualmente numa coluna identity, não influencia o incremento. Isto é, no próximo insert, o valor atribuído à coluna “id” irá ser sempre o valor máximo + 1.
Alguma dúvida? Basta comentar.
Jan 03
Sérgio LourençoMS SQL
Há uns dias ligou-me uma colega de trabalho de uma empresa onde estive há uns anos, perguntando se a podia ajudar num problema relacionado com o MS SQL Server e o software Primavera.
Pelo que consegui perceber dos erros que o Primavera reportava, a base de dados pareceu-me estar com sérios problemas e recomendei um rebuild.
O problema é que não tinha como o fazer pois apesar de ter o MS SQL Server 2000 instalado, não tinha qualquer ferramenta de manutenção.
Aconselhei a instalar o Microsoft SQL Server Management Studio Express pois é gratuito e indiquei os comandos a executar.
As bases de dados, por mais robustas que sejam, precisam sempre de cuidados e manutenção, caso contrário podem começar a acontecer coisas estranhas e podemos vir a perder informação importante.
O que precisamos fazer para reparar uma base de dados MS SQL Server?
- Precisamos de uma ferramenta que nos permita executar querys na base de dados. Caso esta não esteja instalada, podemos instalar o Microsoft SQL Server Management Studio Express por exemplo. É gratuito e compatível com bases de dados SQL Server 2000, 2005 e 2008.
Após a instalação, executamos a aplicação e irá aparecer a seguinte janela:

Colocamos aqui o nome do servidor, tipo de autenticação, user name e password (no caso de seleccionarmos “SQL Server Autentication”).
Ligados ao servidor, clicamos em “New Query”:

O que irá abrir uma janela em branco para executarmos as nossas querys.
- Para podermos fazer um rebuild da base de dados, é preciso que em primeiro lugar ela esteja em modo single user pelo que para tal é necessário que ninguém esteja a aceder à mesma e após nos certificarmos disso, correr o seguinte comando:
ALTER DATABASE nome-da-base-de-dados SET single_user
- Se este comando for executado com sucesso, podemos então passar à recuperação e para isso usamos o DBCC da seguinte forma:
dbcc checkdb ('nome-da-base-de-dados', repair_rebuild)
Geralmente é o suficiente mas por vezes a base de dados está tão danificada que não é possível reparar sem que para isso tenhamos de perder alguma informação. Se estivermos dispostos a tal, então o comando deverá ser o seguinte:
dbcc checkdb ('nome-da-base-de-dados', repair_allow_data_loss)
- Finamente devemos voltar a colocar a base de dados em modo multi user executando o seguinte:
ALTER DATABASE nome-da-base-de-dados SET multi_user
Resumindo:
ALTER DATABASE nome-da-base-de-dados SET single_user
dbcc checkdb ('nome-da-base-de-dados', repair_rebuild)
ALTER DATABASE nome-da-base-de-dados SET multi_user
Se tudo correr bem, a nossa base de dados estará de novo operacional.
Boa sorte!