Occhio alla virgola!

Ravanando in un foglio Excel, io e il mio fido capo abbiamo fatto una scoperta piuttosto inquietante.

una semplice operazione il cui risultato è ottenibile a mente senza sforzo, su Excel (ma direi su tutti i sistemi che trattano dati in virgola mobile) da il risultato sbagliato..

ebbene sì, e la prova arriva prestissimo, per fare la prova consiglio di usare i valori dello screenshot qui sotto, tenendo conto che nella cella C1 è presente la formula =A1-B1:

la differenza è 0,006… ma allora perchè la IF in D1 dice che C1 è maggiore di 0,06?!?!

semplice.. i dati in virgola mobile vengono rappresentati, come tutti i dati di un qualunque programma, in binario. Alcuni numeri non sono perfettamente rappresentabili in binario questo causa in qualche caso (non è regolare, dipende dal numero in se) aggiunge alla “N”esima cifra decimale un valore che però può causare dei problemi..

Aumentando infatti il numero di decimali della differenza fra A1 e B1 ecco cosa viene fuori…

ho fatto una prova anche con SQL e succede esattamente la stessa cosa

e se faccio il commercialista e devo fare dei conti al centesimo di EURO Come risolvo?!?!?

con un trucco del menga.. si memorizzano tutti i dati come interi (con gli interi il problema non sussiste) e si divide solo il risultato finale per 100..

ecco infatti qua sotto il risultato…

(in D5 è presente la stessa IF presente in D1)

Inserito in sql, Utilità | 3 commenti

controllo del nodo in caso di fail over su un cluster SQL

come controllare quando uno dei nodi del cluster cade?

prendendo (molto) spunto da un articolo apparso su SQLSERVER Central (sempre sia lodato) ho creato un pò di codice che verifica il nodo su cui l’istanza attuale sta girando.

in questa maniera è possibile confrontarla con una precedentemente salvata e poi decidere se inviare alert o quant’altro..

tutto si basa su questa riga di codice

exec master..xp_regread 'HKEY_LOCAL_Machine',
	'SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName\',
	'ComputerName'

che permette di capire il nome macchina sulla quale sta girando attualmente il codice lanciato.

giocando un pò è venuto fuori il codice qui sotto:

se non la trova, crea una tabella nel MSDB chiamata UT_DBParameter

esegue poi il codice di cui sopra andando ad estrapolare il nome del nodo sulla quale sta girando l’istanza.

se questo è diverso da quello memorizzato allora invio una mail di allerta e memorizzo il nome del nodo attuale nella riga della mia istanza nella tabella UT_DBParameter

DECLARE @previous Nvarchar(50)
DECLARE @Actual Nvarchar(50)

DECLARE @Sbj NVarChar(200)
Set @Sbj ='IStanza ' + @@SERVERNAME
DECLARE @Bdy NVarChar(4000)
DECLARE @OperatorEmail nvarchar(100)
Set @OperatorEmail = (select email_address from msdb.dbo.sysoperators where name = 'operatore')   --** 

IF OBJECT_ID('MSDB..UT_DBParameters') is null
	BEGIN
		CREATE TABLE UT_DBParameters
		(
		Parametro NVARCHAR(50),
		Valore NVARCHAR(50)
		)
	END	

SELECT @previous = isnull(Valore,'') FROM UT_DBParameters
WHERE Parametro = @@ServerName

IF OBJECT_ID('tempdb..#PHYSICALHOSTNAME') is not null
	BEGIN
		drop table #PHYSICALHOSTNAME
	END	

CREATE TABLE #PHYSICALHOSTNAME
(
VALUE VARCHAR(30),
CURRENT_ACTIVE_NODE VARCHAR(30)
)

INSERT #PHYSICALHOSTNAME
exec master..xp_regread 'HKEY_LOCAL_Machine',
'SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName\',
'ComputerName'

SELECT @Actual=CURRENT_ACTIVE_NODE FROM #PHYSICALHOSTNAME

IF  @previous <> @Actual
	BEGIN

		SET @Bdy = CHAR(13) + 'Istanza ' + @@SERVERNAME + ' passata dal nodo ' + @previous + ' al nodo ' + @Actual

		IF @Previous <> ''
			EXEC msdb.dbo.sp_send_dbmail  -- ***
					@profile_name = '4tsmailrobot'
					,@recipients = @OperatorEmail
					,@body = @Bdy
					,@subject = @Sbj

		Update Msdb..UT_DBParameters
		Set Valore = @Actual
		WHERE Parametro = @@ServerName

	END

NOTA

**operatore va sostituito con un operator valido per il server

*** si presuppone che il servizio di invio mail sia configurato..

Inserito in Server che passione, sql, Utilità | 1 commento

Conversione di un file di testo da UNIX a DOS/WINDOWS e Viceversa

ottimissimo tool..

http://www.sg-chem.net/u2win/

Inserito in Batch Caverna, Utilità, windows | Lascia un commento

Salvare le stored procedure di un Server SQL

da quando ho iniziato a scrivere stored per SQL ho avut il problema di tenere da qualche parte che non fosse SQL le stored che scrivevo.
così mi son messo di buona lena ed approfittando di una sera con la signora in ferie (sì lo sò c’è altro da fare ma tant’è.. ) ho scritto un pò di righe

ed eccole qua, quando imparerò a copincollare per bene il codice dentro sto blocco appunti che è il mio blog sarà anche un pò più leggibile..

Max

 

