Erro em comandos SQL

Forum sobre SQL.

Moderador: Moderadores

alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Erro em comandos SQL

Mensagem por alxsts »

Olá!

Aparentemente a sentença SQL está correta. Não entendi
Poka escreveu:É para deixar o campo codcli como not null ( flag = 1)
Se o conteúdo de uma coluna é null e você quer que ele deixe de ser null, é só atribuir um valor para ele, o que você já está fazendo.
Se quiser atribuir null para uma coluna, desde que ela permita, é só fazer

Código: Selecionar todos

SET nome_da_coluna = NULL
Se quiser testar o nome da coluna para ver se é ou não null, uma das opções é

Código: Selecionar todos

WHERE nome_da_coluna IS NULL OR nome_da_coluna_1 IS NOT NULL
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Erro em comandos SQL

Mensagem por Poka »

Alexandre

quando eu executo o comando abaixo

Código: Selecionar todos

alter table dadopro add PRIMARY KEY  ( codcli)
dá esse erro

Código: Selecionar todos

Error HY000 - [ODBC Firebird Driver][Firebird]unsuccessful metadata update
Column: CODCLI not defined as NOT NULL - cannot be used in PRIMARY KEY constraint definition
estou entendendo que o campo necessita estar como not null

set tiver + alguma dica , agradeço

Poka
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Erro em comandos SQL

Mensagem por alxsts »

Olá!

A sintaxe seria esta:

Código: Selecionar todos

ALTER TABLE dadopro ADD CONSTRAINT PK_dadopro  PRIMARY KEY(codcli);
Se continuar dando este erro que você mostrou, será necessário alterar as propriedades da coluna codcli para NOT NULL e o comando é este mesmo que você mostrou. Não sei qual a razão do erro mas, tente fazer um "quebra galho". Supondo que o tipo de dados da coluna codcli seja BIGINT, crie uma coluna a mais na tabela:

Código: Selecionar todos

ALTER TABLE dadopro ADD tmp_codcli BIGINT NOT NULL;
COMMIT;
O próximo passo será jogar todos os codcli para a nova coluna. Naturalmente, nenhum codcli poderá estar com o valor NULL. Se existir algum NULL nesta coluna, você precisará atribuir um código único e não NULLo para ela, em cada registro que estiver netas condições.
Resolvida a questão dos NULL, preencha a coluna tmp_codcli:

Código: Selecionar todos

UPDATE dadopro SET tmp_codcli = codcli
Se quiser, você poderá mover a nova coluna para a posição 1 da tabela:

Código: Selecionar todos

ALTER TABLE dadopro ALTER tmp_codcli POSITION 1;
Feito isto, tente criar a PK:

Código: Selecionar todos

ALTER TABLE dadopro ADD CONSTRAINT PK_dadopro  PRIMARY KEY(tmp_codcli);
Se der certo delete a coluna codcli antiga

Código: Selecionar todos

ALTER TABLE dadopro drop codcli;
e renomeie a coluna temporária para o nome antigo:

Código: Selecionar todos

ALTER TABLE dadopro alter tmp_codcli to codcli;
Naturalmente, estas operações tem que ser feitas quando o banco não estiver sendo usado por outros usuários. Também é preciso levar em conta as dependências desta tabela, como foreign keys, stored procedures, triggers, views. Nem é preciso dizer que fazer backup da tabela antes é essencial. Para isto, use:

Código: Selecionar todos

SELECT * INTO dadopro_bkp FROM dadoopro;
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Erro em comandos SQL

Mensagem por Poka »

Olá,

Tenho um arquivo de (produto), nesse arquivo não costumo salvar o estoque atual.

Tenho outro arquivo de controle da ficha de estoque (Fichaest) .
Esse arquivo Fichaest contém o movimento de todos os produtos, ele está em ordem de codigo do produto + data, assim
consigo pegar o saldo de qualquer produto, em qualquer data, isto em dbf.
Agora com o Firebird, não estou vendo como pegar esse saldo.

Em dbf eu tinha uma função PegaSaldo(codigo produto, data).
Era só dar um scope , dava um seek numa data maior, retrocedia 1 e estava com o saldo nas mãos.
Não estou vendo jeito de fazer isso com Select.

