• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Pgomes

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

11 mensagens neste tópico

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.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

porque é que o timestamp não pode ser igual? qual a desvantagem disso?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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"

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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.

0

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