Ir para conteúdo
Fórum Script Brasil
  • 0

(Resolvido) Substring - PROBLEMA COM CODIGO


DiegoVix

Pergunta

BOA TARDE PESSOAL,

ESTOU COM O SEGUINTE PROBLEMA,

TABLE PESSOA

IDPESSOA

NOMEPESSOA

ENDPESSOA

TABLE SERVIDOR_PUBLICO

MATRICULA

CARGO

DTADMISSAO

IDPESSOA

EU TENHO ESSAS DUAS TABELAS AI QUE ESTAO LIGADAS PELO ID PESSOA, EU PRECISO DE UMA SUBSTRING QUE TRAGA O NOME DE TODAS PESSOAS QUE POSSUA ESSE ERRO '' EX: Carlos TadeuAlmirante, o correto seria Carlos Tadeu Almirante.''

eu criei o seguinte codigo

SELECT *

FROM RH.T01000_PESFISICA

INNER JOIN RH.T01001_SERVIDOR

ON RH.T01000_PESFISICA.T01000_I_CDPESFIS = RH.T01001_SERVIDOR. T01000_I_CDPESFIS

WHERE len(substring(T01000_S_NOME,patindex('% %',T01000_S_NOME),len(T01000_S_NOME)))>10

SO QUE AINDA não ESTA TRAZENDO SO O QUE QUERO, alguém PODE ME AJUDAR???

Editado por DiegoVix
Link para o comentário
Compartilhar em outros sites

14 respostass a esta questão

Posts Recomendados

  • 0

Boa tarde Diego,

Este problema possui um padrão? Tipo: apenas o primeiro nome possui separação, os sobrenomes estão todos juntos?

Pergunto isto pois provavelmente esta implementação não resolverá o problema. você está pegando strings maiores que 10 caracteres. Mas se o nome for pequeno como Ana, Mara, Joao, José, Maria, etc, há a possibilidade de estarem juntos e seu filtro não identificar. Sem contar que se houver nomes com mais de 10 caracteres, também será listado.

Deixando minha opinião de lado e voltando a sua query, acho que deveria colocar o +1 depois do partindex, para o resultado não vir com o espaço em branco no começo da string. Como está pegando maiores que 10, o espaço contará!

WHERE len(substring(T01000_S_NOME,patindex('% %',T01000_S_NOME),len(T01000_S_NOME)))>10

WHERE len(substring(T01000_S_NOME,patindex('% %',T01000_S_NOME)+1,len(T01000_S_NOME)))>10

Ou então coloca o rtrim / ltrim para garantir que não haja nenhum espaço no começo e no final da string:

WHERE rtrim(ltrim(len(substring(T01000_S_NOME,patindex('% %',T01000_S_NOME),len(T01000_S_NOME)))))>10

Link para o comentário
Compartilhar em outros sites

  • 0
Boa tarde Diego,

Este problema possui um padrão? Tipo: apenas o primeiro nome possui separação, os sobrenomes estão todos juntos?

Pergunto isto pois provavelmente esta implementação não resolverá o problema. você está pegando strings maiores que 10 caracteres. Mas se o nome for pequeno como Ana, Mara, Joao, José, Maria, etc, há a possibilidade de estarem juntos e seu filtro não identificar. Sem contar que se houver nomes com mais de 10 caracteres, também será listado.

Deixando minha opinião de lado e voltando a sua query, acho que deveria colocar o +1 depois do partindex, para o resultado não vir com o espaço em branco no começo da string. Como está pegando maiores que 10, o espaço contará!

WHERE len(substring(T01000_S_NOME,patindex('% %',T01000_S_NOME),len(T01000_S_NOME)))>10

WHERE len(substring(T01000_S_NOME,patindex('% %',T01000_S_NOME)+1,len(T01000_S_NOME)))>10

Ou então coloca o rtrim / ltrim para garantir que não haja nenhum espaço no começo e no final da string:

WHERE rtrim(ltrim(len(substring(T01000_S_NOME,patindex('% %',T01000_S_NOME),len(T01000_S_NOME)))))>10

É ISSO, EU PRECISO QUE ELE TRAGA NA MINHA CONSULTA PALAVRAS DENTRO DO CAMPO NOME QUE ULTRAPASSEM 10 CARACTER, MAS TODA VEZ QUE ELE ENCONTRAR UM ESPAÇO, ELE COMEÇE A CONTA A PALAVRA DE NOVO

EX: DIEGO SANTANA CRUZ - não POSSUI NENHUMA PALAVRA ACIMA DE 10 CARACTER

EX: DIEGO SANTANACRUZ - SANTANACRUZ TEM MAIS DE 10 CARACTER APOS O ESPAÇO

CONSEGUIU ME ENTENDER FULVIO ... E QUE ESSE PROBLEMA FOI DEVIDO A UMA MIGRAÇÃO DE SISTEMA MUITO ANTIGO... AI TO TENTANDO LISTA TODOS COM PROBLEMA PRA MIM PEDIR AOS USUARIOS PARA IREM ACERTANDO.

OBRIGADO PELO RETORNO

Link para o comentário
Compartilhar em outros sites

  • 0

Bom dia Diego,

Ok, entendido. O problema da sintaxe patindex é que o SQL retorna a posição do 1º caracter (no seu caso espaço) que encontrar. Sendo assim, você não conseguirá verificar os próximos espaços, desta forma.

Fiz o seguinte: criei uma tabela temporária, onde coloquei alguns nomes de teste. Fui gravando e quebrando os nomes de acordo com os espaços. Sendo assim, quando se encontra um espaço, divido. Depois conto quantos caracteres possui cada palavra do nome.

Coloquei um campo PrimeiroNome mais 5 sobrenomes. Caso tenha nomes maiores na sua base, só aumentar as colunas.

O WHILE fica do mesmo jeito. Caso queira mais sobrenomes, copia/cola e muda as variáveis. Coisa bem intuitiva, pois coloquei as variáveis na cronologia. Aí é só mudar o número.

Dá uma olhada no exemplo que coloquei aí. Se tiver alguma dúvida, pode postar.

Outra coisa: olha o exemplo de nome "Antonio de Souza Almeida". Se o "de" estiver junto do "Souza", não será identificado no filtro.

-- criar tabela
create table #Nomes (Controle int identity, IDPESSOA int, nome varchar(80), PrimeiroNome varchar(20), Sobrenome1 varchar(20),
Sobrenome2 varchar(20), Sobrenome3 varchar(20), Sobrenome4 varchar(20), Sobrenome5 varchar(20))

-- inserção
insert into #Nomes (IDPESSOA, nome) values (250, 'DIEGO SANTANA CRUZ')
insert into #Nomes (IDPESSOA, nome) values (325, 'DIEGO SANTANACRUZ')
insert into #Nomes (IDPESSOA, nome) values (856, 'Antonio FerreiraDuarte')
insert into #Nomes (IDPESSOA, nome) values (268, 'Antonio Ferreira Duarte')
insert into #Nomes (IDPESSOA, nome) values (2952, 'Antonio de Souza Almeida')
insert into #Nomes (IDPESSOA, nome) values (268, 'Antonio de SouzaAlmeida')

-- rodar tudo, daqui até o **
Declare @Contador int

Set @Contador = 1