PROCEDURE [dbo].[Uds_Save_Stored_Procedure]
AS
DECLARE @StrSQL NVarChar(400)
DECLARE @Db NVarChar(400)
DECLARE @Sp NVarChar(400)
DECLARE @i int
DECLARE @I_SP Int
DECLARE @cmd NVarChar(1000)
DECLARE @Path NVarChar(1000)
Set @path ='c:\trace\'
BEGIN
SET NOCOUNT ON;
SET @StrSQL = ' IF OBJECT_ID(''tempdb.dbo.##DB_List'') IS NOT NULL' + CHAR(13)
+ ' DROP TABLE ##DB_List ' + CHAR(13) + CHAR(13)
+ ' CREATE TABLE ##DB_List (' + CHAR(13)
+ ' id int identity(1,1)' + CHAR(13)
+ ' ,DB nvarchar(max)' + CHAR(13)
+ ' )' + CHAR(13) + CHAR(13)
+ ' Insert Into ##DB_List (DB)' + CHAR(13)
+ ' SELECT name ' + CHAR(13)
+ ' FROM master..sysdatabases' + CHAR(13)
+ ' where name not in (''master'',''tempdb'',''model'',''msdb'')' + CHAR(13)
--PRINT @strsql
EXEC sp_executesql @strsql
SET @StrSQL = ' IF OBJECT_ID(''tempdb.dbo.##SP_List'') IS NOT NULL' + CHAR(13)
+ ' DROP TABLE ##SP_List ' + CHAR(13) + CHAR(13)
+ ' CREATE TABLE ##SP_List (' + CHAR(13)
+ ' id int identity(1,1)' + CHAR(13)
+ ' ,DB nvarchar(max)' + CHAR(13)
+ ' ,SP nvarchar(max)' + CHAR(13)
+ ' )' + CHAR(13) + CHAR(13)
--PRINT @strsql
EXEC sp_executesql @strsql
SET @i = 0
select top 1 @i = id
from ##DB_List
where id > @i
order by id
While @@Rowcount = 1
BEGIN
select @db = DB
from ##DB_List
where id = @i
SET @StrSQL = ' USE [' + @Db + ']' + CHAR(13) + CHAR(13)
+' Insert into ##SP_List (DB,SP)' + Char(13)
+' SELECT ''' + @db +''' ,name' + Char(13)
+' FROM sys.objects' + Char(13)
+' WHERE type = ''P''' + Char(13)
+' AND left(name,3) ''sp_''' + Char(13)
+' AND left(name,3) ''dt_''' + Char(13)
+' AND left(name,7) ''aspnet_''' + Char(13)
EXEC sp_executesql @strsql
--PRINT @strSQL
select top 1 @i = id
from ##DB_List
where id > @i
order by id
END
SET @i = 0
select top 1 @i = id
from ##SP_List
where id > @i
order by id
While @@Rowcount = 1
BEGIN
select @db = DB, @sp = SP
from ##SP_List
where id = @i
SET @strSQL = ' Use [' + @Db + ']' + char(13) + char(13)
+ ' IF OBJECT_ID(''tempdb.dbo.##sp_helptext'') IS NOT NULL' + char(13)
+ ' drop table ##sp_helptext ' + char(13)
+ ' create table ##sp_helpText (' + char(13)
+ ' id int identity(1,1)' + char(13)
+ ' ,tmptext nvarchar(max))' + char(13) + char(13)
+ ' insert into ##sp_helptext exec sp_helptext ['+ @Sp +']'+ char(13)
--PRINT @strsql
EXEC sp_executesql @strsql
set @i_sp = 0
select top 1 @i_sp = id
from ##sp_helpText
where id > @i_sp
order by id
while @@rowcount = 1
BEGIN
SELECT @cmd = 'echo ' + left(tmptext,LEN(tmptext)-2) + ' >> '+ @Path + '[' + @db + '].dbo.[' + @Sp + '].sql'
from ##sp_helpText
where id = @i_sp
--PRINT @cmd
exec master..xp_cmdshell @cmd
select top 1 @i_sp = id
from ##sp_helpText
where id > @i_sp
order by id
END
select top 1 @i = id
from ##SP_List
where id > @i
order by id
END
END
Inserito in sql | Etichette | Lascia un commento

T-SQL usare una variabile nel predicato IN()

Articolo interessantissimo che ho letto solo velocemente. da commentare appena possibile.

Link

Inserito in Dove Stiamo Andando?, sql | Lascia un commento

rap futuristico!

Inserito in Dove Stiamo Andando? | Lascia un commento

yyyymmddhhnnss difficilissimo in dos script..

problema, nominare un file o inserire in una variabile di ambiente la data ed ora attuale nel formato: YYYYMMDDHHNNSS

di solito è una vera rottura, normalmente si usa un arzigogolo strano utilizzando le variabili d’ambiente %DATE% e %TIME% che però hanno un difetto, sono localizzate, quindi uno script che funziona su una localizzazione Italiana non funziona su una inglese e viceversa.. che fare in ambienti misti?

ecco la soluzione, uno script e una riga di codice da inserire nel nostro file batch:

create uno script chiamato dataora.vbs quindi inserite all’interno la seguente stringa

Wscript.Echo year(now())&right("00"&month(now()),2)&right("00"&day(now()),2)&right("00"&hour(now()),2)&right("00"&minute(now()),2)&right("00"&second(now()),2)

quindi la riga magica da utilizzare nei vostri batch è la seguente:

for /F %%a in ('cscript /nologo dataora.vbs ^|find /V ""') DO SET DATAORA=%%a

 

da ora potrete utilizzare la variabile d’ambiente %DATAORA% contenente la tanto agognata stringa

enjoy!

Inserito in Batch Caverna, Utilità | Etichette , , , , , | Lascia un commento