Imagina o arquivo Fichaest com codigo 10 com lançamentos no mês de dezembro do dia 1 ao dia 31, quero pegar o saldo do dai 15, e no dia 15 tenho varios lançamentos, como fazer num select?

Alguém pode dar alguma idéia?

Poka
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Erro em comandos SQL

Mensagem por JoséQuintas »

Precisa ter alguma ordem.
É selecionar o último lançamento da data.

Dependendo do banco de dados, poderia ser numa destas formas

Código: Selecionar todos

SELECT * FROM ESTMOV WHERE CODIGO=10 AND DATA='2015-11-01' ORDER BY LANCTO DESC LIMIT 1

SELECT TOP 1 * FROM ESTMOV WHERE CODIGO=10 AND DATA='2015-11-01' ORDER BY LANCTO DESC
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Erro em comandos SQL

Mensagem por Poka »

Valeu Quintas.
Vou testar amanhã, se não der certo volto aqui.
O desc matou a charada.

Poka
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Erro em comandos SQL

Mensagem por Poka »

Quintas,
testei agora aqui e deu certo.
Dá certo quando a data que procuro tem lançamento .

Imagina o seguinte na ficha de estoque
no mês de outubro tem movimento do dia 1 ao dia 10 e do dia 20 ao 30.
Para pegar o saldo do dia 15 preciso saber o saldo anterior, que é o saldo do dia 10.

Tem alguma idéia?

Grato

Poka
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Erro em comandos SQL

Mensagem por Poka »

Já consegui resolver.


Poka
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Erro em comandos SQL

Mensagem por alxsts »

Olá!

Muito boa a questão, para quem gosta de desafios SQL. Poderia compartilhar a solução encontrada?

Antes de você informar que havia solucionado, eu estava tentando montar uma solução. Considerando os detalhes do tópico anterior, cheguei na consulta abaixo, considerando que a coluna data seja do tipo DateTime:

Código: Selecionar todos

SELECT * 
  FROM MovEst
 WHERE codigo = 10
   AND data = (SELECT MAX(data) 
                     FROM MovEst
                    WHERE codigo = 10
                      AND Cast(data as Date) <= Cast( '2015-10-15' as Date ) ) 
Nestes casos, ajuda muito informar o layout das tabelas envolvidas. Na tabela MovEst, qual é o tipo de dados da coluna que armazena a data do movimento? Se for um campo que armazena a data e hora, ficará mais fácil. Caso contrário, talvez precise de outra coluna que identifique a sequencia do lançamento, como disse o Quintas.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Erro em comandos SQL

Mensagem por Poka »

Olá Alexandre,

Obrigado por responder

Realmente um campo de controle de sequencia se faz necessário para pegar o saldo válido

Código: Selecionar todos

func fSaldo(xcodigo,xdata)
    /*
    fb_executa sempre me retorna  a matriz m_select com as linhas recuperadas
   -nControl é o campo de controle que tem 17 digitos, uso uma funcao do firebird
   que me retorna ano,mes,dia,hora,minuto,segundo e fracao de segundo, assim nunca se repete
   formação de nControl  AAAAMMDDHHMMSSFFF
   - fb_data retorna a data no formato correto para teste com o firebird
   */
   local vsaldo:=0 
   //
   str:="select first 1 e.qtdSldAt  from fichaEst e where e.codprod = "+ xcodigo;
   +" and  e.data = '"+fb_data(xdata) +"' order by e.data , nControl desc ;" 
   //
   fb_executa()
   if empty(m_select) 
      // se nao encontrar procuro o saldo anterior
      // pego a data anterior , aqui preciso da data anterior ,  nem sempre a data anterior é o dia  anterior
      str:="select first 1  e.data  from fichaEst e where e.codprod = "+ xcodigo ;    
      +" and  e.data < '"+fb_data(xdata) +"' order by e.data desc ;" 
      fb_executa()
      // se m_select retornar vazio, não tem nenhum lancamento anterior 
      if empty( len(m_select)  )
         vsaldo:=0
      else 
         // pesquiso a data anteriror
	  xdata:=m_select[1,1]
          str:="select first 1 e.qtdSldAt  from fichaEst e where e.codprod = "+ xcodigo;
	  +" and  e.data = '"+fb_data(xdata)	+"' order by e.data , nControl desc ;" 
	   fb_executa()
           vsaldo:=( m_select[1,1])
       endif			
   else
       vsaldo:=( m_select[1,1])
   endif			
