ATUALIZADOR PARA FIREBIRD

MFLAVIO 16/01/2013 16:52:22
#417515
Ola pessoal estou precisando de uma Ajuda,
e o seguinte eu tenho um sistema com base firebird que esta instalado em alguns clientes
e acontece que existe caso que eu preciso atualizar a Base de dados, então eu criei um Programinha que le um arquivo TXT que contem comandos em SQL
e após ler ele executa esses comandos, eu consigo criar tabelas, alterar tabelas,mudar campos e assim por diante, e funciona legal

o problema veio agora pois preciso criar um campo auto numeração em uma tabela e ai veio o problema para criar a Trigger, eu não consigo cria-la via comando, pelo IBExpert eu consigo criar numa boa mais ai eu teria que atualizar cliente por cliente e isso fica inviável.

o comando que estou tentando enviar para o programa executar e esse
  CREATE TRIGGER NOTA_CCE_BI FOR NOTA_CCE 
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID(GEN_NOTA_CCE_ID,1);
END

mais sempre da erro na quebra de linha já tentei
colocar tudo em uma unica linha mais o erro acontece mesmo assim

alguem sabe o comando para criar uma TRIGGER direto no Firebird sem precisar do IBexpert?
LLAIA 16/01/2013 17:41:37
#417520
Como vc está passando os comandos para o banco criar tabelas e alterá-las?

Que erro está retornando ao tentar criar o Trigger?
RICART 16/01/2013 23:04:17
#417576
Você pode fazer isso utilizando o isql.exe. Você inclui esse arquivo no seu projeto. Ele está na biblioteca do firebird.

Faça o seguinte teste.
Crie um novo banco de dados pelo ibexpert na pasta c:    este chamado testeisql.gdb (nao rie nenhuma tabela ou objetos, apenas crie o banco de dados)

Depois crie um arquivo de lote chamado teste.bat com o seguinte conteúdo:

c:    este\isql.exe -i c:    este    esteisql.sql


Em seguida copie o arquivo isql.exe na pasta bin para a pasta c:    este


Crie um arquivo chamado testeisql.sql com o conteúdo abaixo e salve na pasta c:    este


[txt-color=#0000f0]SET SQL DIALECT 3;

SET NAMES NONE;

CONNECT [ô]c:    este    esteisql.gdb[ô] USER [ô]SYSDBA[ô] PASSWORD [ô]masterkey[ô];

CREATE GENERATOR GEN_TBL_TESTE_ID;
SET GENERATOR GEN_TBL_TESTE_ID TO 0;




CREATE TABLE TBL_TESTE (
ID BIGINT NOT NULL,
DESCRICAO VARCHAR(10) CHARACTER SET NONE
);



SET TERM ^ ;

/* Trigger: TBL_TESTE_BI */
CREATE TRIGGER TBL_TESTE_BI FOR TBL_TESTE
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID(GEN_TBL_TESTE_ID,1);
END
^

SET TERM ; ^[/txt-color]


Agora é só executar o arquivo teste.bat que será criada uma tabela chamada tbl_teste, uma sequence e um trigger. Confira os objetos pelo ibexpert ou outro aplicativo.
Vc pode utilizar esse método até mesmo para criar bancos de dados e inserir vários registros nas tabelas com um script. Ou seja, vc pode executar qualquer script compatível com firebird.





MFLAVIO 28/01/2013 12:13:06
#418187
Amigo Ricart infelizmente isso não vai dar certo para mim, pois em cada cliente a forma de conexão com o DB e diferente, ja que tenho clientes com servidor e clietnes sem servidor e outros que usam maquinas remoto para servidor essas informações são salvas em um INI file

eu estou usando a seguinte Rotina para conexão
  Public Sub Conec()
Static IP, DB As String
On Error GoTo Trata
Dnovo:
IP = LeArquivoINI(nome_arquivo_ini, [Ô]geral[Ô], [Ô]ip[Ô], [Ô]Não Configurado[Ô])
DB = LeArquivoINI(nome_arquivo_ini, [Ô]geral[Ô], [Ô]local[Ô], [Ô]Não Configurado[Ô])
Dim Ping As Ping = New Ping()
Dim PingReply As PingReply = Ping.Send(IP)
If PingReply.Status <> IPStatus.Success Then
MsgBox([Ô]Servidor Esta Fora do AR[Ô])
Exit Sub
End If

Pnome = LeArquivoINI(nome_arquivo_ini, [Ô]geral[Ô], [Ô]remoto[Ô], 0)
If Pnome = [Ô]1[Ô] Then
Pnome = IP & [Ô]:[Ô] & DB
conexaoFB = New FbConnection([Ô]User=SYSDBA;Password=masterkey;Database=[Ô] & Pnome & [Ô] ;DataSource=localhost;ConnectionTimeout=15;Port=3050;Dialect=3[Ô])
IP = [Ô]Remoto [Ô] & IP
Else
conexaoFB = New FbConnection([Ô]User=SYSDBA;Password=masterkey;SIB:Character Set=WIN1252;Database=[Ô] & DB & [Ô];DataSource=[Ô] & IP & [Ô];Connection Timeout=90;Port=3050;Dialect=3;Protocol=NetBEUI[Ô])
End If
conexaoFB.Open()

Pnome = IP & [Ô]|[Ô] & DB
Trata:
If Err.Number = 5 Then
GoTo Dnovo
ElseIf Err.Number <> 0 Then
Erros()
End
End If
End Sub


e a seguinte rotina para executar o SQL
   Private Sub ExecSQL()
On Error GoTo trata
Static CMD As FbCommand
Static NNT As Integer

CMD = New FbCommand(Pnome, conexaoFB)

CMD.ExecuteNonQuery()
CMD.Dispose()
trata:
If Err.Number = 5 Then
Err.Clear()
elseIf Err.Number <> 0 Then
Erros()
Application.Exit()
End If
End Sub

esta funcionando certinho para criar/editar/excluir campos de uma tabela, ate mesmo para deletar tabelas

agora para criar AutoNumeração e relacionamento não da certo

este e o comando que estou tentando executar

Citação:

CREATE TABLE NOTA_CCE (ID BIGINT,REF BIGINT,CHAVE CHAR(100) NOT NULL,DATA DATE,DESTINATARIO CHAR(60) NOT NULL,NFE CHAR(10) NOT NULL,PROTOCOLO CHAR(15),CCE_CHAVE CHAR(15),CCE_PROTOCOLO CHAR(15),CCE_MOTIVO VARCHAR(1000) NOT NULL,CCE_REGISTRO CHAR(10));
CREATE GENERATOR GEN_NOTA_CCE_ID;
set TERM !;CREATE TRIGGER NOTA_CCE_BI FOR NOTA_CCE ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.ID IS NULL) THEN NEW.ID = GEN_ID(GEN_NOTA_CCE_ID,1);END!
SET TERM;!