While @Contador < (select count(nome) from #Nomes)
Begin
  update #nomes set Sobrenome1 = (select substring(nome, patindex('% %',nome)+1, len(nome)) from #Nomes where controle=@Contador) where controle=@Contador
  update #nomes set PrimeiroNome = (select substring(nome, 1, patindex('% %',nome)-1) from #Nomes where controle=@Contador) where controle=@Contador
  Set @Contador = @Contador + 1
End

Set @Contador = 1

While @Contador < (select count(nome) from #Nomes)
Begin
  update #nomes set Sobrenome2 = (select substring(Sobrenome1, patindex('% %',Sobrenome1)+1, len(Sobrenome1)) from #Nomes where controle=@Contador) where controle=@Contador
  update #nomes set Sobrenome1 = (select substring(Sobrenome1, 1, patindex('% %',Sobrenome1)-1) from #Nomes where controle=@Contador) where controle=@Contador
  update #Nomes set Sobrenome2= null where Sobrenome1=Sobrenome2
  Set @Contador = @Contador + 1
End

Set @Contador = 1

While @Contador < (select count(nome) from #Nomes)
Begin
  update #nomes set Sobrenome3 = (select substring(Sobrenome2, patindex('% %',Sobrenome2)+1, len(Sobrenome2)) from #Nomes where controle=@Contador) where controle=@Contador
  update #nomes set Sobrenome2 = (select substring(Sobrenome2, 1, patindex('% %',Sobrenome2)-1) from #Nomes where controle=@Contador) where controle=@Contador
  update #Nomes set Sobrenome3= null where Sobrenome2=Sobrenome3
  Set @Contador = @Contador + 1
End

-- **

select * from #Nomes 

select * from #Nomes where len(PrimeiroNome)>10 or len(Sobrenome1)>10 or len(Sobrenome2)>10 or len(Sobrenome3)>10

Link para o comentário
Compartilhar em outros sites

  • 0
Bom dia Diego,

Ok, entendido. O problema da sintaxe patindex é que o SQL retorna a posição do 1º caracter (no seu caso espaço) que encontrar. Sendo assim, você não conseguirá verificar os próximos espaços, desta forma.

Fiz o seguinte: criei uma tabela temporária, onde coloquei alguns nomes de teste. Fui gravando e quebrando os nomes de acordo com os espaços. Sendo assim, quando se encontra um espaço, divido. Depois conto quantos caracteres possui cada palavra do nome.

Coloquei um campo PrimeiroNome mais 5 sobrenomes. Caso tenha nomes maiores na sua base, só aumentar as colunas.

O WHILE fica do mesmo jeito. Caso queira mais sobrenomes, copia/cola e muda as variáveis. Coisa bem intuitiva, pois coloquei as variáveis na cronologia. Aí é só mudar o número.

Dá uma olhada no exemplo que coloquei aí. Se tiver alguma dúvida, pode postar.

Outra coisa: olha o exemplo de nome "Antonio de Souza Almeida". Se o "de" estiver junto do "Souza", não será identificado no filtro.

-- criar tabela
create table #Nomes (Controle int identity, IDPESSOA int, nome varchar(80), PrimeiroNome varchar(20), Sobrenome1 varchar(20),
Sobrenome2 varchar(20), Sobrenome3 varchar(20), Sobrenome4 varchar(20), Sobrenome5 varchar(20))

-- inserção
insert into #Nomes (IDPESSOA, nome) values (250, 'DIEGO SANTANA CRUZ')
insert into #Nomes (IDPESSOA, nome) values (325, 'DIEGO SANTANACRUZ')
insert into #Nomes (IDPESSOA, nome) values (856, 'Antonio FerreiraDuarte')
insert into #Nomes (IDPESSOA, nome) values (268, 'Antonio Ferreira Duarte')
insert into #Nomes (IDPESSOA, nome) values (2952, 'Antonio de Souza Almeida')
insert into #Nomes (IDPESSOA, nome) values (268, 'Antonio de SouzaAlmeida')

-- rodar tudo, daqui até o **
Declare @Contador int

Set @Contador = 1

While @Contador < (select count(nome) from #Nomes)
Begin
  update #nomes set Sobrenome1 = (select substring(nome, patindex('% %',nome)+1, len(nome)) from #Nomes where controle=@Contador) where controle=@Contador
  update #nomes set PrimeiroNome = (select substring(nome, 1, patindex('% %',nome)-1) from #Nomes where controle=@Contador) where controle=@Contador
  Set @Contador = @Contador + 1
End

Set @Contador = 1

While @Contador < (select count(nome) from #Nomes)
Begin
  update #nomes set Sobrenome2 = (select substring(Sobrenome1, patindex('% %',Sobrenome1)+1, len(Sobrenome1)) from #Nomes where controle=@Contador) where controle=@Contador
  update #nomes set Sobrenome1 = (select substring(Sobrenome1, 1, patindex('% %',Sobrenome1)-1) from #Nomes where controle=@Contador) where controle=@Contador
  update #Nomes set Sobrenome2= null where Sobrenome1=Sobrenome2
  Set @Contador = @Contador + 1
End

Set @Contador = 1

While @Contador < (select count(nome) from #Nomes)
Begin
  update #nomes set Sobrenome3 = (select substring(Sobrenome2, patindex('% %',Sobrenome2)+1, len(Sobrenome2)) from #Nomes where controle=@Contador) where controle=@Contador
  update #nomes set Sobrenome2 = (select substring(Sobrenome2, 1, patindex('% %',Sobrenome2)-1) from #Nomes where controle=@Contador) where controle=@Contador
  update #Nomes set Sobrenome3= null where Sobrenome2=Sobrenome3
  Set @Contador = @Contador + 1
End

-- **

select * from #Nomes 

select * from #Nomes where len(PrimeiroNome)>10 or len(Sobrenome1)>10 or len(Sobrenome2)>10 or len(Sobrenome3)>10

TA DANDO UM ERRO DEVIDO A ISSO AQUI EU ACHO ''(where controle=@Contador)

where controle=@Contador ... E EU PERCEBI NA HORA QUE você CRIOU SUA TABELA você DECLARO ESSE CAMPO... GOSTARIA DE SABER COMO ELE FOI UTILIZADO??

ABRAÇO

Link para o comentário
Compartilhar em outros sites

  • 0

Boa tarde Diego,

Executei o script aqui e deu tudo ok.

A declaração da variável "@Contador" tem que ser executada junto com os While's. Ela existe apenas em tempo de execução. Por isso q deve estar dando erro pra vc. Seleciona ela também e manda executar.

O campo "Controle" é auto-incremento. Foi utilizado apenas para controlar as manipulações.

Qualquer dúvida, posta aí. :.)

Link para o comentário
Compartilhar em outros sites

  • 0
Boa tarde Diego,

Executei o script aqui e deu tudo ok.

A declaração da variável "@Contador" tem que ser executada junto com os While's. Ela existe apenas em tempo de execução. Por isso q deve estar dando erro pra vc. Seleciona ela também e manda executar.

O campo "Controle" é auto-incremento. Foi utilizado apenas para controlar as manipulações.

Qualquer dúvida, posta aí. :.)

deu certo cara... não sei nem como agradecer... eu rodei esse script seu ai... e deu certo... cheguei no meu objetivo

muito obriga Fulvio!!!

Link para o comentário
Compartilhar em outros sites

  • 0

Pensei que tivesse resolvido, mas o comando que me passaram ele atualiza a tabela... e não pode!!!

Bom dia A TODOS!!!

Eu estou precisando de fazer uma consulta no meu banco de dados da seguinte forma!!!!

Tabela Clientes

CodCli ----- integer

NomeCli ----- Varchar(50)

Eu quero que a condição leia linha por linha do meu Banco e so traga aqueles clientes que possuem nomes superiores a 10 caracter,

por exemplo '' Diego de Souza'' ---- nenhuma sas 3 palavras tem mais de 10 caracter

exemplo 2 '' Diego CruzdeSouza'' ---- esse já deve trazer porque tem mais de 10 caracter colado sem espaço...

eu preciso disso idependente se ta no começo ou no fim, mas eu preciso tambem que toda vez que ele tiver espaço ele começe a recontar novamente...

Aguem pode me ajuda????

ResponderCitação

Link para o comentário
Compartilhar em outros sites

  • 0

Boa tarde Diego.

O script que te passei não funcionou não? O script altera a tabela temporária. Toda vez q tem espaço, ele separa os nomes. Inclua sua chave na tabela temporária, dê o select e terá as colunas de sua tabela principal com as linhas pesquisadas.

Link para o comentário
Compartilhar em outros sites

  • 0
Boa tarde Diego.

O script que te passei não funcionou não? O script altera a tabela temporária. Toda vez q tem espaço, ele separa os nomes. Inclua sua chave na tabela temporária, dê o select e terá as colunas de sua tabela principal com as linhas pesquisadas.

Funciono Fulvio, so que eu fiz na base de teste minha aqui, ai o que aconteceu... ele atualizou os nomes no campo e so deixou os sobrenomes, ai depois eu rodei essa consulta

SELECT *

FROM RH.T01000_PESFISICA

INNER JOIN RH.T01001_SERVIDOR

ON RH.T01000_PESFISICA.T01000_I_CDPESFIS =

RH.T01001_SERVIDOR. T01000_I_CDPESFIS

WHERE RTRIM(LTRIM(LEN(SUBSTRING(T01000_S_NOME,PATINDEX('% %',T01000_S_NOME)

,LEN(T01000_S_NOME)))))>10

Ai ele busco realmente so o que eu queria!!! Até ai deu certo!!! So que ele sumiu com os primeiros nomes tudo entendeu!!!!!

RH.T01000_PESFISICA (e minha tabela de cadastro de pessoas)

RH.T01001_SERVIDOR (e minha tabela onde eu tranformo essa pessoa em um servidor''funcionario'')

dexa eu te explicar o porque desse procedimento. a pessoa é cadastrada no sistema em um simples formulario... ai e gerado um codigo somente dentro do banco... ai eu abro outro formulario e consulto essa pessoa e tranformo ele num funcionario, ai nessa tela eu gero a matricula dele no sistema... entendeu!!! por isso fiz essas referencias ai no FROM... o seu comando me serviu perfeitamente... o unico problema que ele atualiza e não deixa voltar o que era antes... sera que se eu der um BEGIN TRAN resolve???? depois eu volto com ROLLBACK...entendeu????

Link para o comentário
Compartilhar em outros sites

  • 0

Boa tarde Diego.

O script que te passei, seria uma verificação em massa. Vamos passo a passo, levando em consideração se fosse rodar na sua Base:

- Criar a tabela temporária (no meu exemplo, #Nomes), ou fixa que posteriormente será deletada.

- Dar carga nesta tabela, com os campos Nomes e IDPESSOA.

- Rodar o script que te passei.

- Dar o select nos campos da tabela criada, identificando os nomes e sobrenomes com mais de 10 caracteres.

- Pegar os IDPESSOA que foram filtrados e utiliza-los na sua tabela, para listar as pessoas que estão com problemas.

No seu caso, você rodaria este select aí que postou, selecionando apenas a coluna NOME e IDPESSOA, inserindo na temporária:

insert into #Nomes (IDPESSOA, nome)
 SELECT  NOME, IDPESSOA FROM RH.T01000_PESFISICA ......

Ai você roda o resto do script

Na temporária, você terá os nomes todos divididos pelo espaço. Nela, você fará seu filtro. Pega os IDPESSOA nela e uitilize na sua Base Oficial.

Outra coisa: se utilizar o BEGIN TRAN e der ROLLBACK, você irá desfazer tudo que vez.

Qualquer dúvida, pode postar.

Link para o comentário
Compartilhar em outros sites

  • 0
Boa tarde Diego.

O script que te passei, seria uma verificação em massa. Vamos passo a passo, levando em consideração se fosse rodar na sua Base:

- Criar a tabela temporária (no meu exemplo, #Nomes), ou fixa que posteriormente será deletada.

- Dar carga nesta tabela, com os campos Nomes e IDPESSOA.

- Rodar o script que te passei.

- Dar o select nos campos da tabela criada, identificando os nomes e sobrenomes com mais de 10 caracteres.

- Pegar os IDPESSOA que foram filtrados e utiliza-los na sua tabela, para listar as pessoas que estão com problemas.

No seu caso, você rodaria este select aí que postou, selecionando apenas a coluna NOME e IDPESSOA, inserindo na temporária:

insert into #Nomes (IDPESSOA, nome)
 SELECT  NOME, IDPESSOA FROM RH.T01000_PESFISICA ......

Ai você roda o resto do script

Na temporária, você terá os nomes todos divididos pelo espaço. Nela, você fará seu filtro. Pega os IDPESSOA nela e uitilize na sua Base Oficial.

Outra coisa: se utilizar o BEGIN TRAN e der ROLLBACK, você irá desfazer tudo que vez.

Qualquer dúvida, pode postar.

ele ta dando esse erro aki não hora que lanco esse codigo

insert into TMP_Nomes (codnome, nome)

SELECT T01000_S_NOME,T01000_I_CDPESFIS FROM RH.T01000_PESFISICA

''Msg 245, Level 16, State 1, Line 1

Conversion failed when converting the varchar value 'GURHU' to data type int.''

Ghuru e o nome de meu banco

eu não achei ainda esse motivo ai...

Link para o comentário
Compartilhar em outros sites

  • 0
Boa tarde Diego.

O script que te passei, seria uma verificação em massa. Vamos passo a passo, levando em consideração se fosse rodar na sua Base:

- Criar a tabela temporária (no meu exemplo, #Nomes), ou fixa que posteriormente será deletada.

- Dar carga nesta tabela, com os campos Nomes e IDPESSOA.

- Rodar o script que te passei.

- Dar o select nos campos da tabela criada, identificando os nomes e sobrenomes com mais de 10 caracteres.

- Pegar os IDPESSOA que foram filtrados e utiliza-los na sua tabela, para listar as pessoas que estão com problemas.

No seu caso, você rodaria este select aí que postou, selecionando apenas a coluna NOME e IDPESSOA, inserindo na temporária:

insert into #Nomes (IDPESSOA, nome)
 SELECT  NOME, IDPESSOA FROM RH.T01000_PESFISICA ......

Ai você roda o resto do script

Na temporária, você terá os nomes todos divididos pelo espaço. Nela, você fará seu filtro. Pega os IDPESSOA nela e uitilize na sua Base Oficial.

Outra coisa: se utilizar o BEGIN TRAN e der ROLLBACK, você irá desfazer tudo que vez.

Qualquer dúvida, pode postar.

ele ta dando esse erro aki não hora que lanco esse codigo

insert into TMP_Nomes (codnome, nome)

SELECT T01000_S_NOME,T01000_I_CDPESFIS FROM RH.T01000_PESFISICA

''Msg 245, Level 16, State 1, Line 1

Conversion failed when converting the varchar value 'GURHU' to data type int.''

Ghuru e o nome de meu banco

eu não achei ainda esse motivo ai...

já achei... era so inverter ali no select o T01000_S_NOME pelo T01000_I_CDPESFIS e deu certo... muito obrigado Fulvio... minha questao esta 100% resolvido desta vez

Grande Abraço e até a proxima!!!

Obrigado!!!!

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,5k
×
×
  • Criar Novo...