retu vsaldo
PROBLEMA

em um relatório com 260 produtos para realizar compras, onde preciso do saldo atual de cada produto, demora cerca de 8 segundos, com dbf era praticamente instantâneo. O meu computador é bem fraco, pode ser que num servidor não venha fazer diferença ( ou notar a diferença). Imagina no select para procurar a data anterior tiver milhares de lançamentosm, em um único produto é instantâneo, agora uma lista com 5 mil produtos!!!.

Vou tentar fazer uns testes com a cláusula Max que você passou para ver se tem jeito também, quem sabe dá alguma diferença.


Poka
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Erro em comandos SQL

Mensagem por alxsts »

Olá.

A tabela do banco tem que ter PK e índice. Poste o script de criação desta tabela.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Erro em comandos SQL

Mensagem por JoséQuintas »

Como já comentamos por aqui, pra tirar proveito da base de dados em SQL é usar o mínimo possível.
Fazer uma consulta complexa é mais rápido do que fazer várias consultas simples.
Então nesse caso o ideal é um comando que já traga TODOS os cálculos prontos, de TODOS os produtos.

Ainda não cheguei nessa parte no meu aplicativo, mas talvez este post ajude a ter alguma idéia.

https://pctoledo.org/forum/viewto ... 42&t=16136
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Erro em comandos SQL

Mensagem por Poka »

Olá
Fazendo um teste aqui, o arquivo que controla o estoque tem +- 35.000 registros de todos os códigos.
O relatório pega os produtos que tem estoque minimo maior que zero. Dá +- 250 produtos, demora 2 minutos e 40 segundos. Em dbf - de 5 segundos.

Quintas , não vi como consultar tudo de uma só vez nesse caso.
Alexandre veja como está o índice (anexo).

Será que tem jeito de melhorar a performance?


Poka
Anexos
tela2.jpg
tela1.jpg
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Erro em comandos SQL

Mensagem por alxsts »

Olá!

Pode mostrar a consulta SQL que está usando?
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Poka
Usuário Nível 4
Usuário Nível 4
Mensagens: 563
Registrado em: 25 Out 2004 21:26
Localização: Leme/SP

Erro em comandos SQL

Mensagem por Poka »

Mx contém os codigos dos produtos
Msaldo guarda os saldos dos produtos



Código: Selecionar todos

for a:= 1 to len(mx)
  
      msaldo[a]:=fsaldoPa( mx[a,1] ,servData)			

next

Código: Selecionar todos

FUNC FSALDOPA(XCODIGO,XDATA)
			// RETORNA O SALDO DA DATA
			// fb_executa() retorna o resultado na matriz m_select
			LOCAL VSALDO:=0 
			//
			str:="select first 1 e.qtdSldAt from fichapaCI e where e.codprod = "+ xcodigo;
   +" and  e.data = '"+fb_data(xdata)	 +"' order by e.data, e.fb_control desc ;"
			x:=fb_executa()
			*-------------- 
			if empty(m_select) 
   			// se nao encontrar procuro o saldo anterior
   			// pego a data anterior
   			str:="select first 1  e.data  from fichapaCI e where e.codprod = "+ xcodigo ;
						+" and  e.data < '"+fb_data(xdata) +"' order by e.data desc ;" 
   			x:=fb_executa()
   			if empty( len(m_select)  )
						   vsaldo:=0      // nao tem lancamento anterior
						else   
						   xdata:=m_select[1,1]
      			str:="select first 1 e.qtdSldAt  from fichapaCI e where e.codprod = "+ xcodigo ;
									+" and  e.data = '"+fb_data(xdata)		+"' order by e.data , fb_control desc ;" 
		       x:=fb_executa()
      			vsaldo:=( m_select[1,1])
      endif			
   else
   			vsaldo:=( m_select[1,1])
   endif			
			*--------------
   
retu vsaldo

Poka
Responder