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

Pgomes

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

Recommended Posts

Pgomes

Boas,

Gostaria de saber se alguem com experiência em PHC me pode ajudar com este dilema.  🤔 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.

Share this post


Link to post
Share on other sites
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"

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 😡 ), 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 🤔, 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. :cheesygrin:

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

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.