a tabela e criada certinho mais não cria o Trigger então não consigo criar o campo autoNumeração
LLAIA 28/01/2013 14:00:27
#418204
CREATE TABLE NOTA_CCE (ID BIGINT,REF BIGINT,CHAVE CHAR(100) NOT NULL,DATA DATE,DESTINATARIO CHAR(60) NOT NULL,NFE CHAR(10) NOT NULL,PROTOCOLO CHAR(15),CCE_CHAVE CHAR(15),CCE_PROTOCOLO CHAR(15),CCE_MOTIVO VARCHAR(1000) NOT NULL,CCE_REGISTRO CHAR(10));

COMMIT;

CREATE GENERATOR GEN_NOTA_CCE_ID;
set TERM !;CREATE TRIGGER NOTA_CCE_BI FOR NOTA_CCE ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.ID IS NULL) THEN NEW.ID = GEN_ID(GEN_NOTA_CCE_ID,1);END!
SET TERM;!


Cara, tente colocar um commit entre a criação da tabela e do trigger.
MFLAVIO 28/01/2013 14:12:15
#418206
Citação:

:

CREATE TABLE NOTA_CCE (ID BIGINT,REF BIGINT,CHAVE CHAR(100) NOT NULL,DATA DATE,DESTINATARIO CHAR(60) NOT NULL,NFE CHAR(10) NOT NULL,PROTOCOLO CHAR(15),CCE_CHAVE CHAR(15),CCE_PROTOCOLO CHAR(15),CCE_MOTIVO VARCHAR(1000) NOT NULL,CCE_REGISTRO CHAR(10));

COMMIT;

CREATE GENERATOR GEN_NOTA_CCE_ID;
set TERM !;CREATE TRIGGER NOTA_CCE_BI FOR NOTA_CCE ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.ID IS NULL) THEN NEW.ID = GEN_ID(GEN_NOTA_CCE_ID,1);END!
SET TERM;!


Cara, tente colocar um commit entre a criação da tabela e do trigger.



Amigo Valeu pela dica mais não funcionou
GUIMORAES 28/01/2013 15:55:12
#418222
Resposta escolhida
MFLAVIO, eu não faço a leitura de um arquivo txt, mas segue exemplo abaixo:

Citação:



sql = [Ô]CREATE TABLE CREDITO ([Ô]
sql = sql & [Ô]CODIGO INTEGER NOT NULL PRIMARY KEY,[Ô]
sql = sql & [Ô]CLIENTE INTEGER,[Ô]
sql = sql & [Ô]DATA DATE DEFAULT CURRENT_DATE,[Ô]
sql = sql & [Ô]VALOR NUMERIC(15, 4) DEFAULT 0,[Ô]
sql = sql & [Ô]USUARIO INTEGER,[Ô]
sql = sql & [Ô]OBSERVACOES BLOB SUB_TYPE 1 CHARACTER SET WIN1251 COLLATE WIN1251); [Ô]

[ô]Executar o sql


sql = [Ô]CREATE GENERATOR CREDITO_CODIGO_GEN; [Ô]
[ô]Executar o sql


sql = [Ô]CREATE TRIGGER BI_CREDIDO_CODIGO FOR CREDITO [Ô]
sql = sql & [Ô]ACTIVE BEFORE INSERT [Ô]
sql = sql & [Ô]POSITION 0 [Ô]
sql = sql & [Ô]AS [Ô]
sql = sql & [Ô]BEGIN [Ô]
sql = sql & [Ô]IF (NEW.CODIGO IS NULL) THEN [Ô]
sql = sql & [Ô]NEW.CODIGO = GEN_ID(CREDITO_CODIGO_GEN, 1); [Ô]
sql = sql & [Ô]End[Ô]

[ô]Executar o sql




Abraços
MFLAVIO 28/01/2013 16:50:58
#418230
Citação:

:
MFLAVIO, eu não faço a leitura de um arquivo txt, mas segue exemplo abaixo:



sql = [Ô]CREATE TABLE CREDITO ([Ô]
sql = sql & [Ô]CODIGO INTEGER NOT NULL PRIMARY KEY,[Ô]
sql = sql & [Ô]CLIENTE INTEGER,[Ô]
sql = sql & [Ô]DATA DATE DEFAULT CURRENT_DATE,[Ô]
sql = sql & [Ô]VALOR NUMERIC(15, 4) DEFAULT 0,[Ô]
sql = sql & [Ô]USUARIO INTEGER,[Ô]
sql = sql & [Ô]OBSERVACOES BLOB SUB_TYPE 1 CHARACTER SET WIN1251 COLLATE WIN1251); [Ô]

[ô]Executar o sql


sql = [Ô]CREATE GENERATOR CREDITO_CODIGO_GEN; [Ô]
[ô]Executar o sql


sql = [Ô]CREATE TRIGGER BI_CREDIDO_CODIGO FOR CREDITO [Ô]
sql = sql & [Ô]ACTIVE BEFORE INSERT [Ô]
sql = sql & [Ô]POSITION 0 [Ô]
sql = sql & [Ô]AS [Ô]
sql = sql & [Ô]BEGIN [Ô]
sql = sql & [Ô]IF (NEW.CODIGO IS NULL) THEN [Ô]
sql = sql & [Ô]NEW.CODIGO = GEN_ID(CREDITO_CODIGO_GEN, 1); [Ô]
sql = sql & [Ô]End[Ô]

[ô]Executar o sql




Abraços



Caramba minha estrutura e exatamente igual a sua
eu crio a tabela
depois crio o Gerador e por fim crio o Trigger o erro acontece apenas no trigger o restante funciona
estou usando assim
Citação:

CREATE TRIGGER NOTA_CCE_BI FOR NOTA_CCE ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.ID IS NULL) THEN NEW.ID = GEN_ID(GEN_NOTA_CCE_ID,1);END



Você esta usando o fbCommand para executar os comandos SQL?
GUIMORAES 28/01/2013 17:12:56
#418238
Sim estou utilizando, segue abaixo um exemplo.


dim fbCmd As FbCommand
dim FBconn As New FbConnection

fbCmd = New FbCommand(sql, FBconn)

fbCmd.ExecuteNonQuery()
fbCmd.Dispose()
RICART 28/01/2013 22:25:58
#418268
Dá certo sim, isso é independente do local e da forma de conexão. Você fica com o arquivo isql.exe embarcado no seu aplicativo ou não. Então vc vai executar um script como informei no exemplo, lembrando de utilizar os delimitadores SET TERM corretamente. Você precisará utilzar isso para que o servidor do firebird interprete que será executada uma sequencia de linhas com processamento único.

Tenta aí que vai dar certo. Não tem problema de ser um arquivo ini. basta vc passar de forma adequada a string que contém o script que será processado.
Tópico encerrado , respostas não são mais permitidas