Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #57 da revista programar. Faz já o download aqui!

Pgomes

Criar Stamp numa tabela de utilizador do PHC através do SQL

Mensagens Recomendadas

Pgomes    0
Pgomes

Boas,

Gostaria de saber se alguem com experiência em PHC me pode ajudar com este dilema.  :hmm: Preciso preencher do lado do SQL um campo de stamp(tipo char) tal como o PHC faz quando se introduz um registo num dos ecrans da aplicação.

O meu problema é que preciso introduzir grandes quantidades de informação calculada através de um StoredProcedure numa tabela de utilizador do PHC, mas o SQL como é muito rápido por vezes tenta criar dois registos com o mesmo stamp, e um deles não é introduzido.

Para esta tarefa criei uma função no SQL que tenta criar um stamp parecido aos do PHC quando se chama a função(u_stamp()) dentro do software:

CREATE FUNCTION u_PHCStamp(@user varchar(10) ='ADM')
RETURNS varchar(50)
as 
begin
declare @stamp varchar(50),@num_rand varchar(5), @num_rand1 varchar(9)

set @stamp=
	rtrim(@user) + rtrim(convert(varchar,getdate(),12)) 

set @num_rand=
left(convert(char,CAST( getdate() AS int )),2)
+ltrim(rtrim(cast(checksum(datepart(ms,getdate()))as char)))

	while len(@num_rand)<5
	begin
		set @num_rand=@num_rand+'0'
	end

set @num_rand1=
ltrim(rtrim(cast(checksum(datepart(n,getdate()))as char)))
+ltrim(rtrim(cast(checksum(datepart(s,getdate()))as char)))
+ltrim(rtrim(cast(checksum(datepart(ms,getdate()))as char)))
+reverse(ltrim(rtrim(cast(datepart(ms,getdate())as char))))

	while len(@num_rand1)<9
	begin
		set @num_rand1=@num_rand1+'0'
	end

set @stamp=@stamp+@num_rand+ ',' +@num_rand1


return @stamp
end
go

Mas tal como disse, mesmo o stamp utilizando milisegundos, o SQL é mais rápido e consegue tentar criar dois registos com o mesmo stamp, o que não pode acontecer.... :nono1:

Já dei várias voltas à cabeça  :wallbash: mas não consigo encontrar uma maneira simples de fazer isto.  :knuppel2:

Alguem que use PHC já se deparou com este problema, e me pode ajudar?

PS: Para quem está familiarizado com o PHC, se estão a pensar porque não usar um alerta do PHC, a resposta é não quero usar a função de alertas do PHC pois acho aquilo uma autêntica porcaria, são mais as vezes que falha do que funciona.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Pgomes    0
Pgomes

Desculpa, esqueci-me de mencionar que no phc o campo de stamp é a chave da tabela, quer seja uma tabela de utilizador ou do software, eles usam este campo de stamp. Por este motivo é que não pode haver duplicados.

Trata-se de um campo Char() com o seguinte aspecto : "ADM09013012345,123456789"

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
vitortomaz    1
vitortomaz

essa função é só chamada por ti?

ia a dizer para consultares o ultimo stamp e caso seja igual adicionares 1 ao stamp actual mas a esta hora já não estou a ver que problemas isso pode levantar, mas é questão de testares

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Pgomes    0
Pgomes

Pois, isso iria implicar ter fazer mais um select à tabela toda para comparar se o stamp que ia ser introduzido, já existe, e caso exista atribuir outro para não dar nenhum erro.

A desvantagem disso é que se trata de código que introduz uns milhares de linhas de cada vez que corre, e o que iria acontecer é que para além do tempo que já demora iria ficar mais demorado pois por cada INSERT teria de haver um SELECT antes.

Penso que o problema está apenas na última parte do stamp a partir da vírgula, pois eu não entendo a constituição destes stamp's na sua totalidade(e não consigo encontrar esta informação em lado nenhum :rant_01:), mas que penso ser esta:

