<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fabio Falcinelli &#187; Java</title>
	<atom:link href="http://www.fabiofalcinelli.it/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fabiofalcinelli.it</link>
	<description>Interessi e appunti</description>
	<lastBuildDate>Tue, 27 Sep 2011 15:52:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>JNI su HP-UX, le dimensioni dello stack contano</title>
		<link>http://www.fabiofalcinelli.it/2010/03/jni-su-hp-ux-le-dimensioni-dello-stack-contano/</link>
		<comments>http://www.fabiofalcinelli.it/2010/03/jni-su-hp-ux-le-dimensioni-dello-stack-contano/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 18:39:00 +0000</pubDate>
		<dc:creator>Fabio</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[BoKS]]></category>
		<category><![CDATA[HP-UX]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JNI]]></category>
		<category><![CDATA[pthread]]></category>
		<category><![CDATA[Stacksize]]></category>
		<category><![CDATA[tusc]]></category>

		<guid isPermaLink="false">http://www.fabiofalcinelli.it/?p=355</guid>
		<description><![CDATA[Arrugginito forse un po&#8217;, quando si passa tanto tempo a fare altro ci si dimentica di avere anche uno spazio web dove annotare quei piccoli successi che potrebbero tornare utili ad altri, ma anche a te semmai te ne dovessi dimenticare :) Il problema di fondo era che la chiamata JNI_CreateJavaVM produceva il segnale SIGABRT [...]]]></description>
			<content:encoded><![CDATA[<p>Arrugginito forse un po&#8217;, quando si passa tanto tempo a fare altro ci si dimentica di avere anche uno spazio web dove annotare quei piccoli successi che potrebbero tornare utili ad altri, ma anche a te semmai te ne dovessi dimenticare :)</p>
<p>Il problema di fondo era che la chiamata JNI_CreateJavaVM produceva il segnale SIGABRT quando invocato all&#8217;interno di un altro framework, nello specifico stavo utilizzando l&#8217;SDK BoKS.</p>
<p>La porzione di codice interessata, a parte dovuti accorgimenti, era del tutto coerente con quanto riportato da HP al link</p>
<p><a href="http://www.docs.hp.com/en/JAVAPROGUIDE/JNI_java2.html" target="_blank">http://www.docs.hp.com/en/JAVAPROGUIDE/JNI_java2.html</a></p>
<p>Provando ad utilizzare i parametri di inizializzazione della VM più svariati non si è cavato un ragno dal buco, seguendo comunque le linee guida riportate qui <a href="http://www.docs.hp.com/en/JAVAPROGUIDE/JNI_java2.html#primordial ">http://www.docs.hp.com/en/JAVAPROGUIDE/JNI_java2.html#primordial</a>, si è ipotizzato da subito un problema con lo stacksize su HP-UX, su Solaris, infatti, non erano stati riscontrati problemi di sorta.</p>
<p>Una sessione con <strong>tusc</strong> ha confermato quanto supposto:</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#6 kwakeup(PTH_CONDVAR_OBJECT, 0x60000000000ea400, WAKEUP_ONE, 0x9fffffff7f63cb50) = 0</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 ksleep(PTH_CONDVAR_OBJECT, 0x60000000000ea400, 0x60000000000d75b8, NULL) = 0</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#6 gettimeofday(0x9fffffff7f63cb30, NULL) ........ = 0</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 write(1, 0x9fffffffef4c0400, 43) .............. = 43</span><br />
E r r o r &nbsp; o c c u r r e d &nbsp; d u r i n g &nbsp; i n i t i a l i z a<br />
t i o n &nbsp; o f &nbsp; V M \n<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 write(1, 0x60000000001683a0, 28) .............. = 28</span><br />
j a v a . l a n g . S t a c k O v e r f l o <span style="color: #c20cb9; font-weight: bold;">w</span> E r r o r<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 write(1, 0xc000000015cf08b8, 1) ............... = 1</span><br />
\n<br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 unlink(&quot;/var/tmp/hsperfdata_boksa/19196&quot;) ..... = 0</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 sigaction(SIGILL, 0x9fffffffef7c6740, NULL) ... = 0</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 sigprocmask(SIG_UNBLOCK, NULL, 0x9fffffffef4c0b80) = 0</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 sigaction(SIGABRT, NULL, 0x9fffffffef4c0ba0) .. = 0</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 getpid() ...................................... = 19196 (19194)</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 &nbsp; Received signal 6, SIGABRT, in kill(), [0x9fffffffef76bfd0]</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">19196</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #666666; font-style: italic;">#2 &nbsp; &nbsp; Siginfo: sent by pid 19196 (uid 600), si_errno: 0</span></div></div>
<p>La soluzione?</p>
<p>Un semplice export della variabile <strong>PTHREAD_DEFAULT_STACK_SIZE</strong> a <strong>524288</strong>.</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">PTHREAD_DEFAULT_STACK_SIZE</span>=<span style="color: #000000;">524288</span></div></div>
<p>Si sarebbe anche potuta usare la chiamata pthread_default_stacksize_np(), ma poiché la parte di codice che crea i thread non è personalizzabile in quel dato SDK, l&#8217;export della variabile d&#8217;ambiente è stata l&#8217;unica soluzione attuabile.</p>
<p>Alla prossima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fabiofalcinelli.it/2010/03/jni-su-hp-ux-le-dimensioni-dello-stack-contano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shutdown HSQLDB</title>
		<link>http://www.fabiofalcinelli.it/2009/05/shutdown-hsqldb/</link>
		<comments>http://www.fabiofalcinelli.it/2009/05/shutdown-hsqldb/#comments</comments>
		<pubDate>Sat, 23 May 2009 09:35:43 +0000</pubDate>
		<dc:creator>Fabio</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Calabria]]></category>
		<category><![CDATA[Fiumefreddo Bruzio]]></category>
		<category><![CDATA[HSQLDB]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JDBC]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tramonto]]></category>

		<guid isPermaLink="false">http://www.fabiofalcinelli.it/?p=221</guid>
		<description><![CDATA[Ultimamente sto usando Hypersonic SQL DB in un software che sto scrivendo. Il driver utilizzato è &#8220;embedded&#8221; ovvero non è presente un server in attesa di ricevere comandi SQL, ma il database è un file gestito direttamente dal driver di hypersonic. Con questo tipo di accesso però, avevo notato perdite di dati sul database, non [...]]]></description>
			<content:encoded><![CDATA[<p>Ultimamente sto usando Hypersonic SQL DB in un software che sto scrivendo. Il driver utilizzato è &#8220;<em>embedded</em>&#8221; ovvero non è presente un server in attesa di ricevere comandi SQL, ma il database è un file gestito direttamente dal driver di hypersonic.</p>
<p>Con questo tipo di accesso però, avevo notato perdite di dati sul database, non tutto infatti diventava persistente e, certo di non aver scritto codice errato, iniziavo a pensare di non capirci più nulla.</p>
<p>Il fatto è che, a differenza di quanto ero solito fare con altri RDBMS, non è sufficiente chiudere una connessione con</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">connection.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></div></div>
<p>al termine dell&#8217;esecuzione del programma, il driver effettua caching delle tabelle per ottimizzare gli accessi al file system e non tutte le modifiche vengono scritte sul file.</p>
<p>È necessario fornire al driver l&#8217;istruzione di &#8220;SHUTDOWN&#8221; di modo che tutti i dati eventualmente ancora in cache vengano correttamente resi persistenti:</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003399;">Statement</span> shutdown <span style="color: #339933;">=</span> connection.<span style="color: #006633;">createStatement</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SHUTDOWN&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
shutdown.<span style="color: #006633;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
shutdown.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
connection.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Esiste inoltre, una funzione di shutdown che effettua anche una riorganizzazione del database ed una compressione dei dati. Essendo un&#8217;operazione lenta è bene non usarla troppo di frequente, il criterio d&#8217;uso è lo stesso di &#8220;SHUTDOWN&#8221;, &#8220;SHUTDOWN COMPACT&#8221;.</p>
<p>Alla prossima :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fabiofalcinelli.it/2009/05/shutdown-hsqldb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java &#8211; Esecuzione comandi su CLI parte II</title>
		<link>http://www.fabiofalcinelli.it/2009/02/java-esecuzione-comandi-su-cli-part-ii/</link>
		<comments>http://www.fabiofalcinelli.it/2009/02/java-esecuzione-comandi-su-cli-part-ii/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 20:24:08 +0000</pubDate>
		<dc:creator>Fabio</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Deadlock]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://fabiofalcinelli.netsons.org/?p=132</guid>
		<description><![CDATA[Se vi ricordate di un pezzo di codice scritto da me e che funzionava particolarmente bene per invocare comandi su UNIX&#8230; Beh&#8230; Scordatevelo! O meglio, dovrete fare qualche piccola modifica. Il codice in questione sembra, infatti, causare un piccolo problema chiamato deadlock. La cosa non si presenta sempre, ma dipende fortemente dalla quantità di output [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Se vi ricordate di un <a title="Java - Esecuzione comandi su CLI" href="http://www.fabiofalcinelli.it/2009/01/java-esecuzione-comandi-su-cli/" target="_blank">pezzo di codice scritto da me</a> e che funzionava particolarmente bene per invocare comandi su UNIX&#8230; Beh&#8230; Scordatevelo! O meglio, dovrete fare qualche piccola modifica.</p>
<p style="text-align: justify;">Il codice in questione sembra, infatti, causare un piccolo problema chiamato <em>deadlock</em>.</p>
<p style="text-align: justify;">La cosa non si presenta sempre, ma dipende fortemente dalla quantità di output che genera il comando e da come il sistema operativo gestisce il buffering della system call &#8220;write&#8221;. Lanciando <em>truss</em> da dentro al codice java, infatti, notavo che l&#8217;esecuzione delle system call si bloccava in attesa:</p>
<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ioctl<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, TCGETA, 0xFFBEDF34<span style="color: #7a0874; font-weight: bold;">&#41;</span> Err<span style="color: #666666; font-style: italic;">#22 EINVAL</span><br />
fstat64<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, 0xFFBEDFA8<span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span><br />
brk<span style="color: #7a0874; font-weight: bold;">&#40;</span>0x00068A70<span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span><br />
brk<span style="color: #7a0874; font-weight: bold;">&#40;</span>0x0006AA70<span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">0</span><br />
<span style="color: #c20cb9; font-weight: bold;">write</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, <span style="color: #ff0000;">&quot; D A T A &quot;</span>.., <span style="color: #000000;">5120</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">5120</span><br />
<span style="color: #c20cb9; font-weight: bold;">write</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, <span style="color: #ff0000;">&quot; * - &amp;gt; *&quot;</span>.., <span style="color: #000000;">5120</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000;">5120</span><br />
llseek<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">0</span>, <span style="color: #000000;">0</span>, SEEK_CUR<span style="color: #7a0874; font-weight: bold;">&#41;</span> Err<span style="color: #666666; font-style: italic;">#29 ESPIPE</span><br />
<span style="color: #c20cb9; font-weight: bold;">write</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>, <span style="color: #ff0000;">&quot; * - &amp;gt; * * * * * &quot;</span>.., <span style="color: #000000;">635</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>sleeping...<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></div>
<p style="text-align: justify;">Non è stato facilissimo arrivare alla causa, il metodo è infatti molto semplice, ma adesso che ho identificato il problema l&#8217;errore appare quasi evidente. Il problema risiede infatti nel canale di <em>standard error </em>letto prima dello <em>standard output</em>:</p>
<ol style="text-align: justify;">
<li>Prima di poter leggere lo standard error è necessario che il processo che esegue il comando termini, e non è detto che vi siano errori;</li>
<li>Prima di poter avere tutto l&#8217;output disponibile c&#8217;è bisogno di qualcuno che consumi i dati nel buffer, ma quel qualcuno è in attesa sullo standard error;</li>
<li>Deadlock!</li>
</ol>
<p style="text-align: justify;">Sinceramente, questa spiegazione, seppur sensata non mi convince ancora appieno e appena avrò più tempo analizzerò meglio i trace delle system call, nonostante ciò riporto di seguito la versione del metodo che risolve il problema.</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> execCommand<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> cmd<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span><span style="color: #009900;">&#123;</span><br />
<span style="color: #003399;">String</span> result <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<span style="color: #003399;">String</span> temp <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<span style="color: #003399;">BufferedReader</span> stdout <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<span style="color: #003399;">BufferedReader</span> stderr <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span></div></div>
<p>Process proc = Runtime.getRuntime().exec(cmd);</p>
<p>/*consume the output*/<br />
stdout = new BufferedReader(new InputStreamReader(<br />
proc.getInputStream()));<br />
temp = stdout.readLine();</p>
<p>while(temp!=null){<br />
if(result==null)<br />
result = temp+&#8221;\n&#8221;;<br />
else<br />
result += temp+&#8221;\n&#8221;;<br />
temp = stdout.readLine();<br />
}</p>
<p>stdout.close();</p>
<p>/*check if errors occurred*/<br />
stderr = new BufferedReader(new InputStreamReader(<br />
proc.getErrorStream()));<br />
temp = stderr.readLine();</p>
<p>if(temp!=null){<br />
result = temp+&#8221;\n&#8221;;<br />
temp = stderr.readLine();<br />
while(temp!=null){<br />
result += temp+&#8221;\n&#8221;;<br />
temp = stderr.readLine();<br />
}</p>
<p>stderr.close();<br />
throw new IOException(result);<br />
}</p>
<p>stderr.close();<br />
/*if no exceptions occurred then proceed to return the output*/<br />
return result;<br />
}</p>
<p style="text-align: justify;">Questo è quanto, il metodo main d&#8217;esempio del post precedente però è ancora valido :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fabiofalcinelli.it/2009/02/java-esecuzione-comandi-su-cli-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Statement vs PreparedStatement</title>
		<link>http://www.fabiofalcinelli.it/2009/01/statement-vs-preparedstatement/</link>
		<comments>http://www.fabiofalcinelli.it/2009/01/statement-vs-preparedstatement/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 12:50:49 +0000</pubDate>
		<dc:creator>Fabio</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Injection]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JDBC]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://fabiofalcinelli.netsons.org/?p=114</guid>
		<description><![CDATA[Quando frequentavo l&#8217;università mi chiedevo quale fosse effettivamente la differenza tra uno Statement e un PreparedStatement Java. Fondamentalmente mi permettevano di raggiungere lo stesso risultato in maniera lievemente diversa. In realtà i due costrutti sono molto più diversi di quanto non si creda. Ogni comando SQL ricevuto dal DBMS viene elaborato seguendo 3 fasi: Compilazione [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Quando frequentavo l&#8217;università mi chiedevo quale fosse effettivamente la differenza tra uno Statement e un PreparedStatement Java. Fondamentalmente mi permettevano di raggiungere lo stesso risultato in maniera lievemente diversa.</p>
<p style="text-align: justify;">In realtà i due costrutti sono molto più diversi di quanto non si creda. Ogni comando SQL ricevuto dal DBMS viene elaborato seguendo 3 fasi:</p>
<ol style="text-align: justify;">
<li>Compilazione (parsing del comando SQL);</li>
<li>Esecuzione;</li>
<li>Fetching  (restituzione del risultato al client).</li>
</ol>
<p style="text-align: justify;">Supponendo che vengano eseguite molte operazioni, la classe PreparedStatement permette di eseguire il passo di compilazione una sola volta, la prima, e poi di aggiornarne i valori in seguito:</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003399;">PreparedStatement</span> pstmt <span style="color: #339933;">=</span> conn.<span style="color: #006633;">prepareStatement</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">&quot;SELECT * FROM TABELLA WHERE CAMPO = ?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003399;">Iterator</span> ricerca <span style="color: #339933;">=</span> lista.<span style="color: #006633;">iterator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>ricerca.<span style="color: #006633;">hasNext</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp;pstmt.<span style="color: #006633;">setString</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span>ricerca.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">ResultSet</span> rs <span style="color: #339933;">=</span> pstmt.<span style="color: #006633;">executeQuery</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>rs.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Get results</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">//...</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p style="text-align: justify;">Questo si concretizza in un miglioramento delle performance, generalmente. Ciò non è sempre vero, ci sono altri fattori che entrano in gioco che possono rendere uno Statement più veloce di un PreparedStatement. A mio avviso anche se fosse, una leggera diminuzione di performance (che dipende moltissimo dal database utilizzato) per il PreparedStatement è sicuramente ben accetta data la sua grande flessibilità. Non solo, dalle <a title="Oracle - PreparedStatement vs Statment" href="http://www.oracle.com/technology/tech/java/sqlj_jdbc/htdocs/jdbc_faq.html#35_02" target="_blank">FAQ Oracle</a> ho appreso anche che ci sono dei benefici in termini di sicurezza nell&#8217;utilizzo di PreparedStatement: il binding dei dati, infatti, eviterebbe un considerevole numero di attacchi di tipo SQL Injection. La FAQ infatti riporta:</p>
<blockquote>
<p style="text-align: justify;"><em>&#8220;Statements may be slightly faster if you are only going to execute the SQL once. PreparedStatements are much faster when the SQL will be executed more than once. If you are using the statement cache, which you should, getting a statement from the cache is the same as executing the same statement.</em></p>
<p><em>In general we strongly recommend that you use PreparedStatements. This is especially true if you are sending user provided data in the SQL. By binding the data to a PreparedStatement parameter you can prevent most SQL injection attacks. Any performance advantage of using Statements is negligible.&#8221;</em></p></blockquote>
<p style="text-align: justify;">Insomma, per i miei gusti, non c&#8217;è motivo di usare Statement e PreparedStatement è la classe vincente.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fabiofalcinelli.it/2009/01/statement-vs-preparedstatement/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Java &#8211; Esecuzione comandi su CLI</title>
		<link>http://www.fabiofalcinelli.it/2009/01/java-esecuzione-comandi-su-cli/</link>
		<comments>http://www.fabiofalcinelli.it/2009/01/java-esecuzione-comandi-su-cli/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 20:50:49 +0000</pubDate>
		<dc:creator>Fabio</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://fabiofalcinelli.netsons.org/?p=85</guid>
		<description><![CDATA[Prima o poi può essere utile astrarre un po&#8217; meno dalla macchina e tornare a interfacciarsi con il Sistema Operativo sottostante. Quello che può tornare utile è quindi un metodo per eseguire comandi di sistema dalla VirtualMachine Java. Il seguente è un metodo che ho scritto in fretta e furia, ma che su sistemi UNIX [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Prima o poi può essere utile astrarre un po&#8217; meno dalla macchina e tornare a interfacciarsi con il Sistema Operativo sottostante. Quello che può tornare utile è quindi un metodo per eseguire comandi di sistema dalla VirtualMachine Java. Il seguente è un metodo che ho scritto in fretta e furia, ma che su sistemi UNIX sembra funzionare molto molto bene:</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> execCommand<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> cmd<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">String</span> result <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">BufferedReader</span> stdout <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">BufferedReader</span> stderr <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">Runtime</span> runtime <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">Process</span> proc <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;runtime <span style="color: #339933;">=</span> <span style="color: #003399;">Runtime</span>.<span style="color: #006633;">getRuntime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;proc <span style="color: #339933;">=</span> runtime.<span style="color: #006633;">exec</span><span style="color: #009900;">&#40;</span>cmd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;stderr <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">BufferedReader</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">InputStreamReader</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; proc.<span style="color: #006633;">getErrorStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003399;">String</span> temp <span style="color: #339933;">=</span> stderr.<span style="color: #006633;">readLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">/*check if errors occurred*/</span><br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>temp<span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">do</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>result<span style="color: #339933;">==</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result <span style="color: #339933;">=</span> temp<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result <span style="color: #339933;">+=</span> temp<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;temp <span style="color: #339933;">=</span> stderr.<span style="color: #006633;">readLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>temp<span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; stderr.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IOException</span><span style="color: #009900;">&#40;</span>result<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">/*if no exceptions occurred then proceed to return the output*/</span><br />
&nbsp; &nbsp;stdout <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">BufferedReader</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">InputStreamReader</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;proc.<span style="color: #006633;">getInputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;temp <span style="color: #339933;">=</span> stdout.<span style="color: #006633;">readLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>temp<span style="color: #339933;">!=</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>result<span style="color: #339933;">==</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result <span style="color: #339933;">=</span> temp<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result <span style="color: #339933;">+=</span> temp<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; temp <span style="color: #339933;">=</span> stdout.<span style="color: #006633;">readLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; stdout.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">return</span> result<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p style="text-align: justify;">L&#8217;idea è semplice: se il comando fallisce, restituisco l&#8217;esito del comando (lo standard error) come un&#8217;eccezione di I/O, altrimenti il metodo torna l&#8217;esito del comando (lo standard output).</p>
<p style="text-align: justify;">A questo punto possiamo, per esempio, scrivere il seguente main, un po&#8217; inutile, ma rende l&#8217;idea</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> args<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">try</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003399;">String</span> result <span style="color: #339933;">=</span> execCommand<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ls -lrt&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>result<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #000000; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">err</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>e.<span style="color: #006633;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p style="text-align: justify;">Ovviamente il codice non è ottimizzato essendo la prima stesura di getto, alcune cose potevano essere evitate (i due BufferedReader per esempio), ma spero che a qualcuno questo metodo torni utile.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fabiofalcinelli.it/2009/01/java-esecuzione-comandi-su-cli/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle 10g &#8211; Upsert</title>
		<link>http://www.fabiofalcinelli.it/2009/01/oracle-10g-upsert/</link>
		<comments>http://www.fabiofalcinelli.it/2009/01/oracle-10g-upsert/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 12:03:07 +0000</pubDate>
		<dc:creator>Fabio</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Information Technology]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JDBC]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://fabiofalcinelli.netsons.org/?p=17</guid>
		<description><![CDATA[Recentemente mi è capitato di dover eseguire una insert or update, anche detta upsert, su Oracle 10g. Su MySQL ero solito usare la forma &#8220;INSERT &#8230; ON DUPLICATE KEY UPDATE &#8230;&#8221; che funziona piuttosto bene, ma che non era supportata dal database che stavo utilizzando. La versione 10g di Oracle, però, supporta l&#8217;operazione &#8220;MERGE&#8221;, entrata [...]]]></description>
			<content:encoded><![CDATA[<p>Recentemente mi è capitato di dover eseguire una <strong>insert or update</strong>, anche detta <strong>upsert</strong>, su Oracle 10g. Su MySQL ero solito usare la forma &#8220;INSERT &#8230; ON DUPLICATE KEY UPDATE &#8230;&#8221; che funziona piuttosto bene, ma che non era supportata dal database che stavo utilizzando.</p>
<p>La versione 10g di Oracle, però, supporta l&#8217;operazione &#8220;MERGE&#8221;, entrata a far parte dello standard SQL nel 2003, e si è rivelata molto comoda utilizzandola tramite JDBC.</p>
<p>Supponiamo di dover memorizzare in una tabella l&#8217;ultima pagina visitata da un utente in un dato giorno, possiamo utilizzare il seguente prepared statement java:</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003399;">PreparedStatement</span> pstmt <span style="color: #339933;">=</span> conn.<span style="color: #006633;">prepareStatement</span><span style="color: #009900;">&#40;</span><br />
<span style="color: #0000ff;">&quot;MERGE INTO last_page_table dst &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;USING ( &quot;</span><span style="color: #339933;">+</span><br />
<span style="color: #0000ff;">&quot;SELECT <span style="color: #000099; font-weight: bold;">\'</span>&quot;</span><span style="color: #339933;">+</span>username<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\'</span> USER_ID, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;TO_DATE(<span style="color: #000099; font-weight: bold;">\'</span>&quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">new</span> java.<span style="color: #006633;">sql</span>.<span style="color: #003399;">Date</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\'</span>YYYY-MM-DD') &nbsp;DATE_FIELD, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\'</span>&quot;</span><span style="color: #339933;">+</span>lastPage<span style="color: #339933;">+</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\'</span> LAST_PAGE &quot;</span><span style="color: #339933;">+</span><br />
<span style="color: #0000ff;">&quot;FROM DUAL) src &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;ON (dst.USER_ID = src.USER_ID AND &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;dst.DATE_FIELD = src.DATE_FIELD) &quot;</span><span style="color: #339933;">+</span><br />
<span style="color: #0000ff;">&quot;WHEN MATCHED THEN &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;UPDATE SET dst.LAST_PAGE = src.LAST_PAGE &quot;</span><span style="color: #339933;">+</span><br />
<span style="color: #0000ff;">&quot;WHEN NOT MATCHED THEN &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;INSERT (dst.USER_ID, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;dst.DATE_FIELD, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;dst.LAST_PAGE) &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; <span style="color: #0000ff;">&quot;VALUES (src.USER_ID, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;src.DATE_FIELD, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;src.LAST_PAGE)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>In sostanza, l&#8217;operazione &#8220;MERGE&#8221; funziona tra tabelle, prende i valori di una e li inserisce o aggiorna nell&#8217;altra in base al matching della condizione nella clausola &#8220;ON&#8221;.<br />
Tuttavia, la necessità non era di utilizzare valori preesistenti di una tabella ed inserirli o aggiornarli nell&#8217;altra, ma l&#8217;effettivo popolamento della tabella. Esigenza risolta appoggiandosi alla tabella &#8220;DUAL&#8221;.<br />
Ovviamente, invece di inserire direttamente nella stringa i valori necessari, si poteva utilizzare anche il &#8216;?&#8217; e chiamare poi le funzioni della classe PreparedStatement.</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003399;">PreparedStatement</span> pstmt <span style="color: #339933;">=</span> conn.<span style="color: #006633;">prepareStatement</span><span style="color: #009900;">&#40;</span><br />
<span style="color: #0000ff;">&quot;MERGE INTO last_page_table dst &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;USING ( &quot;</span><span style="color: #339933;">+</span><br />
<span style="color: #0000ff;">&quot;SELECT ? USER_ID, ? &nbsp;DATE_FIELD, ? LAST_PAGE &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;FROM DUAL) src &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;ON (dst.USER_ID = src.USER_ID AND &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;dst.DATE_FIELD = src.DATE_FIELD) &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;WHEN MATCHED THEN &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;UPDATE SET dst.LAST_PAGE = src.LAST_PAGE &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">&quot;WHEN NOT MATCHED THEN &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;INSERT (dst.USER_ID, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">&quot;dst.DATE_FIELD, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">&quot;dst.LAST_PAGE) &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">&quot;VALUES (src.USER_ID, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">&quot;src.DATE_FIELD, &quot;</span><span style="color: #339933;">+</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">&quot;src.LAST_PAGE)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div>
<p>Se non vi sono particolari necessità in termini di performance, sicurezza, flessibilità, in genere preferisco inserire tutto direttamente nella stringa in modo da poterla scrivere facilmente su un file di log prima di inviarla al driver:</p>
<div class="codecolorer-container java twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003399;">String</span> sqlMerge <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;MERGE INTO ...&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #003399;">PreparedStatement</span> pstmt <span style="color: #339933;">=</span> conn.<span style="color: #006633;">prepareStatement</span><span style="color: #009900;">&#40;</span>sqlMerge<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
logger.<span style="color: #006633;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Executing &quot;</span><span style="color: #339933;">+</span>sqlMerge<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
pstmt.<span style="color: #006633;">executeUpdate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fabiofalcinelli.it/2009/01/oracle-10g-upsert/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