"ADM09013012345,123456789"

[table]

[td]Utilizador[/td][td]| Data[/td][td]| Data anterior convertida[/td][td]| Separador[/td][td]| Nº q ñ entendo c é calculado[/td]

[td]ADM[/td][td]| 090130[/td][td]| 12345[/td][td]| ,[/td][td]| 123456789[/td]

[/table]

Por isso é que eu criei uma função para tentar replicar os stamp's da aplicação e tornar o processo o mais simples e fluido possivel.

Mas no entanto deste-me uma ideia vitortomaz :hmm:, a de passar mais um parametro para a função com o nº de registo, e adicionar um contador do lado do StoredProcedure que é incrementado a cada registo e passado para dentro da função de cada vez que esta é chamada. Usando este valor e acrescentando-o à direita da vírgula consigo garantir que o SQL não consegue criar e introduzir stamp's idênticos dentro do mesmo milésimo de segundo.

Tinha esperanças de encontrar alguém aqui no fórum que use PHC e já se tenha deparado com o problema de criar registos nas tabelas do PHC mas do lado do SQL, que me pudesse dizer como ultrapassou, ou não, este problema, não só para resolver o meu próprio dilema mas para perceber se é a maneira mais correcta ou se existe outra forma de o fazer. :biggrin:

Mas, se mais alguém quiser opinar sobre o assunto, agradeço. Todas as sugestões são bem vindas :notworthy: , e mais não seja podem ajudar a que se faça luz no fundo do túnel e me ocorram outras ideias... :)

Obrigado

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
vitortomaz    1
vitortomaz

Quando pensei no consultar o último foi mesmo com a ideia de um parâmetro que anda de chamada em chamada a "dizer" qual foi o último, por isso é que perguntei "quem" usava a função...

Nunca vi PHC à frente...

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Slammer    0
Slammer

mas o stamp tem de ser mesmo com esse aspecto?

eu sempre que preciso de inserir um registo em alguma tabela do PHC, por exemplo na tabela cl, utilizo o newid(), por exemplo: insert into cl(clstamp,no,estab) values(right(newid(),24),1,0).

O newid() produz uma string única. Caso queira com o prefixo 'ADM', faço: 'ADM'+right(newid(),21)

Faço sempre o stamp desta forma e nunca tive problemas.

Espero ter ajudado, fiquem bem pessoal

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
haztik    0
haztik

Esta função cria-te um stamp válido, o @value é normalmente o Rownumber, ou seja, se inserires 2 registos o 1º leva o numero 1 e o segundo o nº 2. No entanto podes por um numero aleatório qualquer para garantir que não tens stamps repetidos.

para o numero aleatório, chamas a função com algo pareciso com isto:

--Exemplo de chamada de função, com feed de numero random
select dbo.criaStamp('ABC',cast(right(ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)),6) as int),getdate()) as stamp

--Exemplo de chamada de função, com feed 1
select dbo.criaStamp('ABC',1,getdate()) as stamp

Função:

CREATE FUNCTION dbo.criaStamp 
(@user AS char(3), @value AS int, @currentdate as datetime)

RETURNS char(25) AS

BEGIN
DECLARE @stamp as char(25)

IF @value > 0 and @value < 999999
	BEGIN
	-- Cria o stamp
	SET @stamp = RTRIM(@user)
				+CONVERT(CHAR(6),@currentdate,12)
				+RIGHT(STR(CONVERT(float,@currentdate)*100000,20,3),9)
				+STUFF('000000',(7-LEN(LTRIM(STR(@value)))),6,@value)
	END
RETURN REPLACE(@stamp,'.',',')
END

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
miro3    1
miro3

Boas

Porque não usas a função do SQL que a PHC usa?

select

suser_sname()+left(newid(),5)+right(newid(),5)+ left(newid(),5)+right(newid(),5) stamp

gera sempre um um stamp unico.

Já migrei alguns milhares de registos usando sempre esta função para gerar stamps.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora


×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade