<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1079486184614702376</id><updated>2024-08-28T21:42:23.243-03:00</updated><category term="Django"/><category term="Cubesat"/><category term="Python"/><category term="DBExpress"/><category term="DataSnap"/><category term="Sql Server"/><category term="Delphi"/><category term="Telemetry"/><category term="tuning"/><category term="ISIS"/><category term="Test"/><category term="ASP.NET"/><category term="Console"/><category term="Delphi WebServices Certificados"/><category term="Eclipse"/><category term="Ground Segment"/><category term="Isis cubesat"/><category term="ORM"/><category term="Reflection"/><category term="Sniffer"/><category term="Sql Management Studio"/><category term="Sql Trace"/><category term="Telecommand"/><category term="Threads"/><category term="general purpose language"/><title type='text'>Desarrollo de software</title><subtitle type='html'>Blog dedicado al desarrollo de software con Delphi, C#, Django, SqlServer  y otras yerbas</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-3107471281188477143</id><published>2017-09-19T13:16:00.003-03:00</published><updated>2017-09-19T13:48:25.526-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cubesat"/><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Ground Segment"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><title type='text'>Formado Satelital 2017 (Comando, control y telemetría satelital de próxima generación)</title><content type='html'>&lt;h2 style=&quot;clear: both; text-align: center;&quot;&gt;
Formado Satelital 2017&lt;/h2&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
Este video es un resumen del trabajo realizado por la Maestría en Desarrollos Informáticos de Aplicación Espacial para el proyecto integrador. La maestría es dictada por el instituto Gulich (CONAE) y su socio académico la Universidad Nacional de La Matanza. Parte del trabajo es explicado en el post: &amp;nbsp;&lt;a href=&quot;https://www.youtube.com/watch?v=R34izsKnD90&quot; style=&quot;text-align: start;&quot; target=&quot;_blank&quot;&gt;Comando, control y telemetría satelital de próxima generación&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/R34izsKnD90/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/R34izsKnD90?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/3107471281188477143/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2017/09/formado-satelital-2017-este-video-es-un.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/3107471281188477143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/3107471281188477143'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2017/09/formado-satelital-2017-este-video-es-un.html' title='Formado Satelital 2017 (Comando, control y telemetría satelital de próxima generación)'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/R34izsKnD90/default.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-291169736361176276</id><published>2017-07-31T16:06:00.000-03:00</published><updated>2017-09-01T13:21:08.519-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cubesat"/><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="general purpose language"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="Telecommand"/><category scheme="http://www.blogger.com/atom/ns#" term="Telemetry"/><title type='text'>Comando, control y telemetría satelital de próxima generación</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: center;&quot;&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 12pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;I. Introducción&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;En la industria cuando se trata de comandar un equipo remoto existen varios enfoques dependiendo de las necesidades. Desde sencillas implementaciones Maestro-Esclavo sin ningún tipo lógica de control asociada, pasando por sistemas algo mas complejos donde se aplican restricciones o sistemas basados en maquinas de estado. En el área espacial, una práctica común, es el uso de secuencias de comandos sobre estructuras de control. Empresas y agencias espaciales en todo el mundo han desarrollados sus propios lenguajes e intérpretes para cumplir con este objetivo:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;STOL: Satellite Test and Operation Language. Desarrollado por la Nasa y ampliamente utilizado en varias misiones.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;PLUTO: presente en algunas misiones de la&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;ESA (Satellite Control and Operation Sys- tem 2000).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;Otros: desarrollados o utilizados por difer- entes compañias SOL(GMV), CCL(Harris), PIL(Astrium), SCL(ICS).&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify; text-indent: 9.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;En el caso del segmento terreno del FS2017 se optó por usar un lenguaje de propósito general en lugar de crear un lenguaje especifico o utilizar los existentes en la agencia espacial. Este enfoque presenta múltiples ventajas,&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;Portabilidad: escogiendo correctamente la herramienta se puede lograr una buena portabilidad entre distintas plataformas.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;Capacidad: las herramientas y capacidades generales de un buen lenguaje y entorno de desarrollo de propósito general su- peran ampliamente las posibilidades que puede ofrecer un entorno de propósito es- pecifico.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;Base de usuarios: una importante base de usuarios implica soporte, documentación y mejoras además de una base de posibles recursos ya capacitados.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify; text-indent: 9.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;En el caso de este proyecto  la opción de lenguaje propio de la misión se descartó por no disponer del tiempo que implica desarrollar y validar un intérprete de propósito específico. La opción de utilizar los interpretes disponibles en la agencia espacial quedó relegada por sobre la opción Python, con una base de usuarios mucho más grande, multiplataforma, con mejores capacidades de depuración, documentación disponible en la comunidad y de dominio de todos los estudi- antes.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;II. Arquitectura&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;La solución propuesta propuesta para el segmento terreno se basa en una arquitectura cliente-servidor estándar y está influenciada por el framework de desarrollo Django, el que también influyo en un análisis y diseño orientado a objetos. Como repositorio de datos se utiliza un Postgresql 9.0 donde se almacenan la definición de datos y los datos mismos. Todo el acceso se realiza mediante el ORM (Object Relational Mapping) y no hay en todo el software un acceso directo al motor. Los componentes de software son los siguientes:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;&lt;b&gt;Database server (1): &lt;/b&gt;Un servidor SQL Post- gres donde se almacenan telemetría, tele- comandos y sus definiciones para todas las misiones.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;&lt;b&gt;Application server (1):&lt;/b&gt; Un servidor de apli- cación responsable de la generación de interfaces y lógica de operación.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-weight: 700; line-height: 1.38; white-space: pre-wrap;&quot;&gt;Telemetry and Telecomand Processor (n): &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; text-indent: 0.48pt; white-space: pre-wrap;&quot;&gt;modulo encargado de decodificar, calibrar y transformar en variables de ingeniería la telemetría según su definición y de codificar y enviar los comandos al segmento de vuelo. En este caso existe un proceso por satélite incluso si son del mismo fabricante. Para el caso de FS2017&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq74s8AB82VJK00sL3I-55NHO671H5rLRxBznVPdJtrGr4sxtKb3glzCSPsTkanX_kYCH_7S8PB_uj0ZRFkkTvS3GJ1esAbMuNL-H-RotkIvuUNtyNSFrDKqUmAQ2npYCE7w97BtahSkuz/s1600/Arq01.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;657&quot; data-original-width=&quot;629&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq74s8AB82VJK00sL3I-55NHO671H5rLRxBznVPdJtrGr4sxtKb3glzCSPsTkanX_kYCH_7S8PB_uj0ZRFkkTvS3GJ1esAbMuNL-H-RotkIvuUNtyNSFrDKqUmAQ2npYCE7w97BtahSkuz/s320/Arq01.png&quot; width=&quot;306&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 12pt; line-height: 1.38; text-align: justify; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 12pt; line-height: 1.38; text-align: justify; white-space: pre-wrap;&quot;&gt;III. Python y Django&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Python es un lenguaje portable, abierto, de alto nivel. Es dinámico y tiene orientación a objetos no estricta (Permite programación estructurada). Concebido durante los 80 se pop- ularizó en los 90, muestra una performance superior a otros interpretes, producto de su código intermedio (bytecode). Además de la portabilidad, que no mostró ninguna fisura, su punto fuerte es la gran comunidad que brinda soporte y la buena integración con entornos de desarrollo como Eclipse. El lenguaje tiene buena productividad [3], estructuras complejas de datos ya incorporadas, manejo de excepciones, recolector de basura y capacidad de reflexión, mandatoria para cumplir con el obje- tivo. Otros beneficios de trabajar con Python, o con otro lenguaje maduro de propósito general, son las capacidades de depuración, los test unitarios y la generación de documentación automatizada. Este enfoque además permite pleno acceso a herramientas de comunicación como Sockets, http, RPC (Remote Procedure &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;Call), Web Services, email y a bibliotecas de manejo de archivos XML entre otros. Django es el framework web para python más popular, además de ofrecer herramientas para el desarrollo web incorpora un ro- busto ORM que se ha usado intensivamente en todos los módulos del segmento terreno, incluyendo los que no tienen interfaces web. Django propone un desarrollo basado en modelos, con una orientación a objetos estricta, pudiendo aprovechar las capacidades de abstracción, herencia, polimorfismo y las ventajas de un mejor modelo de reusabilidad. El acceso al motor de base de datos es transparente al de- sarrollador de la aplicación como al operador, ingeniero o equipo encargado de desarrollar los scripts de comandos, toda la responsabil- idad sobre la recuperación y persistencia de datos recae sobre el ORM.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;IV. Telemetría&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Si bien la arquitectura del segmento terreno es agnóstica de la fuente de datos se ha utilizado como segmento de vuelo el satélite denominado FS2017. El FS2017 envía la telemetría en tramas AX.25 por TCP/IP 1 puerto 3210 según especificación del fabricante. La trama tiene un fragmento de Payload donde viene codificada la telemetría. La definición de la telemetría esta persistida en una entidad (TlmyVarType) donde se establece el tipo, valor, rangos, límites, posición den- tro del fragmento de payload y la función que la transforma en una variable de ingeniería. En el área satelital y en algunos sistemas de control y automatización es común recibir la telemetría en valores crudos o raw. A estos val- ores crudos se les debe aplicar una función que los transforme en unidades de ingeniería. En algunas áreas, incluida la satelital, esta trans- formación también es utilizada para calibrar sensores o equipos que puedan sufrir desgaste o variaciones por las condiciones de uso. Estos ajustes pueden ir desde un simple ajuste por función lineal hasta una discretización de val- ores por tablas de look-up. El sistema debe ser lo suficientemente flexible como para permitir&lt;/span&gt;&lt;/div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8qrhyphenhyphenEMxjQRE5OcvSSxP3eejA6OqA0OuLo0ImOmkT-xrnbH0uTWaWBhRHGXK_AE1ulksf9HAgke6F4stHM_rxR4cB07erk1plyKmirpT6oC25p8aonFg0Upw3q1NUO4b1ZJigqqPnGkHx/s1600/TTCCalibracionDiscreta.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;295&quot; data-original-width=&quot;552&quot; height=&quot;171&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8qrhyphenhyphenEMxjQRE5OcvSSxP3eejA6OqA0OuLo0ImOmkT-xrnbH0uTWaWBhRHGXK_AE1ulksf9HAgke6F4stHM_rxR4cB07erk1plyKmirpT6oC25p8aonFg0Upw3q1NUO4b1ZJigqqPnGkHx/s320/TTCCalibracionDiscreta.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 12px; line-height: 16.56px; white-space: pre-wrap;&quot;&gt;Figure 2: Selección de método de calibración&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; text-align: justify; white-space: pre-wrap;&quot;&gt;aplicar cualquier función de transformación a toda variable de telemetría y permitir ajustarla a medida que el desgaste de los sensores lo requiera. La figura 2 muestra como al configurar una variable de telemetría se selecciona la función a aplicar para convertirla en variable de ingeniería.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify; text-indent: 9.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Mediante técnicas de reflexión se carga en tiempo de ejecución la función seleccionada de calibración y se le aplica al valor raw extraído de la trama de telemetría proveniente del pa- quete AX.25. La función de calibración puede ser cualquier secuencia de comandos program- able en python sin ningún tipo de restricción mas allá del tiempo de procesamiento. To- das las bibliotecas y estructuras de datos están disponibles incluyendo funciones matemáticas e incluso el acceso al la base de datos completa mediante ORM. Al tener acceso a la base de datos se pueden obtener coeficientes actualiza- dos de calibración permitiendo:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;Reutilizar funciones: es posible crear una única función para ajustes típicos (lineal, cuadrático) y reutilizarla con distintos co- eficientes según la variable de telemetría requiera.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;Calibración fina: creada una función modifi- cando los coeficientes se puede realizar un ajuste fino, por ejemplo por desgaste de un sensor, sin necesidad de recodificar la misma.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 9.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Como ejemplo, el segmento de vuelo FS2017 requiere que a muchos de sus valores crudos &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; text-align: justify; white-space: pre-wrap;&quot;&gt;se les aplique una ganancia (GAIN) y un de- splazamiento (OFFSET). En todos los casos se realiza mediante una única función llamada linealCalibration aunque cada tipo de variable de telemetría posea sus propios valores para ambos coeficientes.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify; text-indent: 9.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Para que un método sea considerado de calibración o ajuste debe estar desarrollado como método de una clase heredada de BaseCalibration. El software realiza periódicamente una exploración de todos los métodos públicos de clases derivadas de BaseCalibration y los disponibiliza para su aplicación a las distintas variables de telemetría 2. La figura 6 muestra la clase GCalibration, heredada de BaseCalibration, donde se implementan algunos métodos de calibración incluido el seleccionado en la figura 2.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.calibrationLogic(self.tmlyVarType, raw )&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;elif self.tmlyVarType.varType==self.tmlyVarType.FLOAT:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.lastCalFValue =&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 15.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.calibrationLogic(self.tmlyVarType, raw ) else:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.lastCalSValue =&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 21.12pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.calibrationLogic(self.tmlyVarType, raw ) else:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;if self.tmlyVarType.varType==self.tmlyVarType.INTEGER:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 10.56pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.lastCalIValue = raw elif self.tmlyVarType.varType==self.tmlyVarType.FLOAT:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 10.56pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.lastCalFValue = raw else:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.lastCalSValue = raw&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: #ba2121; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&quot;&quot;&quot; Si el tipo no es cadena llevo el dato a cadena &quot;&quot;&quot; value = self.tmlyVarType.getValue()&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;if self.tmlyVarType.varType!=self.tmlyVarType.STRING: if (value&amp;gt;=self.tmlyVarType.limitMaxValue and&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;value&amp;lt;=self.tmlyVarType.limitMinValue): raise Exception(&quot;Invalid value in var &quot;+&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.code)&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;if saveifchange:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.lastUpdate = datetime.now(utc) self.tmlyVarType.save()&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;if self.tmlyVarType.varType==self.tmlyVarType.INTEGER:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.calIValue = self.tmlyVarType.lastCalIValue self.calSValue = str(self.calIValue) elif self.tmlyVarType.varType==self.tmlyVarType.FLOAT:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.calFValue = self.tmlyVarType.lastCalFValue self.calSValue = str(self.calFValue) else:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.calSValue = self.tmlyVarType.lastCalSValue&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;return self.tmlyVarType.getValue()&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify; text-indent: 9.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Cuando se recibe un nuevo valor de telemetría se persiste mediante una instancia de TlmyVar. Toda recepción de nueva telemetría se registra en el histórico, haya cam- biado o no su valor. También se deja el último valor en la variable TlmyVarType, esta desnormalización tiene como objetivo ganar eficiencia al consultar los valores de tiempo real. En lugar de consultar a la tabla de histórica de valores recibidos, se consulta a la tabla de tipos que tiene un tamaño acotado. Si el valor raw para una variable determinada no cam- bió desde la ultima actualización entonces se guarda el registro de la recepción pero no se aplican las calibraciones. Esto ultimo hace ganar eficiencia ya que no se vuelve a transformar cuando se sabe que el resultado sera el mismo, se debe tener en cuenta, sin embargo, que ante un cambio en las funciones de calibración se debe forzar mediante software a una nueva evaluación aunque el raw no haya cambiado.&lt;/span&gt;&lt;/div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj11RnFsDeRWOHAzgXyv5o5OyjN-0haERS9if2CVyKpALfp0-MemmkssK2Go97LUCKFnn4qdOPxdMCDqWFkomhNha2drueKrfme4tMN-IeT3m_j-cdIqfwEvMbV_guBZkQtEaVJoOWy9eS8/s1600/TelemetryVarType.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;756&quot; data-original-width=&quot;205&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj11RnFsDeRWOHAzgXyv5o5OyjN-0haERS9if2CVyKpALfp0-MemmkssK2Go97LUCKFnn4qdOPxdMCDqWFkomhNha2drueKrfme4tMN-IeT3m_j-cdIqfwEvMbV_guBZkQtEaVJoOWy9eS8/s320/TelemetryVarType.png&quot; width=&quot;86&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-size: medium; line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: start;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 9pt; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Figure 3: Clase Tlmy&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 9pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;VarType&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 9pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvPjF59DPQd_4z_uULPKB2vRICXKKnPBeEdhf-w7eOSz5nhnsBvsQM0LOzidMZxyUfZjWAIrCdy_KJe-MjmnDYs0n8VAt0LG6Rv3Wjl1lep-k7AqS5ClE0kdds2nGNh2gnQYuh9d1_wezA/s1600/CommandType.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;375&quot; data-original-width=&quot;242&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvPjF59DPQd_4z_uULPKB2vRICXKKnPBeEdhf-w7eOSz5nhnsBvsQM0LOzidMZxyUfZjWAIrCdy_KJe-MjmnDYs0n8VAt0LG6Rv3Wjl1lep-k7AqS5ClE0kdds2nGNh2gnQYuh9d1_wezA/s320/CommandType.png&quot; width=&quot;205&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-size: medium; line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: start;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 9pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;Figure 4: Clase Com&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 9pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;mandType&lt;/span&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 9pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 9pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify; text-indent: 10.32pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;El siguiente código muestra parte de la implementación del método setValue de la clase TlmyVar.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;class TlmyVar(models.Model):&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;... if raw!=self.tmlyVarType.lastRawValue:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.lastRawValue = raw if self.tmlyVarType.calibrationMethod:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;if not self.tmlyVarType.calibrationLogic:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;klass =&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 5.28pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;globals()[self.tmlyVarType.calibrationMethod.aClass] instance = klass() methodToCall =&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;getattr(instance,&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 21.12pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.calibrationMethod.aMethod) self.tmlyVarType.calibrationLogic =&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 21.12pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;methodToCall else:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: #408080; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;pass #Calibracion ya cargada&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;if self.tmlyVarType.varType==self.tmlyVarType.INTEGER:&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.lastCalIValue =&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;self.tmlyVarType.calibrationLogic solo si no fue cargada anteriormente.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify; text-indent: 9.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;La carga del método de calibración a una atributo del tipo de variable de telemetría se realiza, si no ocurren cambios, una única vez durante la ejecución. Esto también permite mejorar los tiempos de ejecución ya que evita la carga por cada valor de telemetría recibido. Con una frecuencia configurable, el software analiza si alguna función de calibración fue ac- tualizada, si asi ocurriera se procede al limpiar el atributo que contiene la función para forzar su recarga 3. La figura 5 muestra los tiempos de procesamiento para un bloque de 15 pa- quetes donde se decodifican 5000 variables de telemetría, cantidad compatible con un satélite científico de envergadura.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify; text-indent: 9.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;La primera decodificación demora mas que las siguientes dado que tiene que realizar la carga de las funciones de transformación. La primera telemetría recibida difiere de la ante- rior y al ser la primera calibración la función no esta precargada. Luego el tiempo se estabiliza entre 3 y 3.5 segundos para el conjunto de las 5000 variables con una probabilidad de cambio de 10% entre muestra y muestra. El tiempo de procesamiento incluye además la verificación de que los valores de las variables de ingeniería estén dentro del rango de seguridad y el alma- cenamiento en el histórico. Los pruebas han sido realizadas en maquinas virtuales sobre equipos de escritorio.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 9.84pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;El siguiente código muestra una calibración lineal (que puede ser usada en muchas tipos &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 13.3333px; line-height: 18.4px; white-space: pre-wrap;&quot;&gt;de variable de telemetría) y que obtiene sus coeficientes utilizando el ORM.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 9pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisabzxbP6_ljEO9H0wgPaf4XBsOcgz-rVLET_q-TfnJt-cAHJsothPZh3T4csqyuDDcj-LBY3VsxfFcQrTgNFjoFsTZMpCHUT7QnqnEM1j2qGhqlot-fbpXAFPKgCb9abUgscmUAKYkNls/s1600/tiempoDecodificacion.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;362&quot; data-original-width=&quot;662&quot; height=&quot;348&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisabzxbP6_ljEO9H0wgPaf4XBsOcgz-rVLET_q-TfnJt-cAHJsothPZh3T4csqyuDDcj-LBY3VsxfFcQrTgNFjoFsTZMpCHUT7QnqnEM1j2qGhqlot-fbpXAFPKgCb9abUgscmUAKYkNls/s640/tiempoDecodificacion.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 12px; line-height: 16.56px; white-space: pre-wrap;&quot;&gt;Figure 5: Tiempo de decodificación&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: #408080; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;#Clase GCalibration hereda de BaseCalibration class GCalibration(BaseCalibration):&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: #666666; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;...&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;#Metodo generico de calibración lineal def linealCalibration(self, obj, raw):&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: #408080; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;#Multiplica el valor raw por la ganancia y #offset configurado para ese tipo de #de variable de ingeniería. Los obj tiene #el tipo de variable de ingeniería y #por medio del ORM se accede a los #valores configurados. return raw*&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;obj.coefficients.get(code=&quot;GAIN&quot;).value + obj.coefficients.get(code=&quot;OFFSET&quot;).value&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;V. Telecomandos&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;En el caso del FS2017 los telecomandos deben ser enviados al segmento de vuelo por el mismo canal en donde se recibe la telemetría, TCP/IP puerto 3210. Los comandos deben ser codificados en una trama AX.25. Para permitir el la creación de scripts de comandos, de la misma forma que con la telemetría IV se utilizaran las capacidades de reflexión para analizar, en tiempo de ejecución los scripts a ejecutar. Los scripts de comandos pueden ejecutarse por acción explicita de un operador o porque fueron aplicados a una pasada. El operador tiene pleno acceso al ORM de donde se&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvir9fucgR0Z5QGpB4VpyXBQFihJbfaqrz9AfWntkszSHT2naB133Df_MJb9C_pzxQQupTW9IeQFyrW9OssKITsbiM4b46QTajD0GDS5E55tf16dZ62LUBnE1kdMHNjQxzRKOr4PHFzWji/s1600/GenericCalibration.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;485&quot; data-original-width=&quot;212&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvir9fucgR0Z5QGpB4VpyXBQFihJbfaqrz9AfWntkszSHT2naB133Df_MJb9C_pzxQQupTW9IeQFyrW9OssKITsbiM4b46QTajD0GDS5E55tf16dZ62LUBnE1kdMHNjQxzRKOr4PHFzWji/s320/GenericCalibration.png&quot; width=&quot;139&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 12px; line-height: 16.56px; white-space: pre-wrap;&quot;&gt;Figure 6: GCalibration&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;puede obtener el diccionario de comandos y los valores de telemetría si necesitara aplicar condicionales que dependieran del estado del segmento de vuelo u otro valor disponible en el sistema. El siguiente código muestra como se envía un comando de encendido de heater si la temperatura de la OBC esta por debajo de un valor determinado.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;#Instancio el satélite FS2019 sat = Satellite.objects.get(code=&quot;FS2019&quot;) ...&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;if not sat.isConnected():&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: #ba2121; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;raise Exception(&quot;Abort, flight segment offline&quot;)&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: #408080; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;#Consulto si la temperatura de la OBC esta por #debajo de 10 grados y tambien #Verifico que el heater este apagado if(sat.tmlyVarType.get(code=&quot;obcT1&quot;).getValue()&amp;lt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;sat.parameters.get(code=&quot;MinTolOBCTemp&quot;)) and (sat.tmlyVarType.get(code=&quot;HeaterOn&quot;).getValue()&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;==False):&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: #408080; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;#Creo un nuevo comando para el satelite, con fecha #de vencimiento 5 minutos desde la #fecha de creación. #Es un comando de ejecución en tiempo real #y por tanto no se agrega un tercer parametro #de fecha de ejecución cmd = sat.SendRTCommand(&quot;HeaterTurnOn&quot;,&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;datetime.utcnow()+ timedelta(minutes=5))&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-indent: 10.32pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Por consola se obtiene el satélite con el que se desea trabajar. Se consulta por la temperatura de la OBC mediante una lectura del valor en tiempo real de la variable de telemetría obcT1. Si ese valor es inferior a limite parametrizado (El método getValue() siempre retorna variable de ingeniería) y los heaters esta apagados entonces se envía un comando de encendido. Sentencias como sat.tmlyVarType.get(code=&quot;obcT1&quot;).getValue() que retornan la instancias de TlmyVarType son provistas por el ORM de django a pesar de ser utilizadas por consola.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;VI. Resultados&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;i. Interprete y Framework de desarrollo&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify; text-indent: 0.48pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;El lenguaje (python) es sencillo aprender, pero por sobre todo, esta disponible una extensa comunidad con ayudas ante los problemas o &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; white-space: pre-wrap;&quot;&gt;desafíos que puedan aparecer. Para las posibles limitaciones es fácil encontrar soluciones alternativas (workarounds). Las experiencias realizadas con lenguajes de propósito especifico requirieron de la asistencia constante de un experto. Trabajando sobre python esto no fue necesario y la mayoría de los problemas pueden ser resueltos mediante información disponible en la comunidad. Las herramientas de depuración y análisis se mostraron poderosas, incluso superando las expectativas. Como contrapartida el hecho de ser un lenguaje dinámico limita las capacidades de Code Insight/IntelliSense que el entorno de desarrollo puede ofrecer (comparando con lenguajes compilados) aunque sigue superando las capacidades que la mayoría de las herramientas propietarias tiene al alcance ofrece.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;ii. Desarrollo multiplatafoma&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;La solución fue ejecutada en ubuntu linux 15.10 como en windows 10.0 y windows 7.0. Se re- alizaron pruebas sobre dispositivos físicos y virtuales. En todos casos el software se ejecuto sin cambios. En este punto tanto el interprete como el framework mostraron uno de sus atributos mas destacables.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;iii. ORM&lt;/span&gt;&lt;/div&gt;
&lt;span id=&quot;docs-internal-guid-cec63370-3def-131b-d5d2-dda09ddc3f79&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;El ORM de Django se mostró estable, se registraron pocos problemas o bugs y cuando ocurrieron se encontró información disponible que lo documentaba. Para la creación y modificación de modelos, su flujo divido en dos etapas  Make Migrations y Migrate permitió el trabajo colaborativo y con múltiples servidores. El acceso a datos requiere de la práctica de convenciones propias que, aunque muy bien documentadas, afectan la curva de aprendizaje por poseer particularidades propias de la filosofía de convención por sobre configuración (Convention over configuration/coding by convention). Por otro lado el modelo no acepta atributos privados, cuestión que afecta el encapsulamiento. &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; text-indent: 0.48pt; white-space: pre-wrap;&quot;&gt;La capacidad del ORM para trabajar con polimorfismo esta limitada y se requiere añadir paquetes especiales, este últimos puntos se pueden considerar como una limitación de relevancia.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; text-indent: 0.48pt; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;iv. Reflexión&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span id=&quot;docs-internal-guid-cec63370-3e39-2a90-fe5d-9b39b9cbd6b6&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Quizá por ser un lenguaje híbrido y su definición algo mas antigua, se juzga a los mecanismos de reflexión disponibles en python mas complejos que los disponibles en otras herramientas como C#.Net. Estos, sin embargo, fueron suficientes para cumplir el objetivos. Los tiempos de respuesta no presentan una limitación a su implementación. La reutilización de métodos previamente cargados colabora en mantener los tiempos entre margenes aceptables.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;VII. Discusión&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Los lenguajes específicos del sector espacial fueron creados hace décadas. Durante los 70, si bien existían opciones interpretadas , están no eran de uso extendido. En la actualidad existen varias opciones con una amplia cantidad de usuarios de base y múltiples proyectos que avalan su robustez. Python, Perl, VB- Script, JavaScript son solo algunas opciones. Incluso la técnica aplicada en este trabajo es implementable, con algunas restricciones, en lenguajes compilados, siempre y cuando ten- gan capacidades de reflexión avanzadas. Java o C#, herramientas que generan código interme- dio son aplicables así como compilados puros. Delphi mediante su RTTI (Run-time type information) para citar un ejemplo, requeriría que los métodos de calibración sean compilados previamente para luego ser cargados dinámica- mente como complementos o plug-ins durante la ejecución del modulo principal. A esta op- ción se la juzga mas compleja y si bien puede ofrecer mejoras en cuanto a rendimiento, los resultados, como los mostrados en 5, no justifi- can su implementación. Las opciones amplia- mente probadas de la actualidad no justifican el desarrollo de un lenguaje propietario, no&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span id=&quot;docs-internal-guid-cec63370-3e39-ae86-2ace-ecb1c3d7fe34&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;tener una base de usuarios implica ausencia de documentación, soporte, herramientas y por sobre todo recursos como explica [4] refiriéndose a ADA. “Using Ada could potentially offer lower life cycle costs compared to other programming languages, but it seems more likely that using Ada would raise life cycle costs due to a dearth of tools and compilers and lack of trained, experienced programmers”. La creación de una herramienta propietaria limita las capacidades disponibles en términos de es- tructuras de datos y bibliotecas en general y obliga a su desarrollo con el costo que esto conlleva y su aprendizaje resta mucho valor al ser inaplicable por fuera del ámbito donde se implemente.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 12pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Referencias&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;[1] Garcia, Gonzalo, Use of Python as a Satel- lite Operations and Testing Automation Lan- guage, GSAW2008 Conference, Redondo Beach, California, 2008.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;[2] Galal, Ken and Hogan, Roger P, Satellite Mission Operations Best Practices, Space op- erations and support technical committe american institute of aeronautics and as- tronautics, 2001.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;[3] Prechelt, Lutz, An empirical comparison of&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;seven programming languages, IEEE, 2000.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span id=&quot;docs-internal-guid-cec63370-3e3a-e958-4b89-101f1c2933ee&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;[4] Smith, II and others, What About Ada? The State of the Technology in 2003, Software Engineering Institute, 2003.&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;background-color: transparent; color: black; font-family: &amp;quot;times&amp;quot;; font-size: 10pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; text-indent: 0.48pt; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.38; margin-bottom: 5pt; margin-top: 0pt; text-align: justify;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; text-indent: 0.48pt; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;times&amp;quot;; font-size: 10pt; line-height: 1.38; text-indent: 0.48pt; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/291169736361176276/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2017/07/satellite-command-telemetry-and-control.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/291169736361176276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/291169736361176276'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2017/07/satellite-command-telemetry-and-control.html' title='Comando, control y telemetría satelital de próxima generación'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq74s8AB82VJK00sL3I-55NHO671H5rLRxBznVPdJtrGr4sxtKb3glzCSPsTkanX_kYCH_7S8PB_uj0ZRFkkTvS3GJ1esAbMuNL-H-RotkIvuUNtyNSFrDKqUmAQ2npYCE7w97BtahSkuz/s72-c/Arq01.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-5559549864541157531</id><published>2017-05-23T10:18:00.001-03:00</published><updated>2017-05-30T13:09:53.147-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cubesat"/><category scheme="http://www.blogger.com/atom/ns#" term="ISIS"/><category scheme="http://www.blogger.com/atom/ns#" term="Telemetry"/><title type='text'>ISIS cubesat Telemetry (Part 2)</title><content type='html'>&lt;h2&gt;
Introduccion:&lt;/h2&gt;
&lt;div&gt;
En la parte uno de esta entrada&amp;nbsp;&lt;a href=&quot;http://pablosoligo.blogspot.com.ar/2017/05/isis-cubesat-telemetry-part-1.html&quot; target=&quot;_blank&quot;&gt;ISIS Cubesat Telemetry (Part 1)&lt;/a&gt;&amp;nbsp;explicamos brevemente algunas particularidades de la telemetría en el área satelital. Encontramos un XML que describía parcialmente los paquetes que llegan del satelite por TCP/IP y decimos parcialmente porque en la practica si intentamos desempaquetar la trama utilizando unicamente el XML el proceso falla.&lt;/div&gt;
&lt;div&gt;
La razón es que ese XML describe el paquete (packet) de una trama mayor que viene dada de la siguiente manera.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_DsRQVk8nfPOsO0l-q4A5hunhEBeAb9Em1eZT0VQ3ON0fK5wynWgtgmQJr5U_FfV6OliJT1GCVPJ2gwywrErdMCglQLQVNkyTLvKTE0bgWTLKo2p7px9t3z9ndDeMyOd90ByyilYPeesN/s1600/ISISFRAME.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;178&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_DsRQVk8nfPOsO0l-q4A5hunhEBeAb9Em1eZT0VQ3ON0fK5wynWgtgmQJr5U_FfV6OliJT1GCVPJ2gwywrErdMCglQLQVNkyTLvKTE0bgWTLKo2p7px9t3z9ndDeMyOd90ByyilYPeesN/s320/ISISFRAME.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
En las siguientes lineas vamos a desarmar completamente la trama hasta llegar a las variables de telemetria.&lt;br /&gt;
Primero establecemos hasta donde nos es posible posición y tamaño de las cosas. Como se observa en la tabla 7.1 existen campos de tamaño variable (Ejemplo: modulation name con tamaño indicado por modulation name length) que impiden presetear todo de antemano.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: python&quot;&gt;PosFrameCommand &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = 0

LenFrameCommand &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = 1

&amp;nbsp; &amp;nbsp;

PosFrameLen &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = PosFrameCommand+LenFrameCommand

LenFrameLen &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = 4

&amp;nbsp; &amp;nbsp;

PosDataRate &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = PosFrameLen+LenFrameLen

LenDataRate &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = 4

&amp;nbsp; &amp;nbsp;

PosModuluationNameLen &amp;nbsp; = PosDataRate+LenDataRate

LenModuluationNameLen &amp;nbsp; = 1

&amp;nbsp; &amp;nbsp;

PosModulationName &amp;nbsp; &amp;nbsp; &amp;nbsp; = PosModuluationNameLen+LenModuluationNameLen

LenModulationName &amp;nbsp; &amp;nbsp; &amp;nbsp; = 0

&amp;nbsp; &amp;nbsp;

PosRSSI &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = PosModulationName+LenModulationName

LenRSSI &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = 8

&amp;nbsp; &amp;nbsp;

PosFrequency &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= PosRSSI+LenRSSI

LenFrequency &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= 8

&amp;nbsp; &amp;nbsp;

PosPktLen &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = PosFrequency+LenFrequency

LenPktLen &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = 2

&lt;/pre&gt;
&lt;br /&gt;
Luego en un bucle infinito desarmamos los paquetes que van llegando hasta llegar al payload que es lo que nos interesa. Esta variable es la que en futuras entradas vamos a desarmar en función del xml de configuración. Por lo pronto el siguiente código recibe en un bucle infinito la trama (chunk) del socket y la desarma hasta llegar al payload, el código tiene una breve descripción de lo que hace antes de cada linea y se puede observar que el mismo es no bloqueante porque por el mismo canal debe enviarse los comandos....&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: python&quot;&gt;s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:

&amp;nbsp; &amp;nbsp; s.connect( (uhfServerIp, int(uhfServerPort)) )

&amp;nbsp; &amp;nbsp; print(&quot;Successfully connection to..&quot;, uhfServerPort)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; while True:

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; try:

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Establezco un timeout para la bajada, con o sin bajada los comandos deben ser enviados

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; s.settimeout(5.0)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Me quedo esperando recibir informacion del socket (IPC)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; chunk = s.recv(int(BUFFER_SIZE))

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; unconnectionLimit = 0

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Buena o mala la telemetria fue recibida, reseteo el watchdog

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; wd.reset()

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Si recibo telemetria, defenitivamente estoy en contacto

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; sat.setInContact(True)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Si la informacion es una trama de bits completa la proceso

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if chunk == b&#39;&#39;:

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; raise RuntimeError(&quot;socket connection broken&quot;)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else:

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; os.system(&#39;cls||clear&#39;)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; print(bcolors.OKGREEN+&quot;--------------------Data Received-------------------&quot;+bcolors.OKGREEN)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; print(&quot;Data length:&quot;, len(chunk))

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; #Me guardo el crudo tal cual llego antes de procesarlo, la tabla donde se guarda es UHFRawData


&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; data = UHFRawData()

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; data.source = source

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; data.data = chunk

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; data.processed = False

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; data.save()

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; framecommand = unpack(&quot;&amp;lt;B&quot;,chunk[PosFrameCommand:PosFrameCommand+LenFrameCommand])[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; frameLength &amp;nbsp;= unpack(&quot;&amp;lt;I&quot;,chunk[PosFrameLen:PosFrameLen+LenFrameLen])

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; datarate &amp;nbsp; &amp;nbsp; = unpack(&quot;&amp;lt;I&quot;,chunk[PosDataRate:PosDataRate+LenDataRate])

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; modulationnamelen = (unpack(&quot;&amp;lt;B&quot;,chunk[PosModuluationNameLen:PosModuluationNameLen+LenModuluationNameLen]))[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; modulationname &amp;nbsp; &amp;nbsp;= chunk[PosModulationName:PosModulationName+modulationnamelen]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PosRSSI &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = PosModulationName+modulationnamelen

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; rssi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= unpack(&quot;&amp;lt;d&quot;, chunk[PosRSSI:PosRSSI+LenRSSI])

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PosFrequency &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= PosRSSI+LenRSSI

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; freq &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= unpack(&quot;&amp;lt;d&quot;, chunk[PosFrequency:PosFrequency+LenFrequency])

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PosPktLen &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = PosFrequency+LenFrequency

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pktLen &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = unpack(&quot;&amp;lt;H&quot;, &amp;nbsp;chunk[PosPktLen:PosPktLen+LenPktLen])

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PosUtcTime = PosPktLen+pktLen[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; LenUtcTime = 4

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PosPayload = PosPktLen+int(LenPktLen)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ax25 = chunk[PosPayload:PosPayload+pktLen[0]]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; destination &amp;nbsp;= ax25[0:7]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; asource &amp;nbsp; &amp;nbsp; &amp;nbsp;= ax25[7:7+7]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; control &amp;nbsp; &amp;nbsp; &amp;nbsp;= ax25[7+7:7+7+1]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; protocol &amp;nbsp; &amp;nbsp; = ax25[7+7+1:7+7+1+1]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; vardataoffset = 7+7+1+1

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; payload = ax25[ vardataoffset: ]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pn = unpack(&quot;&amp;lt;H&quot;, &amp;nbsp;payload[1:3])

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; print(&quot;Packet number:&quot;, pn)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; frameTypeId = payload[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl = DownlinkFrame()

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.frameCommand &amp;nbsp; &amp;nbsp; = framecommand

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.frameLength &amp;nbsp; &amp;nbsp; &amp;nbsp;= frameLength[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.dataRate &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = datarate[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.modulationName &amp;nbsp; = str(modulationname)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.rssi &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; = rssi[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.frequency &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= freq[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.packetLength &amp;nbsp; &amp;nbsp; = pktLen[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.satellite &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;= sat

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.ax25Destination &amp;nbsp;= &quot;Pending&quot;#destination.decode(&quot;utf-8&quot;)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.ax25Source &amp;nbsp; &amp;nbsp; &amp;nbsp; = &quot;Pending&quot;#asource.decode(&quot;utf-8&quot;)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.ax25Protocol &amp;nbsp; &amp;nbsp; = &quot;Pending&quot;#protocol.decode(&quot;utf-8&quot;)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.ax25Control &amp;nbsp; &amp;nbsp; &amp;nbsp;= &quot;Pending&quot;#control.decode(&quot;utf-8&quot;)

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.packetNumber &amp;nbsp; &amp;nbsp; = pn[0]

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dl.frameTypeId &amp;nbsp; &amp;nbsp; &amp;nbsp;= frameTypeId

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;


&lt;/pre&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/5559549864541157531/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2017/05/isis-cubesat-telemetry-part-2.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/5559549864541157531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/5559549864541157531'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2017/05/isis-cubesat-telemetry-part-2.html' title='ISIS cubesat Telemetry (Part 2)'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_DsRQVk8nfPOsO0l-q4A5hunhEBeAb9Em1eZT0VQ3ON0fK5wynWgtgmQJr5U_FfV6OliJT1GCVPJ2gwywrErdMCglQLQVNkyTLvKTE0bgWTLKo2p7px9t3z9ndDeMyOd90ByyilYPeesN/s72-c/ISISFRAME.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-6016810915074061835</id><published>2017-05-14T16:02:00.000-03:00</published><updated>2017-05-30T13:16:57.373-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cubesat"/><category scheme="http://www.blogger.com/atom/ns#" term="ISIS"/><category scheme="http://www.blogger.com/atom/ns#" term="Telemetry"/><title type='text'>ISIS cubesat Telemetry (Part 1)</title><content type='html'>&lt;h2 style=&quot;text-align: left;&quot;&gt;
Introducción&lt;/h2&gt;
El los últimos meses estuve cursando una maestría en desarrollo software de aplicación espacial. Una de las asignaturas exige algunas practicas mínimas sobre un pequeño satélite. El satélite fue comprado hace algunos años por la agencia espacial donde se desarrollan las practicas, pero nunca había sido utilizado. El problema es que también había caducado el periodo de soporte y no teníamos documentación para nuestro primer objetivo que era procesar la telemetría de este diminuto satélite.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Telemetría vs Telemetría Satelital&lt;/h3&gt;
Se denomina telemetria a la medición y transmisión remota de magnitudes, físicas o lógicas. ¿Que diferencia hay entre la telemetría de cualquier equipo remoto y de un satélite? Las diferencias son muy pocas pero existen y son generadas por los siguientes problemas:&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
Eficiencia de la transmisión:&lt;/h4&gt;
En el area espacial existe un obsesión (Relativamente justificada) por el ahorro de bytes a transferir. Las capacidades y tiempos de transmisión son limitadas. El hardware en los sistemas de vuelo suele ser viejo, muy viejo o con limitaciones en términos de capacidad de computo. Esto se traduce en que pueden no ser aplicables técnicas de compresión o protocolos que utilicen exhaustivamente la lógica para reducir la cantidad de bytes como por ejemplo &amp;nbsp;&lt;a href=&quot;https://developers.google.com/protocol-buffers/&quot; target=&quot;_blank&quot;&gt;Google Protocols Buffers&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
Desgaste de componentes:&lt;/h4&gt;
Los componentes en el espacio sufren un desgaste y ya no es posible remplazarlos. Los valores de telemetria recibidos pueden estar modificados por ese desgaste y no representan el verdadero valor.&lt;br /&gt;
&lt;br /&gt;
Estas cuestiones definen y acotan el margen de acción, en contraste con el mundo informático actual donde nos damos el lujo de transferir por protocolos autocontenidos, de transferir texto, XML etc, acá se opta por trabajar, como antaño, con protocolos binarios &amp;nbsp;y los datos transferidos no representan el valor final de la variable que se pretende analizar tanto por la necesidad de reducir la cantidad de bytes transferidos al mínimo como la necesidad de ajustar los valores.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
RF checkout box&lt;/h4&gt;
Afortunadamente el kit del satélite disponía de un equipo de radio conectable a un PC por USB y un sencillo software de test que alcanzaba a mostrar algunos valores de telemetria. El manual indicaba que ese software publicaba la trama en un server TCP/IP pero no indicaba el formato completo de la trama. Con estos escasos recursos algunos compañeros comenzaron a decompilar los .class del software y llegaron a la conclusion de que utilizaba un XML para desarmar parte de la trama...buena parte del problema esta resuelto.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMtWJfbusvLXUdca5JdrAq59K-9wj0GvsFsLBDNnaK0eMYuvkxE_2UabGeJ3lmDmxQ5nUFWPC0PhLXpzVCPgddgFM9t722GAju4tvmLKrlnmEm2AGZnj0O_iNQd_eOf-eP7bg_IJCTUIcX/s1600/ISISXML.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;170&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMtWJfbusvLXUdca5JdrAq59K-9wj0GvsFsLBDNnaK0eMYuvkxE_2UabGeJ3lmDmxQ5nUFWPC0PhLXpzVCPgddgFM9t722GAju4tvmLKrlnmEm2AGZnj0O_iNQd_eOf-eP7bg_IJCTUIcX/s400/ISISXML.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
De un golpe de vista se entiende el formato de este paquete (o subpaquete). Por ejemplo, el frame type 1 es el de toda la telemetria (allTelemetry), esto viene indicado en un valor char en la posición 0. En la posición 8 tenemos la temperatura 1 de la OBC, viene en un short (2 bytes calculados a prueba y error) y offset y gain indican los valores por los que hay que multiplicar y sumar ese short para transformarlo en el valor real de temperatura Celsius.&lt;br /&gt;
Como dijimos&amp;nbsp;RF checkout box publica las tramas por un server TCP/IP puerto default 3210, si el satélite esta conectado y funcionando con conectarse al server se comienzan a recibir las tramas.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: python&quot;&gt; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 s.connect( (uhfServerIp, int(uhfServerPort)) )

 ...

 chunk = s.recv(int(BUFFER_SIZE))

&lt;/pre&gt;
&lt;br /&gt;
Sin embargo estas tramas contienen información de cabecera previa al paquete que describe el XML. Esto lo iremos desarmando en la&amp;nbsp;&lt;a href=&quot;http://pablosoligo.blogspot.com.ar/2017/05/isis-cubesat-telemetry-part-2.html&quot; target=&quot;_blank&quot;&gt;Parte 2&lt;/a&gt; (Part 2) de esta entrada.&lt;br /&gt;
&lt;br /&gt;
Continua en...&lt;a href=&quot;http://pablosoligo.blogspot.com.ar/2017/05/isis-cubesat-telemetry-part-2.html&quot; target=&quot;_blank&quot;&gt;Parte 2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/6016810915074061835/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2017/05/isis-cubesat-telemetry-part-1.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/6016810915074061835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/6016810915074061835'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2017/05/isis-cubesat-telemetry-part-1.html' title='ISIS cubesat Telemetry (Part 1)'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMtWJfbusvLXUdca5JdrAq59K-9wj0GvsFsLBDNnaK0eMYuvkxE_2UabGeJ3lmDmxQ5nUFWPC0PhLXpzVCPgddgFM9t722GAju4tvmLKrlnmEm2AGZnj0O_iNQd_eOf-eP7bg_IJCTUIcX/s72-c/ISISXML.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-7674955315326935615</id><published>2017-05-10T13:28:00.000-03:00</published><updated>2017-05-10T18:41:37.085-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Cubesat"/><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Isis cubesat"/><title type='text'>Misión Cubesat FS2017</title><content type='html'>La función del software del segmento terreno es la operación y mantenimiento del estado de salud del satélite (bajada y análisis de Telemetría -TM- y subida de Telecomandos
-TC) y la bajada, procesamiento y publicación
de datos de ciencia. A tal fin se ha estudiado el diseño y desarrollo de un SW multimisión que, ademas de contar con un alto nivel de robustez, posea atributos de generalidad que
permitan su aplicación a futuras misiones. &amp;nbsp;El sistema esta desarrollado sobre una arquitectura cliente-servidor clásica utilizando Python sobre el framework
Django, el cual fuerza el uso del paradigma orientado
a objetos y un diseño del tipo Model-Driven Architecture (MDA). La aplicación esta hosteada sobre apache en Linux Ubuntu 15.10.
El sistema intenta ser una alternativa a otros desarrollos
ad-hoc ofreciendo una variante multiplataforma
y multimisión que maximiza los
atributos de: interoperabilidad, eficiencia, accesibilidad/disponibilidad,
integridad, seguridad y
recuperación.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe height=&quot;960&quot; src=&quot;https://drive.google.com/file/d/0B7YyA6_ms1X_Q2RhV2V2ek5vcTZ2S2xscDkzUkZfMWN0UnhV/preview&quot; width=&quot;540&quot;&gt;&lt;/iframe&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/7674955315326935615/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2017/05/mision-cubesat-fs2017.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/7674955315326935615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/7674955315326935615'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2017/05/mision-cubesat-fs2017.html' title='Misión Cubesat FS2017'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-3384023728075358871</id><published>2016-09-22T12:21:00.002-03:00</published><updated>2016-09-22T12:21:38.066-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Eclipse"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="Test"/><title type='text'>Django: Test en eclipse</title><content type='html'>&lt;h2&gt;
El problema&lt;/h2&gt;
&lt;div&gt;
Ejecutar un test automático desde el eclipse sin necesidad de trabajar con una consola aparte. Existen librarias que mejoran el soporte a los test automáticos (seran tema de otro post), pero si no queremos llegar a tanto y pretendemos realizar la ejecución o, también imprescindible, el debug de algunos test no es tan directo como seleccionar simplemente Run As-&amp;gt;Python unit-test&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0Zwevi_CKM0pmUUVu1ocSTW_UkR3JBREdC6yW-jmHCkth-tkXCGW1uuBhx0pG_1cWhUAiyfx6aoSnb-i6VCjFKZXcGhKXR1ze2LKatXFl64zGI0gUrNTlTZTPjJRa0z-gQ8EZYKNM8lE/s1600/pic1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;136&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0Zwevi_CKM0pmUUVu1ocSTW_UkR3JBREdC6yW-jmHCkth-tkXCGW1uuBhx0pG_1cWhUAiyfx6aoSnb-i6VCjFKZXcGhKXR1ze2LKatXFl64zGI0gUrNTlTZTPjJRa0z-gQ8EZYKNM8lE/s640/pic1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Debería ser así, pero la realidad es que no funciona y obtendrán el mensaje...&lt;br /&gt;
&lt;br /&gt;
raise AppRegistryNotReady(&quot;Apps aren&#39;t loaded yet.&quot;)&lt;br /&gt;
django.core.exceptions.AppRegistryNotReady: Apps aren&#39;t loaded yet.&lt;br /&gt;
&lt;br /&gt;
Seguramente se ejecutan los unit-test sin antes cargar cuestiones básicas del ORM y demás, todavía no me queda claro porque.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2&gt;
La solución&lt;/h2&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Para resolver este tema, sin instalar librerias adicionales tenemos el siguiente workaround:&lt;br /&gt;
&lt;br /&gt;
1.Ir a Run Configurations...&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3UQo5zPDEnssXM51VwQyLb9zjI18-y4D06xt354G42_OxWNY0oU51SDTrimlqPXGqu9V2P7qFb3ZFKxmRdzZN0ic9ZM1WOpPZ60m2NjpRDwO7nPEN9TaGaIVenuOwzZbm_07VruliIiuW/s1600/pic0ed.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3UQo5zPDEnssXM51VwQyLb9zjI18-y4D06xt354G42_OxWNY0oU51SDTrimlqPXGqu9V2P7qFb3ZFKxmRdzZN0ic9ZM1WOpPZ60m2NjpRDwO7nPEN9TaGaIVenuOwzZbm_07VruliIiuW/s1600/pic0ed.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
2.Crear una nueva configuración de ejecución, &lt;b&gt;&lt;u&gt;muy importante estar parado sobre PyDev Django&lt;/u&gt;&lt;/b&gt; como indica la siguiente imagen.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin2iqMDHkQgk_Ap2kMMs9AzLzoSEpR_bvSl4lOKoP2YnZhi6n38km9ITGJ1rLIH-Ao-bQ-8kXDi9M_spGi0ZkNZG9_0BUzPoNReNsmChAODe9zcYC8zuAU6pRgQxR3S7xmYL5j8B9IGkuM/s1600/pic1ed.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;346&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin2iqMDHkQgk_Ap2kMMs9AzLzoSEpR_bvSl4lOKoP2YnZhi6n38km9ITGJ1rLIH-Ao-bQ-8kXDi9M_spGi0ZkNZG9_0BUzPoNReNsmChAODe9zcYC8zuAU6pRgQxR3S7xmYL5j8B9IGkuM/s640/pic1ed.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
3.Luego colocar un nombre descriptivo, tener en cuenta que esta es una configuración para correr test, luego seguramente necesitemos una para depurar, por tanto no esta demás indicar esta característica en el nombre&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZN-XtSNKQX0VwHlUlBJpoOO6wUQ0h_YUEGHs8IM3zwMF3t5DLxks8JDR6wN5_Y94i4MjIVsHbmQ1icVa_4UnZz8i5ct4uQ-jbvhwf4QCX2LPN-Lanpz-0fLran7O5MXvfEWCAKEYft5Sx/s1600/pic2ed.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;366&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZN-XtSNKQX0VwHlUlBJpoOO6wUQ0h_YUEGHs8IM3zwMF3t5DLxks8JDR6wN5_Y94i4MjIVsHbmQ1icVa_4UnZz8i5ct4uQ-jbvhwf4QCX2LPN-Lanpz-0fLran7O5MXvfEWCAKEYft5Sx/s640/pic2ed.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
4.Luego indicar para que proyecto estamos armando la configuración&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHxalNc7ruYrhDP37cvOkO8vpe4gHAuwIVwRIQihEFjPD2RoNHyUl5fARz9s0qNidJGh0iwbSeM5X5oUVP5AtgiHyiLInbqlvhzxmQUUMbMAuP64bXQljyOB1SXBbLQhO4kaVprfPmj4-f/s1600/pic3ed.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;354&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHxalNc7ruYrhDP37cvOkO8vpe4gHAuwIVwRIQihEFjPD2RoNHyUl5fARz9s0qNidJGh0iwbSeM5X5oUVP5AtgiHyiLInbqlvhzxmQUUMbMAuP64bXQljyOB1SXBbLQhO4kaVprfPmj4-f/s640/pic3ed.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
5.Indicar la ubicación del manage.py del proyecto&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOCdIwUAyjYIz8gX7KJ0KxWxBE0vZh_1w2aeNGlW3aBe3QLvfy3B-sMO89udqs4d2-q3wDsyYhXg-_4f14wwulaMfFmwp5uKUbps7KlUURStIE7YLlT9CSjafNPh7G7vr8YlB-3BFc4wB2/s1600/pic4ed.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;408&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOCdIwUAyjYIz8gX7KJ0KxWxBE0vZh_1w2aeNGlW3aBe3QLvfy3B-sMO89udqs4d2-q3wDsyYhXg-_4f14wwulaMfFmwp5uKUbps7KlUURStIE7YLlT9CSjafNPh7G7vr8YlB-3BFc4wB2/s640/pic4ed.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
6.En argumentos colocar la palabra &quot;test&quot;, como si lo hiciéramos por consola&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzA6i2mSHhvsJAvVBvsW7rvSL7KHuMAWqqqj9xlvzCsIp19PCrl_UtdttYve22gYqk3Apnkpu5LngDa3psaD86tcJAnuyZdkLNE7LefNdE-ohNk-jjA3o4tHn-YJBZRwHjVMYOdjHwTjHp/s1600/pic5ed.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;488&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzA6i2mSHhvsJAvVBvsW7rvSL7KHuMAWqqqj9xlvzCsIp19PCrl_UtdttYve22gYqk3Apnkpu5LngDa3psaD86tcJAnuyZdkLNE7LefNdE-ohNk-jjA3o4tHn-YJBZRwHjVMYOdjHwTjHp/s640/pic5ed.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
7.Salvar y ejecutar el test....&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHPmsKqaW5QW-gwiuOyRBHZUUh9B1MRmyncoI2Yk2qlUrY3SWJimEvp_OU_Ly2-M9mztQ7tSgc3CEM-VFMP5S3-a9I8iJqTxAiyhha7IUjBHpiPvtV-NURPSOzvkdiTr7N7wjFG59NXBwU/s1600/pic6ed.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;324&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHPmsKqaW5QW-gwiuOyRBHZUUh9B1MRmyncoI2Yk2qlUrY3SWJimEvp_OU_Ly2-M9mztQ7tSgc3CEM-VFMP5S3-a9I8iJqTxAiyhha7IUjBHpiPvtV-NURPSOzvkdiTr7N7wjFG59NXBwU/s640/pic6ed.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Para debug:&lt;/h3&gt;
&lt;br /&gt;
Para debug realizar los mismos pasos pero al utilizar el debug configuration en lugar del run configuration...&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRYNtErqgjttib7JrmSxDLiifFiqr9uUVmutv31tcgdpM8WA8NvQNwNPRjer_fiK41TUzOO1tHxsMA_dwgQpL9m7ck0v8RYDbialhpoz_-QTbI2FJpUBKVNxRpJ-JychQjitN27-HuX7UU/s1600/pic7ed.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;227&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRYNtErqgjttib7JrmSxDLiifFiqr9uUVmutv31tcgdpM8WA8NvQNwNPRjer_fiK41TUzOO1tHxsMA_dwgQpL9m7ck0v8RYDbialhpoz_-QTbI2FJpUBKVNxRpJ-JychQjitN27-HuX7UU/s400/pic7ed.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h2&gt;
Conclusion&lt;/h2&gt;
&lt;div&gt;
Rápidamente se puede acceder a los test automáticos sin necesidad de componentes de terceros y cuando se entiende la idea se configura muy rápido.&lt;/div&gt;
&lt;div&gt;
Espero haya servido.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/3384023728075358871/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2016/09/django-test-en-eclipse.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/3384023728075358871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/3384023728075358871'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2016/09/django-test-en-eclipse.html' title='Django: Test en eclipse'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0Zwevi_CKM0pmUUVu1ocSTW_UkR3JBREdC6yW-jmHCkth-tkXCGW1uuBhx0pG_1cWhUAiyfx6aoSnb-i6VCjFKZXcGhKXR1ze2LKatXFl64zGI0gUrNTlTZTPjJRa0z-gQ8EZYKNM8lE/s72-c/pic1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-5355531641983007222</id><published>2016-09-20T23:20:00.001-03:00</published><updated>2016-09-22T11:35:58.452-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="ORM"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="Sniffer"/><category scheme="http://www.blogger.com/atom/ns#" term="Sql Trace"/><title type='text'>Django: Log de consultas SQL</title><content type='html'>&lt;h2&gt;
El problema&lt;/h2&gt;
&lt;div&gt;
La verdad que en el poco tiempo que llevo jugando con Django no he tenido grandes problemas con código SQL generado automáticamente por el ORM de Django, y cuando tuve algun inconveniente el mensaje de error fue lo suficientemente descriptivo como para resolverlo sin mas.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
Esto no me hace creer que no pueden aparecer problemas un poco mas complejos y que no estaría de mas tener un buen registro de todo lo que el ORM esta ejecutando sobre el motor relacional. Tiempo atrás, trabajando con Delphi/DataSnap procuraba guardar toda consulta generada en un tabla para posterior analisis/auditoria. ¿Como hacer los mismo en Django?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2&gt;
La solución&lt;/h2&gt;
&lt;div&gt;
Yo no he pedido hacer en django que las consultas SQL se persistan en una tabla de la base de datos, pero al menos si que se guarden en un archivo del proyecto.&lt;/div&gt;
&lt;div&gt;
Tan simple como agregar la siguiente entrada en el settings.py&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
LOGGING = {&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &#39;version&#39;: 1,&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &#39;disable_existing_loggers&#39;: False,&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &#39;handlers&#39;: {&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;console&#39;: {&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;level&#39;: &#39;DEBUG&#39;,&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;class&#39;: &#39;logging.StreamHandler&#39;,&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;file&#39;: {&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;level&#39;: &#39;DEBUG&#39;,&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; #&#39;class&#39;: &#39;logging.FileHandler&#39;,&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;class&#39;: &#39;logging.handlers.RotatingFileHandler&#39;,&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;filename&#39;: os.path.join(BASE_DIR, &#39;logs/django.log&#39;), #&#39;/path/to/django/debug.log&#39;,&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;maxBytes&#39;: 16745#16777216, # 16megabytes&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; #&#39;formatter&#39;: &#39;verbose&#39;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; },&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &#39;loggers&#39;: {&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;django.db.backends&#39;: {&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;handlers&#39;: [&#39;file&#39;],&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &#39;level&#39;: &#39;DEBUG&#39;,&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; }&lt;/div&gt;
&lt;div&gt;
}&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Revisar tener la carpeta en el proyecto, en mi caso llamada logs.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2&gt;
Algunas pruebas&lt;/h2&gt;
&lt;div&gt;
Ahora para verificar vamos a realizar algunas pruebas por consola, si aun no sabes como hacerlo en eclipse te recomiendo un post anterior&amp;nbsp;&lt;a href=&quot;http://pablosoligo.blogspot.com.ar/2016/09/django-testeo-de-escritorio-sobre.html&quot; target=&quot;_blank&quot;&gt;Django: Testeo de escritorio sobre consola de eclipse&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Desde ORM:&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
Plato.objects.all()&lt;/div&gt;
&lt;div&gt;
[&amp;lt;Plato: Flan Casero&amp;gt;, &amp;lt;Plato: Omelette&amp;gt;, &amp;lt;Plato: Milanesa de soja&amp;gt;, &amp;lt;Plato: Tortilla&amp;gt;]&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Consulta SQL:&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
(0.001)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
SELECT &quot;djSisitia_plato&quot;.&quot;id&quot;, &quot;djSisitia_plato&quot;.&quot;descripcion&quot;, &quot;djSisitia_plato&quot;.&quot;tipo_id&quot;, &quot;djSisitia_plato&quot;.&quot;imagen&quot;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
FROM &quot;djSisitia_plato&quot; LIMIT 21; args=()&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Plato.objects.all().filter(tipo__descripcion=&quot;Postre&quot;)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
(0.000)&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
SELECT &quot;djSisitia_plato&quot;.&quot;id&quot;, &quot;djSisitia_plato&quot;.&quot;descripcion&quot;, &quot;djSisitia_plato&quot;.&quot;tipo_id&quot;, &quot;djSisitia_plato&quot;.&quot;imagen&quot;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
FROM &quot;djSisitia_plato&quot; INNER JOIN &quot;djSisitia_tipoplato&quot; ON (&quot;djSisitia_plato&quot;.&quot;tipo_id&quot; = &quot;djSisitia_tipoplato&quot;.&quot;id&quot;)&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
WHERE &quot;djSisitia_tipoplato&quot;.&quot;descripcion&quot; = &#39;Postre&#39;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
LIMIT 21; args=(&#39;Postre&#39;,)&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/5355531641983007222/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2016/09/django-log-de-consultas-sql.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/5355531641983007222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/5355531641983007222'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2016/09/django-log-de-consultas-sql.html' title='Django: Log de consultas SQL'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-860072632957853303</id><published>2016-09-20T19:45:00.001-03:00</published><updated>2016-09-22T11:36:15.585-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Console"/><category scheme="http://www.blogger.com/atom/ns#" term="Django"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="Test"/><title type='text'>Django: Testeo de escritorio/interactivo sobre consola de eclipse</title><content type='html'>&lt;h3 style=&quot;text-align: left;&quot;&gt;
Trabajar sobre la consola&lt;/h3&gt;
&lt;div&gt;
Seguramente para quienes tengan experiencia en lenguajes dinámicos este post les parecerá trivial, para quienes venimos del mundo de los lenguajes estáticos (En mi caso delphi, C++ o C#) la posibilidad de trabajar sobre una consola no esta contemplada, de hecho no existe la posibilidad y tampoco se me hubiese ocurrido como opción.&lt;/div&gt;
&lt;div&gt;
Siendo python un lenguaje dinámico técnicamente es posible y esta muy bien tener en mente esta idea porque compensa, al menos un poco, las penurias de no tener un compilador hecho y derecho&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h3&gt;
La idea general&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
Al trabajar sobre un lenguaje dinámico no tenemos un intelligent code completion decente, tenemos que trabajar mucho con la memoria y ser muy estrictos con la convenciones. Con todo, la memoria tiene limitaciones, la ide puede ayudar pero si tenemos la posibilidad de probar alguna implementacion sobre la marcha se agradece, y como se puede prever la consola lo permite probar ahí, en caliente.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
El ejemplo&lt;/h3&gt;
&lt;div&gt;
Para entender la idea imaginemos un ejemplo muy chico, un ejemplo mínimo de un software gastronómico donde se declara la clase&quot;Seleccion&quot;, el objeto de la clase puede contener una serie de platos pero no puede contener mas de un plato del mismo tipo, es decir, puede tener, entrada, plato principal, postre, merienda y tanto como se quiera siempre y cuando se cumpla que no existen 2 del mismo tipo (No se agrega al ejemplo la clase Plato, ni la clase TipoPlato, la cual indica su tipo)&lt;/div&gt;
&lt;div&gt;
Para asegurarnos el control creamos un método &quot;agregarPlato&quot;, solo se debería poder agregar platos a la selección por este método (tristemente python no permite restringirlo verdaderamente)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
class Seleccion(models.Model):&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; platos = models.ManyToManyField(Plato, related_name=&quot;selecciones&quot;)&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; comenzal = ....&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; otros atributos...&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; def agregarPlato(self, plato):&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Controlar aqui regla de que solo&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;un plato de cada tipo!&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pass&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
La consola&lt;/h3&gt;
&lt;div&gt;
Para abrir la consola de python en eclipse hacer lo siguiente:&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
Boton derecho en raiz del proyecto-&amp;gt;Django-&amp;gt;Shell with django environment&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBzy65Jn6aZ9H38tRl3J2lT5hDrILxXK5WZzjPt3IEn9IvENgfRFov37y-rZR__KJzgslwV7oHHbQVEnRcLEKehv6Gzakh7raxA-jXlZHCzhd3mDTlovQ7OeHwoAKuTjfcIgvY7UAz1qPS/s1600/Img1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;420&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBzy65Jn6aZ9H38tRl3J2lT5hDrILxXK5WZzjPt3IEn9IvENgfRFov37y-rZR__KJzgslwV7oHHbQVEnRcLEKehv6Gzakh7raxA-jXlZHCzhd3mDTlovQ7OeHwoAKuTjfcIgvY7UAz1qPS/s640/Img1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
El resultado deberia ser el siguiente,,,&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5JEFA_z6EjyB0pqG-oLR5FXDwAlGt6rY-JUZhLJ1ijGet-XfvAHUxdKbE-Yv8EpB2N3oFXLRI91il63skyc1le8rRB-FEfNaG3Ykj2EHDiVAejrEdI_Hr33_NGiuhr8JkC7xG_C5gj4oa/s1600/Img2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;196&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5JEFA_z6EjyB0pqG-oLR5FXDwAlGt6rY-JUZhLJ1ijGet-XfvAHUxdKbE-Yv8EpB2N3oFXLRI91il63skyc1le8rRB-FEfNaG3Ykj2EHDiVAejrEdI_Hr33_NGiuhr8JkC7xG_C5gj4oa/s640/Img2.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
El proceso de prueba&lt;/h3&gt;
&lt;h4&gt;
Importaciones&lt;/h4&gt;
&lt;div&gt;
Ahora bien, vamos a codificar y probar. Lo primero es importar nuestras clases.&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;Tip: No es necesario realizar el proceso de importación manualmente, la ide puede ayudar. Simplemente tratemos de instanciar un objeto y con ctrl-space podemos tocar en las sugerencias de importación como indica la imagen&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMbbN90mzBwdHqK93XayQ2yJRWf1zWuR8xbMjUG-CcU9jajcmOObZ7wwoZm14qqSXle09DTdXPaBHZKdkLns13ob6Ooq1hTz_KPzfL3AzgCmjg25Bqzq2TjOmhTzqUvRYNmzK5mJZqsovu/s1600/Img3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMbbN90mzBwdHqK93XayQ2yJRWf1zWuR8xbMjUG-CcU9jajcmOObZ7wwoZm14qqSXle09DTdXPaBHZKdkLns13ob6Ooq1hTz_KPzfL3AzgCmjg25Bqzq2TjOmhTzqUvRYNmzK5mJZqsovu/s640/Img3.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;esta&amp;nbsp;técnica&amp;nbsp;puede ahorrar mucho tiempo...&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;h4&gt;
Datos maestros&lt;/h4&gt;
&lt;div&gt;
Volviendo a nuestro tema, vamos a investigar un poco si tenemos los datos que nos permitan realizar la prueba....&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
plts = Plato.objects.all()&lt;br /&gt;
plts&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
[&amp;lt;Plato: Flan Casero&amp;gt;, &amp;lt;Plato: Omelette&amp;gt;, &amp;lt;Plato: Milanesa de soja&amp;gt;, &amp;lt;Plato: Tortilla&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Tenemos platos, veamos los tipos de esos platos...&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
for p in plts:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;print(p.tipo.descripcion)&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
Postre&lt;br /&gt;
Principal&lt;br /&gt;
Principal&lt;br /&gt;
Principal&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Como vemos los ultimo tres platos son del tipo &quot;Principal&quot; si intento meter mas de uno en una &quot;Seleccion&quot; la clase no debería permitirlo&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
La prueba&lt;/h4&gt;
&lt;div&gt;
Primero creamos una Seleccion:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
from djSisitia.models.Seleccion import Seleccion&lt;/div&gt;
&lt;div&gt;
sel = Seleccion()&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Como la relación es many to many tengo que salvar primero (aun no tengo estudiado el tema).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
#Completar todos los datos obligatorios y guardar&lt;/div&gt;
&lt;div&gt;
sel.save()&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Ahora dejamos la consola como esta e intentamos codificar el método &quot;agregarPlato&quot;&lt;/div&gt;
&lt;div&gt;
Para lograr el objetivo vamos a aplicar una logica muy simple, si ya existe un plato del mismo tipo lanzamos un excepción...&lt;/div&gt;
&lt;div&gt;
Como estamos aprendiendo a desarrollar en django vamos a usar la consola para investigar como seria preguntar si la selección tiene ya un plato de un tipo determinado, primero metemos platos por izquierda, utilizando el add de la coleccion&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
plts&lt;/div&gt;
&lt;div&gt;
[&amp;lt;Plato: Flan Casero&amp;gt;, &amp;lt;Plato: Omelette&amp;gt;, &amp;lt;Plato: Milanesa de soja&amp;gt;, &amp;lt;Plato: Tortilla&amp;gt;]&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
#Agrego un postre&lt;/div&gt;
&lt;div&gt;
sel.platos.add(plts[0])&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
#Pregunto si en la lista de platos de la seleccion existe un plato del tipo plts[0].tipo (que es postre)&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
sel.platos.filter(tipo=plts[0].tipo)&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
[&amp;lt;Plato: Flan Casero&amp;gt;]&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Listo! Funciona, ahora si a implementar...&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
def agregarPlato(self, plato):&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pl = self.platos.filter(tipo=plato.tipo)&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if not pl:&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; self.platos.add(plato)&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else:&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; raise Exception(&quot;Se esta intentando meter mas de plato del mismo tipo&quot;)&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return self.platos.all().count()&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
probemos....&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
sel.agregarPlato(plts[0]) #Se agrega un plato del tipo postre&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
1 #Exito&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
sel.agregarPlato(plts[0]) #Se otro plato del tipo postre&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;Traceback (most recent call last):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;&amp;nbsp; File &quot;&amp;lt;input&amp;gt;&quot;, line 1, in &amp;lt;module&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;&amp;nbsp; File &quot;C:\Users\pabli\git\djSisitia\djSisitia\djSisitia\models\Seleccion.py&quot;, line 29, in agregarPlato&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;&amp;nbsp; &amp;nbsp; raise Exception(&quot;Se esta intentando meter mas de plato del mismo tipo&quot;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;Exception: Se esta intentando meter mas de plato del mismo tipo #Error&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
sel.agregarPlato(plts[1]) #Se agrega un plato del tipo principal&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
2 &amp;nbsp;#Exito&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
sel.agregarPlato(plts[1]) #Se otro plato del tipo principal&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;Traceback (most recent call last):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;&amp;nbsp; File &quot;&amp;lt;input&amp;gt;&quot;, line 1, in &amp;lt;module&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;&amp;nbsp; File &quot;C:\Users\pabli\git\djSisitia\djSisitia\djSisitia\models\Seleccion.py&quot;, line 29, in agregarPlato&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;&amp;nbsp; &amp;nbsp; raise Exception(&quot;Se esta intentando meter mas de plato del mismo tipo&quot;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;color: red;&quot;&gt;Exception: Se esta intentando meter mas de plato del mismo tipo &amp;nbsp;#Error&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Conclusion&lt;/h3&gt;
&lt;div&gt;
Lo mas importante a destacar es que al estar limitados con las capacidades del ide para autocompletar código y especialmente cuando uno esta en la etapa de aprendizaje esta técnica realmente ayuda a probar características, métodos, soluciones. En el ejemplo queda especialmente visible cuando se debió probar las técnicas del filtrado que (aunque son muy básicas) quien esta aprendiendo no domina totalmente.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;Tip: Se debe tener en cuenta que ciertos cambios en el&amp;nbsp;código&amp;nbsp;requieren volver a lanzar la consola para que el interprete vuelta a interpretar las implementaciones, desconozco si existe una forma de deshabilitar esto y que reinterprete cualquier cambio, es un tema que voy a investigar y puede ser la&amp;nbsp;próxima&amp;nbsp;entrada dado que me parece que es muy factible que exista.&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/860072632957853303/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2016/09/django-testeo-de-escritorio-sobre.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/860072632957853303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/860072632957853303'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2016/09/django-testeo-de-escritorio-sobre.html' title='Django: Testeo de escritorio/interactivo sobre consola de eclipse'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBzy65Jn6aZ9H38tRl3J2lT5hDrILxXK5WZzjPt3IEn9IvENgfRFov37y-rZR__KJzgslwV7oHHbQVEnRcLEKehv6Gzakh7raxA-jXlZHCzhd3mDTlovQ7OeHwoAKuTjfcIgvY7UAz1qPS/s72-c/Img1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-2799942581446428010</id><published>2012-11-03T11:34:00.000-03:00</published><updated>2012-11-03T11:35:56.992-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Sql Management Studio"/><category scheme="http://www.blogger.com/atom/ns#" term="Sql Server"/><title type='text'>Generacion de inserts con Sql Management Studio</title><content type='html'>&lt;h2&gt;
Generacion de inserts Sql Management Studio&lt;/h2&gt;
&lt;br /&gt;
&lt;h3&gt;
¿Qué queremos hacer?&lt;/h3&gt;
Lo que intentamos hacer es crearnos los comandos de insert de los registros de una tabla determinada.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
¿Cómo lo hacemos?&lt;/h3&gt;
Decidí&amp;nbsp;escribir esta simple entrada porque es una funcionalidad tan&amp;nbsp;útil&amp;nbsp;como oculta. Sabiendo incluso que existe la posibilidad de hacerlo no es&amp;nbsp;fácil&amp;nbsp;encontrar donde.&amp;nbsp;Así&amp;nbsp;que vamos paso por paso.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
1.Abrir y autenticarse al&amp;nbsp;Sql Management Studio&lt;/h4&gt;
&lt;h4&gt;
2.Acceder a la carpeta que muestra las bases de datos&lt;/h4&gt;
&lt;h4&gt;
3.Ir por&amp;nbsp;menú&amp;nbsp;contextual a la&amp;nbsp;opción&amp;nbsp;de&amp;nbsp;menú&amp;nbsp;Generate Script como indica la siguiente imagen&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHIr89N_ST1lE1Y20WXoZduZE4uUruT5dUzys2NkLxXrkQXGHBJguQ51lPzpVsBHL17PWI0FtaqtWAz8mfD7Bcba8NnqsNh372HFQFhvVRSVClC4gcnf0acqYQKvgvLmfjxLVqfW-6FwBb/s1600/GenerateScript.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHIr89N_ST1lE1Y20WXoZduZE4uUruT5dUzys2NkLxXrkQXGHBJguQ51lPzpVsBHL17PWI0FtaqtWAz8mfD7Bcba8NnqsNh372HFQFhvVRSVClC4gcnf0acqYQKvgvLmfjxLVqfW-6FwBb/s640/GenerateScript.JPG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
4.Next a la pantalla de bienvenida del wizard&lt;/h4&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi08DlLjis5hT8vicPN6da4GCv2k5i3x3SFsbyCa73rLY9RE-BR4ue9SkT_F_d8yostJbYQw4pdDTbKbrjDAMSZMqslm9QWzvONT8airNvi_4imTpiJ6yWoe7Hu6aFjYiQlZWEAJADEL0Rl/s1600/Wizard.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;286&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi08DlLjis5hT8vicPN6da4GCv2k5i3x3SFsbyCa73rLY9RE-BR4ue9SkT_F_d8yostJbYQw4pdDTbKbrjDAMSZMqslm9QWzvONT8airNvi_4imTpiJ6yWoe7Hu6aFjYiQlZWEAJADEL0Rl/s320/Wizard.JPG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
5.Selecciona la base de donde necesitas generar los scripts y obviamente luego next&lt;/h4&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhzAOlOxiaQIpuzDkqhAFFIs3mOPiiEg5Lm0vY36YJJ3gCbIYOPo-c67vD_GvjhnQtBzoAAJ-3Ve5-4kEY-MeKuqyVvjdXXn12fDITQ_51Whra7zPgljwvBDU-Pk7TE61s8b_MKA0Tc5s9/s1600/SeleccionBase.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;286&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhzAOlOxiaQIpuzDkqhAFFIs3mOPiiEg5Lm0vY36YJJ3gCbIYOPo-c67vD_GvjhnQtBzoAAJ-3Ve5-4kEY-MeKuqyVvjdXXn12fDITQ_51Whra7zPgljwvBDU-Pk7TE61s8b_MKA0Tc5s9/s320/SeleccionBase.JPG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
6. Aca&amp;nbsp;viene lo importante, la siguiente pantalla muestra una serie de opciones de&amp;nbsp;configuración&amp;nbsp;que no vamos a ver en detalle en este post y ademas la&amp;nbsp;mayoría&amp;nbsp;se puede deducir simplemente analizando el nombre. &lt;u&gt;&lt;span style=&quot;color: #990000;&quot;&gt;Ahora hay una propiedad que nos interesa especialmente, es la propiedad Script Data , la misma&amp;nbsp;deberá&amp;nbsp;ser true si queremos generar los insert.&lt;/span&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_pfFHDEYpO12NY8Qm4iPAO66-2XBWahpKl1Ptn0MA1Gr7q6bKpoz659l6a0OeLy-BUaVm7mND9cD_4Ar1QEDjZjs0HVEKoQ4-gkWwMzoTPjmgkoDfsE9tPaLCS3Of9Vcm-uyTI1Kh0m-Y/s1600/Opciones.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_pfFHDEYpO12NY8Qm4iPAO66-2XBWahpKl1Ptn0MA1Gr7q6bKpoz659l6a0OeLy-BUaVm7mND9cD_4Ar1QEDjZjs0HVEKoQ4-gkWwMzoTPjmgkoDfsE9tPaLCS3Of9Vcm-uyTI1Kh0m-Y/s320/Opciones.JPG&quot; width=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
7.Luego el wizard nos ofrece los tipos de objetos a generar, en mi humilde base de datos, creada para esta entrada solo tengo tablas, selecciono entonces esa&amp;nbsp;opción.&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG10oQ2iJ4GiBrGLQbG8tXSkJf4oB6MbewZw0cDJYc5ErMVXZpBwsL-zSDfntK_TXrL1CouxhgvDtRs_jL2LjrZC3EgflwS1CcX8rnouMz4Vq_-SLGx3E3v_ueUM441NRjq__g_2dmfpHv/s1600/SeleccionDeObjetos.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG10oQ2iJ4GiBrGLQbG8tXSkJf4oB6MbewZw0cDJYc5ErMVXZpBwsL-zSDfntK_TXrL1CouxhgvDtRs_jL2LjrZC3EgflwS1CcX8rnouMz4Vq_-SLGx3E3v_ueUM441NRjq__g_2dmfpHv/s320/SeleccionDeObjetos.JPG&quot; width=&quot;299&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
8.El wizard esta ahora interesado en saber cual o cuales tablas quiero generar. Indico entonces la que me interesan&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj07OPjdFso5KdqbAxhRHmAaWLQ04Yjth3SVqWAHDBWHJIW_CagIFf3Ahh_xlRH-wLlWkcT1anKxkLtrHYVUgTPhyphenhyphen6YleFg9aHFsUOtQGGOQNocvR6N8rGVBCKlLGt-YLCXmeSyVX0gqcsS/s1600/SeleccionDeObjetosDetalle.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj07OPjdFso5KdqbAxhRHmAaWLQ04Yjth3SVqWAHDBWHJIW_CagIFf3Ahh_xlRH-wLlWkcT1anKxkLtrHYVUgTPhyphenhyphen6YleFg9aHFsUOtQGGOQNocvR6N8rGVBCKlLGt-YLCXmeSyVX0gqcsS/s320/SeleccionDeObjetosDetalle.JPG&quot; width=&quot;299&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
9.Siguiente paso nos pregunta donde queremos dejar el script,&amp;nbsp;básicamente&amp;nbsp;si queremos generar un archivo, si queremos poner el script en el portapapeles o si lo dejamos en una query window de nuestro sql management studio&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0ts5FiuX8stqukclvUkXvXcGt6DZhhhCuVyrnxpHhuegjCPud4kZMX67QT0M_d0QgVmhSyThtj2JMy1w3muQ-LkchI6ooyILEKdfEAZ0GZXzmd8P7AgrxoxYce1Bhdl6PLrN3oojiG0gO/s1600/Destino.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0ts5FiuX8stqukclvUkXvXcGt6DZhhhCuVyrnxpHhuegjCPud4kZMX67QT0M_d0QgVmhSyThtj2JMy1w3muQ-LkchI6ooyILEKdfEAZ0GZXzmd8P7AgrxoxYce1Bhdl6PLrN3oojiG0gO/s320/Destino.JPG&quot; width=&quot;299&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
10.Ahora sumarizado de las opciones tomadas durante la&amp;nbsp;ejecución&amp;nbsp;del wizard y finish para la generación del efectiva del script&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipow4pb1e8bsL9aonbn142mL9o9L_hmS2U6y5enmslDmkX5dKCqSw5TLg0QE5n8F0Rl8w1CR4nI0RzNYKSuWv-6sAwdYS-V_JL1MJfQXXGe42vxxMkmuvMEZr9DJ2KbsoVhzWdCpOvda9O/s1600/Sumarizacion.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipow4pb1e8bsL9aonbn142mL9o9L_hmS2U6y5enmslDmkX5dKCqSw5TLg0QE5n8F0Rl8w1CR4nI0RzNYKSuWv-6sAwdYS-V_JL1MJfQXXGe42vxxMkmuvMEZr9DJ2KbsoVhzWdCpOvda9O/s320/Sumarizacion.JPG&quot; width=&quot;299&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE2fNPfhMp8PISQHxWXFfZDxw7s9S73mBhcR635iFcXV72bHiphWdTqlRovV5z2m4uiYJTH9yw7uWMNHt-ckNgCXyKYLrsgNC2_4PUtf1lAQoEXQTAjS9EyP34GuwHkasmj7eYbHqr9qSl/s1600/Finalizacion.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE2fNPfhMp8PISQHxWXFfZDxw7s9S73mBhcR635iFcXV72bHiphWdTqlRovV5z2m4uiYJTH9yw7uWMNHt-ckNgCXyKYLrsgNC2_4PUtf1lAQoEXQTAjS9EyP34GuwHkasmj7eYbHqr9qSl/s320/Finalizacion.JPG&quot; width=&quot;299&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
11.Finalmente el script generado donde se pueden ver los comandos de script perfectamente generados.&lt;/h4&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmgCjEvAzZJCvyXTI8Erqxe_TqCyqAne5PuQrerZEYnQYwJDJHvKXltxEYObisUXaRMBVlfZbPM_bb2WhxGspPFJNm9YPIWU6Yu7wmReCTs0FhpQJbZeAQ12-ugAOa_MbtRy68vzwhPG-A/s1600/ScriptsConInsertGenerados.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmgCjEvAzZJCvyXTI8Erqxe_TqCyqAne5PuQrerZEYnQYwJDJHvKXltxEYObisUXaRMBVlfZbPM_bb2WhxGspPFJNm9YPIWU6Yu7wmReCTs0FhpQJbZeAQ12-ugAOa_MbtRy68vzwhPG-A/s640/ScriptsConInsertGenerados.JPG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
Espero haya sido de utilidad.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/2799942581446428010/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/11/generacion-de-inserts-con-sql.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/2799942581446428010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/2799942581446428010'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/11/generacion-de-inserts-con-sql.html' title='Generacion de inserts con Sql Management Studio'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHIr89N_ST1lE1Y20WXoZduZE4uUruT5dUzys2NkLxXrkQXGHBJguQ51lPzpVsBHL17PWI0FtaqtWAz8mfD7Bcba8NnqsNh372HFQFhvVRSVClC4gcnf0acqYQKvgvLmfjxLVqfW-6FwBb/s72-c/GenerateScript.JPG" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-4071830603319748245</id><published>2012-10-17T16:54:00.002-03:00</published><updated>2012-10-17T16:54:31.464-03:00</updated><title type='text'>DB Stress Generator </title><content type='html'>El DB Stress generator es un software que programe yo para simular algunas situaciones de stress en la base de datos.&lt;br /&gt;
A la fecha no es un software comercial, profesional ni mucho menos pero me ayuda bastante y no&amp;nbsp;encontré&amp;nbsp;en el mercado nada que hiciera lo que DB Stress Generator hace y como el lo hace.&lt;br /&gt;
Muchas veces desarrolladores simulan carga de trabajo generando consultas desde el administrador de la base de datos pero esto es una sola&amp;nbsp;conexión&amp;nbsp; una sola instancia. Yo estaba buscando la manera de generar n instancias para ejecutar repetidamente una consulta determinada pero ademas me interesaba mucho que los&amp;nbsp;parámetros&amp;nbsp;fueran random y que oscilaran.&lt;br /&gt;
&lt;br /&gt;
Importante aclarar que solo fue probado con SqlServer 2005/2008&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;Modo de uso&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
Configurar la&amp;nbsp;conexión, utiliza ADO para&amp;nbsp;conexión, por tanto la maquina debe tener instalado MDAC.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK-KlPfFV1MtdZ8EGcvG-xZ4HIXmi0hfmGXBuXHwwkDhmpVL8DhbYD3GclVQWD5m-nK_PvsVpnaFZA2qjxI5YesaUJDG4vXarfiO6ln50ji_cwZjgs_ElBHGiiTU1uedy47C2PxKMHFTL1/s1600/ConfigConnection1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;376&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK-KlPfFV1MtdZ8EGcvG-xZ4HIXmi0hfmGXBuXHwwkDhmpVL8DhbYD3GclVQWD5m-nK_PvsVpnaFZA2qjxI5YesaUJDG4vXarfiO6ln50ji_cwZjgs_ElBHGiiTU1uedy47C2PxKMHFTL1/s640/ConfigConnection1.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Configurar driver, host y base&amp;nbsp;según&amp;nbsp;corresponda&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnLeARAnX9hV4qzY_-9lrq32F5PEgbh8srMIY86RAKv4XU8y_hhqCyC0Jz0Fxzu0oY5zwr35DJ0sH9nqIkGn3tm4148hV15waYVSyC8z-qKW4iqOOo6nXytbaYmwwe6ZWJbh7V4o2U7bKZ/s1600/Connection.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnLeARAnX9hV4qzY_-9lrq32F5PEgbh8srMIY86RAKv4XU8y_hhqCyC0Jz0Fxzu0oY5zwr35DJ0sH9nqIkGn3tm4148hV15waYVSyC8z-qKW4iqOOo6nXytbaYmwwe6ZWJbh7V4o2U7bKZ/s320/Connection.jpg&quot; width=&quot;255&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh7Z0SDkc92wQwfdVYzGt9jw1ltJc88iuILihCumrptDsN4qX71PdC3iy1KuUc9Naz13TrQSkctinYB0KzZydUQtyPOWquJLfigFLFoFtGe_kHFMFvpKl9MwOm-Ycokto0c62qz31gfgp-/s1600/Provider.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh7Z0SDkc92wQwfdVYzGt9jw1ltJc88iuILihCumrptDsN4qX71PdC3iy1KuUc9Naz13TrQSkctinYB0KzZydUQtyPOWquJLfigFLFoFtGe_kHFMFvpKl9MwOm-Ycokto0c62qz31gfgp-/s320/Provider.jpg&quot; width=&quot;255&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
2.Conectar y colocar usuario y contraseña&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSHVvZTvyTuYB_bRFQ7HAcSzC-QK_kHZwqzdFP9ba77pDwEMQ1TFA5rCgTxY3K-hMna3XBMp3AXMCGsnZkZt2lNafi1n7cTcOhjyCio7diskIfbvmE2nsuE_5_Gntxd9K4GutEGXxCPlnd/s1600/Connect.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;376&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSHVvZTvyTuYB_bRFQ7HAcSzC-QK_kHZwqzdFP9ba77pDwEMQ1TFA5rCgTxY3K-hMna3XBMp3AXMCGsnZkZt2lNafi1n7cTcOhjyCio7diskIfbvmE2nsuE_5_Gntxd9K4GutEGXxCPlnd/s640/Connect.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf5MUmbSKyoctWyVbvtx4sVUZtizxLjGTlw9Bmw2j2DhyeFgrkAj2CCx-McUwDk6eM4eUyYF6x1est0Y685Lt-3bdloXU9wPolVc5tN0egalZNNC9Ewo6dxyEyZ7DwDNuD_SDMhB_KFAMU/s1600/UserPass.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjf5MUmbSKyoctWyVbvtx4sVUZtizxLjGTlw9Bmw2j2DhyeFgrkAj2CCx-McUwDk6eM4eUyYF6x1est0Y685Lt-3bdloXU9wPolVc5tN0egalZNNC9Ewo6dxyEyZ7DwDNuD_SDMhB_KFAMU/s640/UserPass.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Una vez conectado puede presionar el&amp;nbsp;botón&amp;nbsp;“New Stress panel” un nuevo panel&amp;nbsp;aparecerá&amp;nbsp;para realizar
el test.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_ClaC7SeTbVHKQu6izzpXF5IxwAU908fDIKGp8VMs3Pc205mRjN6VGp6VK2Q9_WUERaY_in5mmPWDn7xNKa7OosT0HLdNgn2WrFu2GnVBgMrkHJbtYfAjI75pxiH8O6UQYEdhYYkYF136/s1600/General.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;376&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_ClaC7SeTbVHKQu6izzpXF5IxwAU908fDIKGp8VMs3Pc205mRjN6VGp6VK2Q9_WUERaY_in5mmPWDn7xNKa7OosT0HLdNgn2WrFu2GnVBgMrkHJbtYfAjI75pxiH8O6UQYEdhYYkYF136/s640/General.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Escriba la query en el editor de texto
de la derecha colocando los&amp;nbsp;parámetros&amp;nbsp;de la consulta con el
anteponiendo carácter “:” . Puede&amp;nbsp;también&amp;nbsp;abrir un archivo con
la consulta previamente guardada.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Presione luego el&amp;nbsp;botón&amp;nbsp;Refresh
parameters para que se generen&amp;nbsp;automáticamente&amp;nbsp;los&amp;nbsp;parámetros&amp;nbsp;de la
consulta. Luego escriba el valor del&amp;nbsp;parámetro&amp;nbsp;o&amp;nbsp;seleccione&amp;nbsp;alguna de
las opciones de random que se despliegan con el combo donde se indica
el valor del&amp;nbsp;parámetro&amp;nbsp; Espero que en futuras versiones se permita
traer una valor aleatorio de una columna de una tabla.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Configurada la consulta y los&amp;nbsp;parámetros&amp;nbsp;se debe indicar el nivel de stress indicando cantidad de
conexiones y ejecuciones en cada conexión:&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
#Threads: indica la cantidad de hilos,
cada hilo&amp;nbsp;tendrá&amp;nbsp;una conexión a la base de datos.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Sleep between initial exe...: delay en
milisegundos para la primera&amp;nbsp;ejecución&amp;nbsp;del thread, la idea es evitar
sincronismos de&amp;nbsp;ejecución&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Iteration per Thread: cantidad de
ejecuciones por hilo&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Delay between iterations: espera entre
ejecuciones dentro del hilo.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Configurado todo esto darle “Play”
para que comience la ejecución.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Para verificar en cualquier momento la
cantidad de hilos activos puede ir al panel inferior, solapa
Statistics y ver Active Threads, cuando ese valor este en 0 indica
que el test finalizo completamente.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Se puede crear varios paneles de stress&amp;nbsp;simultáneamente!!&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Aquí&amp;nbsp;el link de descarga de la&amp;nbsp;aplicación:&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://skydrive.live.com/redir?resid=E40DE9FCAF976AD3!679&amp;amp;authkey=!AO6GrLeGAFEOzkM&quot; target=&quot;_blank&quot;&gt;https://skydrive.live.com/redir?resid=E40DE9FCAF976AD3!679&amp;amp;authkey=!AO6GrLeGAFEOzkM&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/4071830603319748245/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/10/db-stress-generator.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/4071830603319748245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/4071830603319748245'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/10/db-stress-generator.html' title='DB Stress Generator '/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK-KlPfFV1MtdZ8EGcvG-xZ4HIXmi0hfmGXBuXHwwkDhmpVL8DhbYD3GclVQWD5m-nK_PvsVpnaFZA2qjxI5YesaUJDG4vXarfiO6ln50ji_cwZjgs_ElBHGiiTU1uedy47C2PxKMHFTL1/s72-c/ConfigConnection1.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-8344747057753132765</id><published>2012-10-04T20:09:00.000-03:00</published><updated>2012-10-04T20:09:08.631-03:00</updated><title type='text'>Blackberry browser y ASP.NET</title><content type='html'>&lt;h2&gt;
Problemas con ASP.NET y navegadores
Blackberry&lt;/h2&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Y si, me&amp;nbsp;sorprendió&amp;nbsp;que me aplicación
que tan bien funcionaba, probada en varios navegadores, presentaba un
extraño comportamiento ejecutada sobre un browser de blackberry.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Se presentaban problemas con los
postback de los controles, los mismos&amp;nbsp;parecían&amp;nbsp;no ejecutarse.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
El problema es&amp;nbsp;fácil&amp;nbsp;de solucionar
aunque molesto a esta altura del partido. 
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
La&amp;nbsp;solución&amp;nbsp;requiere de la registración
del browser de blackberry en ASP.NET, realmente muy molesto.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Cree un archivo con nombre Blackberry.browser y
copie el siguiente texto dentro:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;western&quot;&gt;&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1079486184614702376&quot; name=&quot;pre1&quot;&gt;&lt;/a&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;browsers&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1079486184614702376&quot; name=&quot;pre11&quot;&gt;&lt;/a&gt;&lt;span style=&quot;color: black;&quot;&gt;  &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;browser&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;BlackBerry&quot;&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;parentID&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;Default&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;identification&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;userAgent&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;match&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;BlackBerry(?&#39;model&#39;\d+)/(?&#39;version&#39;((?&#39;major&#39;\d+).&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;(?&#39;minor&#39;\d+).(?&#39;other&#39;\d+)))&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;identification&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span style=&quot;color: black;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capabilities&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;browser&quot;&lt;/span&gt;             &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;BlackBerry&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;isMobileDevice&quot;&lt;/span&gt;      &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;true&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;javascript&quot;&lt;/span&gt;          &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;true&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;ecmascriptversion&quot;&lt;/span&gt;   &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;1.3&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;          &lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;version&quot;&lt;/span&gt;             &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;${version}&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;majorVersion&quot;&lt;/span&gt;        &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;${major}&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;minorVersion&quot;&lt;/span&gt;        &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;${minor}&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;supportsCss&quot;&lt;/span&gt;         &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;true&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;frames&quot;&lt;/span&gt;              &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;false&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;      &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capability&lt;/span&gt; &lt;span style=&quot;color: red;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;cookies&quot;&lt;/span&gt;             &lt;span style=&quot;color: red;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;=&quot;true&quot;&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;    &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;capabilities&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;  &lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;browser&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;  &lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;browsers&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Salvar el archivo en el siguiente
directorio:&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
C:&lt;a href=&quot;file://windows/Microsoft.NET/Framework/V2.0.50727/CONFIG/Browsers&quot;&gt;\\WINDOWS\Microsoft.NET\Framework\V2.0.50727\CONFIG\Browsers o directorio analogo&amp;nbsp;según&amp;nbsp;instalación&amp;nbsp;del SO&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Ahora el siguiente paso es registrar el
browser de blackberry en ASP.NET. Para registrarlo&amp;nbsp;deberá&amp;nbsp;utilizar la
aplicación aspnet_regbrowsers.exe con el&amp;nbsp;parámetro&amp;nbsp;-i, como ejemplo:&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
C:\\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regbrowsers.exe
-i&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
El path puede&amp;nbsp;cambiar&amp;nbsp;en virtud del
path de&amp;nbsp;instalación&amp;nbsp;del SO.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Realmente es muy molesto tener que
hacer esta registración previa al deploy, como contrapartida una&amp;nbsp;vez&amp;nbsp;realizada las aplicaciones ejecutadas sobre navegadores blackberry
pasan a comportarse normalmente&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/8344747057753132765/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/10/blackberry-browser-y-aspnet.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/8344747057753132765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/8344747057753132765'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/10/blackberry-browser-y-aspnet.html' title='Blackberry browser y ASP.NET'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-61232562463100988</id><published>2012-10-04T00:37:00.001-03:00</published><updated>2012-10-04T20:10:19.193-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Sql Server"/><category scheme="http://www.blogger.com/atom/ns#" term="tuning"/><title type='text'>SqlServer, plan de consulta y optimización (Tuning) (3)</title><content type='html'>&lt;h2&gt;
&lt;b&gt;&lt;u&gt;SqlServer, plan de consulta y optimización (Tuning)&amp;nbsp;&lt;/u&gt;&lt;/b&gt;&lt;u&gt;(3)&lt;/u&gt;&lt;/h2&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;El problema&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
En la entrada pasada vimos al sql server meter la pata groseramente al intentar estimar la cantidad de registros a recibir en una consulta con datos correlacionados.&lt;br /&gt;
Quedo en evidencia el problema y se dijo que dado lo grosero del error dificilmente el motor pudiera escoger un plan optimo de consulta.&lt;br /&gt;
El problema radica en que el sql server no entiende que existe&amp;nbsp;relación&amp;nbsp;entre dos columnas, hay&amp;nbsp;múltiples&amp;nbsp;ejemplos de datos correlacionados, edad y altura, peso y tamaño, calidad y precio etc.&lt;br /&gt;
La&amp;nbsp;situación&amp;nbsp;es que el sql server calcula la probabilidad de que se cumpla una&amp;nbsp;condición&amp;nbsp;múltiple basicamente como el producto de ambas, esto es correcto y es lo que aprendimos en probabilidad y estadista, la probabilidad de que ocurran dos eventos es el producto de la probabilidad de que ocurra cada uno de ellos.&lt;br /&gt;
Lo que&amp;nbsp;también&amp;nbsp;nos enseñaron es que los experimentos deben ser independiente y no deben afectarse mutuamente cosa que&amp;nbsp;aquí&amp;nbsp;no pasa.&amp;nbsp;Difícilmente&amp;nbsp;encontremos una persona con cintura estrecha, que mida menos de 1.6 metros y que pese mas de 100 kg, las tres variables&amp;nbsp;están&amp;nbsp;correlacionadas.&lt;br /&gt;
Podemos encontrar ejemplo donde el motor descarta un indice por errores de&amp;nbsp;estimación&amp;nbsp;en columnas correlacionadas, no es tan&amp;nbsp;fácil&amp;nbsp;encontrar ejemplos donde el motor escoja una estrategia de join equivocada.&lt;br /&gt;
&lt;br /&gt;
Hagamos un experimento con la siguiente consulta :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
declare @marca char(20)&lt;br /&gt;
declare @Modelo char(20)&lt;br /&gt;
declare @Motor char(20)&lt;br /&gt;
declare @Origen char(20)&lt;br /&gt;
declare @Ranking int&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
set @marca=&#39;VW&#39;&lt;br /&gt;
set @Modelo=&#39;GOL&#39;&lt;br /&gt;
set @Motor=&#39;VW 1.6&#39;&lt;br /&gt;
set @Origen=&#39;BRASIL&#39;&lt;br /&gt;
set @Ranking=1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
select *&lt;br /&gt;
from Vehiculo as v1 inner JOIN Vehiculo as v2&lt;br /&gt;
On v1.IdVehiculo=v2.IdVehiculo &amp;nbsp;inner &amp;nbsp;JOIN Vehiculo as v3&lt;br /&gt;
On v2.IdVehiculo=v3.IdVehiculo inner join Vehiculo as v4&lt;br /&gt;
On v3.IdVehiculo=v4.IdVehiculo&lt;br /&gt;
Where&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;v1.Marca=@marca and&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;v1.Modelo=@Modelo and&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;v1.Motor=@Motor and&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;v1.Origen=&#39;BRASIL&#39; and&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;v1.Ranking=1&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La&amp;nbsp;ejecución&amp;nbsp;de la consulta otorga la siguiente&amp;nbsp;información,&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjettBAA1HTYlGv8ZVU-zhDFadhWpuGSzpkWfBg7NrrQRM9TB6VZyBySaOU1Uf_08slvNn70krplqZpSRUV6RJFKOZGeZ_u-sw4eH3Rq5lXCGSyDiHT3jGvwH6iMXY4rZAjbEj5qiT08k8_/s1600/A1.JPG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjettBAA1HTYlGv8ZVU-zhDFadhWpuGSzpkWfBg7NrrQRM9TB6VZyBySaOU1Uf_08slvNn70krplqZpSRUV6RJFKOZGeZ_u-sw4eH3Rq5lXCGSyDiHT3jGvwH6iMXY4rZAjbEj5qiT08k8_/s640/A1.JPG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La estrategia de join del motor es &quot;nested loop&quot;, el motor piensa que va a recibir pocos registros y por tanto escoge esta&amp;nbsp;estrategia, seguramente la mas conveniente con conjuntos de 1500 registros (Los que estima recibir).&lt;br /&gt;
La realidad demuestra que se reciben 200000, y el join es por IdVehiculo, indice cluster, por tanto los conjuntos&amp;nbsp;están&amp;nbsp;ordenados.&lt;br /&gt;
Se ve marcado en rojo la enorme diferencia que existe entre lo que el sql espera recibir y lo que verdaderamente recibe&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;La&amp;nbsp;solución (&amp;nbsp;MERGE JOIN )&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
Existe un mecanismo de join llamado MERGE_JOIN es un mecanismo que es eficiente solo con conjuntos ordenados de&amp;nbsp;determinado&amp;nbsp;tamaño. Si&amp;nbsp;forzáramos&amp;nbsp;MERGE JOIN en conjuntos no ordenados el sql los&amp;nbsp;tendría&amp;nbsp;que ordenar previamente y generalmente esto no da buenos resultados.&lt;br /&gt;
No es este el caso donde ex profeso hemos hecho el join por el indice cluster.&lt;br /&gt;
Vemos&amp;nbsp;también&amp;nbsp;que no es la&amp;nbsp;opción&amp;nbsp;elegida por nuestro Sql Server, a pesar de que los conjuntos&amp;nbsp;están&amp;nbsp;ordenados la cantidad de registros que espera obtener no&amp;nbsp;a merita&amp;nbsp;el uso de Merge join.&lt;br /&gt;
Forzamos entonces al sql a utilizar MERGE_JOIN a sabiendas de que el motor tiene enormes problemas para predecir la cantidad de registros que cumplen la&amp;nbsp;condición.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
declare @marca char(20)&lt;br /&gt;
declare @Modelo char(20)&lt;br /&gt;
declare @Motor char(20)&lt;br /&gt;
declare @Origen char(20)&lt;br /&gt;
declare @Ranking int&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
set @marca=&#39;VW&#39;&lt;br /&gt;
set @Modelo=&#39;GOL&#39;&lt;br /&gt;
set @Motor=&#39;VW 1.6&#39;&lt;br /&gt;
set @Origen=&#39;BRASIL&#39;&lt;br /&gt;
set @Ranking=1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
select *&lt;br /&gt;
from Vehiculo as v1 inner MERGE JOIN Vehiculo as v2&lt;br /&gt;
On v1.IdVehiculo=v2.IdVehiculo &amp;nbsp;inner MERGE &amp;nbsp;JOIN Vehiculo as v3&lt;br /&gt;
On v2.IdVehiculo=v3.IdVehiculo inner MERGE join Vehiculo as v4&lt;br /&gt;
On v3.IdVehiculo=v4.IdVehiculo&lt;br /&gt;
Where&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;v1.Marca=@marca and&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;v1.Modelo=@Modelo and&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;v1.Motor=@Motor and&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;v1.Origen=&#39;BRASIL&#39; and&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt;  &lt;/span&gt;v1.Ranking=1&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Observemos y comparemos el rendimiento en uno y otro caso&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJm2wLb5ktwvnW2_9s1zkQxAb3iVvpLSY56TagBvLIb5Iq1dOPQqjeiC4cEds_r0Sh1Syh2UvIoRKuOa7FxgXPAVsG-KSqp6XXl8WwYNIo9m5a_87QS2JTSjj4dZQ7-IGnA6fGmk5AAWfY/s1600/DifRendimiento.JPG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;310&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJm2wLb5ktwvnW2_9s1zkQxAb3iVvpLSY56TagBvLIb5Iq1dOPQqjeiC4cEds_r0Sh1Syh2UvIoRKuOa7FxgXPAVsG-KSqp6XXl8WwYNIo9m5a_87QS2JTSjj4dZQ7-IGnA6fGmk5AAWfY/s400/DifRendimiento.JPG&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Mas&amp;nbsp;allá&amp;nbsp;de esta&amp;nbsp;medición&amp;nbsp;puntual en varias pruebas observe que el tiempo de&amp;nbsp;ejecución&amp;nbsp;se reduce a la mitad, en fin los datos correlacionados hicieron desastres con las estimaciones y destruyeron los intentos del motor por obtener un buen plan de consulta.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Consideraciones finales&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
Para cerrar, mucho cuidado,&amp;nbsp;el problema se da bajo las condiciones actuales de la tabla, pero atención &amp;nbsp;mas registros, un cambio en la&amp;nbsp;distribución&amp;nbsp;y&amp;nbsp;correlación&amp;nbsp;de los datos, o un cambio en la estructura&amp;nbsp;invalidaría&amp;nbsp;lo expuesto, por eso precaución al forzar el plan de consulta&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/61232562463100988/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/10/sqlserver-plan-de-consulta-y.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/61232562463100988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/61232562463100988'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/10/sqlserver-plan-de-consulta-y.html' title='SqlServer, plan de consulta y optimización (Tuning) (3)'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjettBAA1HTYlGv8ZVU-zhDFadhWpuGSzpkWfBg7NrrQRM9TB6VZyBySaOU1Uf_08slvNn70krplqZpSRUV6RJFKOZGeZ_u-sw4eH3Rq5lXCGSyDiHT3jGvwH6iMXY4rZAjbEj5qiT08k8_/s72-c/A1.JPG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-632269426717247105</id><published>2012-09-29T18:26:00.001-03:00</published><updated>2012-10-04T20:10:00.960-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Sql Server"/><category scheme="http://www.blogger.com/atom/ns#" term="tuning"/><title type='text'>SqlServer, plan de consulta y optimización (Tuning) (2)</title><content type='html'>&lt;h2&gt;
&lt;b&gt;&lt;u&gt;SqlServer, plan de consulta y optimización (Tuning) (2)&lt;/u&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;
&lt;b&gt;&lt;u&gt;Datos correlacionados&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
En la entrada anterior hablamos sobre cuando puede fallar el optimizador, que&amp;nbsp;podría&amp;nbsp;hacer fallar el path suboptimo pensado por el motor.&lt;br /&gt;
Se me ha hecho muy&amp;nbsp;fácil&amp;nbsp;engañar algunos motores y hacerles meter la pata, con sql server se complica un poco mas y las situaciones por donde podemos hacer &quot;pinchar&quot; al optimizador son pocas. Una de ellas es tener datos correlacionados.&lt;br /&gt;
Para el ejemplo de la entrega vamos a manejarnos con una tabla de vehiculos con campos marca, modelo y motor, la tabla seria la siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;Tabla&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
CREATE TABLE [dbo].[Vehiculo](&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;[IdVehiculo] [int] IDENTITY(1,1) NOT NULL,&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;[Dominio] [char](20) NOT NULL,&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;[Observacion] [text] NOT NULL,&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;[Marca] [char](20) NOT NULL,&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;[Modelo] [char](20) NOT NULL,&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;[Motor] [char](20) NOT NULL,&lt;br /&gt;
&amp;nbsp;CONSTRAINT [PK_Vehiculo] PRIMARY KEY CLUSTERED&lt;br /&gt;
(&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;[IdVehiculo] ASC&lt;br /&gt;
)WITH (PAD_INDEX &amp;nbsp;= OFF, STATISTICS_NORECOMPUTE &amp;nbsp;= OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS &amp;nbsp;= ON, ALLOW_PAGE_LOCKS &amp;nbsp;= ON) ON [PRIMARY]&lt;br /&gt;
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
En la misma insertamos aproximadamente 100000 VW GOL POWER con motor VW 1.6, insertamos&amp;nbsp;también&amp;nbsp;alrededor de 50000 de otros&amp;nbsp;vehículos, de otras marcas y modelos&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;¿Porque es&amp;nbsp;difícil&amp;nbsp;que se equivoque el sql server?&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
El sql server maneja&amp;nbsp;estadísticas&amp;nbsp;para tablas con mas de 500 registros con una buena&amp;nbsp;precisión, el sql server sabe en muchos casos, y por ejemplo para nuestra tabla de&amp;nbsp;vehículo&amp;nbsp; cuantos FIAT, cuando VW o cuantos FORD hay, sabe&amp;nbsp;también cuantos GOL POWER hay y cuantos PALIO (Las estadisticas las fue generando a medida que se ejecutaron selects con condiciones de&amp;nbsp;selección&amp;nbsp;aplicadas a los campos).&lt;br /&gt;
Si&amp;nbsp;pidiéramos&amp;nbsp;al sqlserver que nos retorne todos los&amp;nbsp;vehículos&amp;nbsp;PALIO el mismo&amp;nbsp;sabría&amp;nbsp;con buena&amp;nbsp;precisión&amp;nbsp;cuantos hay, escogería&amp;nbsp;una estrategia de&amp;nbsp;búsqueda&amp;nbsp;adecuada.&lt;br /&gt;
&lt;br /&gt;
Lo que no sabe y no puede saber es la correlación&amp;nbsp;que existe entre, por ejemplo, el modelo GOL POWER y la marca VW,&amp;nbsp;hay una&amp;nbsp;relación&amp;nbsp;estricta entre marca y modelo y sí alguien&amp;nbsp;podría&amp;nbsp;decir,&lt;br /&gt;
&lt;br /&gt;
-El problema es que la base esta mal diseñada,&amp;nbsp;deberías&amp;nbsp;tener tabla de modelos y tabla de marcas, ambas relacionadas&lt;br /&gt;
&lt;br /&gt;
Si es cierto para este caso, la realidad es que las bases con las que nos toca trabajar no siempre&amp;nbsp;están&amp;nbsp;bien diseñadas y ademas hay casos donde la&amp;nbsp;relación&amp;nbsp;es muy estrecha pero no definitiva.&lt;br /&gt;
Por ejemplo si&amp;nbsp;preguntáramos&amp;nbsp;Franceses que hablan&amp;nbsp;Francés&amp;nbsp;obtendríamos a casi todos los Franceses, pero no necesariamente a todos.&lt;br /&gt;
En cualquier caso si&amp;nbsp;pidiéramos&amp;nbsp;al SqlServer que nos retorne todos los VW que son GOL POWER es probable que lo pongamos en un aprieto a la hora de estimar la cantidad de registros que&amp;nbsp;retornaría&amp;nbsp;la consulta, una mala&amp;nbsp;estimación&amp;nbsp;de este tipo desencadena una serie de malas decisiones a la hora de elegir la estrategia de join, la estrategia de&amp;nbsp;búsqueda&amp;nbsp;etc.&lt;br /&gt;
&lt;br /&gt;
En las ultimas versiones de sql server (2008 o superior) existe la posibilidad de explicarle al motor la&amp;nbsp;situación&amp;nbsp;mediante indices especiales, es una&amp;nbsp;opción&amp;nbsp;valida pero algo oscura.&lt;br /&gt;
Me da la&amp;nbsp;sensación&amp;nbsp;que esos indices tan&amp;nbsp;específicos&amp;nbsp;pueden generar problemas entre implementaciones o durante el ciclo de vida de la base de datos si no se tiene control de su existencia y de su&amp;nbsp;carácter&amp;nbsp;especifico.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;Miren todos como se equivoca el sql server&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En la siguiente imagen se puede ver la&amp;nbsp;pésima&amp;nbsp;estimación&amp;nbsp;que hace el sqlserver .&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKyNH76xEBhPo4YtvcW_H71Cm8NGdJlZSnBfTthPUxpKjIASF_nIVv8F1TbjFqQxicC2KM_PPNEURYCrIFpg4S6sq-EaxbTtj3Nax7ksYRaj9saj8NNkkqNR_Fzritc0GltU10ahyA7UKS/s1600/planDeConsulta.JPG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;398&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKyNH76xEBhPo4YtvcW_H71Cm8NGdJlZSnBfTthPUxpKjIASF_nIVv8F1TbjFqQxicC2KM_PPNEURYCrIFpg4S6sq-EaxbTtj3Nax7ksYRaj9saj8NNkkqNR_Fzritc0GltU10ahyA7UKS/s640/planDeConsulta.JPG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Si examinamos el plan de consulta el mismo espera recibir algo&amp;nbsp;así&amp;nbsp;como 1125 filas, veamos que fue lo que efectivamente recibimos luego de ejecutar la consulta...&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZaVBpeE96XGn_5EJENb4jpoq4oMOafmkFxPRYmiXFrUhBE0Te7S1IaEgAU1Mn_1eal7FZ-yiBRHXMWssaKbZ9oYiryJWvEp5MlgLh6CSL86hXrfqMehTASkfms_yZJlcpiujBQKM1ldcR/s1600/Resultado.JPG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;235&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZaVBpeE96XGn_5EJENb4jpoq4oMOafmkFxPRYmiXFrUhBE0Te7S1IaEgAU1Mn_1eal7FZ-yiBRHXMWssaKbZ9oYiryJWvEp5MlgLh6CSL86hXrfqMehTASkfms_yZJlcpiujBQKM1ldcR/s400/Resultado.JPG&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La consulta&amp;nbsp;devolvió&amp;nbsp;100001 registros, la diferencia es importante en una tabla con 150000 registros, y como se menciono antes ya no se puede esperar mucho del plan de consulta&amp;nbsp;después&amp;nbsp;de semejante error.&lt;br /&gt;
&lt;br /&gt;
En la&amp;nbsp;próxima&amp;nbsp;entrada vamos a ver como este error degenera en la perdida de rendimiento de la consulta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/632269426717247105/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/09/sqlserver-plan-de-consulta-y_29.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/632269426717247105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/632269426717247105'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/09/sqlserver-plan-de-consulta-y_29.html' title='SqlServer, plan de consulta y optimización (Tuning) (2)'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKyNH76xEBhPo4YtvcW_H71Cm8NGdJlZSnBfTthPUxpKjIASF_nIVv8F1TbjFqQxicC2KM_PPNEURYCrIFpg4S6sq-EaxbTtj3Nax7ksYRaj9saj8NNkkqNR_Fzritc0GltU10ahyA7UKS/s72-c/planDeConsulta.JPG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-1499187339557968070</id><published>2012-09-28T15:46:00.002-03:00</published><updated>2012-10-04T20:10:38.425-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Sql Server"/><category scheme="http://www.blogger.com/atom/ns#" term="tuning"/><title type='text'>SqlServer, plan de consulta y optimización (Tuning) (1)</title><content type='html'>&lt;h2&gt;
SqlServer, plan de consulta y optimización (Tuning) (1)&lt;/h2&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
De mi parte, siempre di la derecha al plan de consulta que el motor escogía, si el rendimiento no es el esperado sera porque diseñe mal la base o porque me faltan indices o directamente porque el software esta trabajando de manera incorrecta. Tengo desarrollos completos, algunos de tiempo real con bastante exigencia al motor donde la cantidad de planes de consulta forzados en todo los módulos del software es 0.&lt;/div&gt;
&lt;div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;
Hace mucho años trabajando para una compañía bastante grande observaba horrorizado como se había instalado la cultura de crear la consulta e indicar porque indice ir.&lt;br /&gt;
Meses después tuve mi revancha cuando nos mandaron a todos a hacer un curso de tuning de sql, y si no fue lo primero, lo segundo que dijo el instructor fue “No fuercen el plan de consulta, es muy probable que no tengan el conocimiento y la cantidad de información necesaria para hacerlo”&lt;br /&gt;
Los mismo dice microsoft en su msdn, traducción mediante “Típicamente sqlserver encuentra el mejor plan posible, no lo cambie salvo que sea un experto programador o experto administrador de base de datos”.&lt;br /&gt;
&lt;br /&gt;
Probablemente todos nos sentimos expertos programadores, sea así o no, con eso no alcanza. Ademas de la experiencia se necesita conocimiento del modelo, de los indices y de la distribución y naturaleza de la información, en la mayoría de los casos conocer todo esto es poco probable y casualmente el sqlServer (Correctamente configurado) en sus estadísticas tiene esta información con un nivel de confiabilidad superior al 80%.&lt;br /&gt;
&lt;br /&gt;
Entonces si no hay posibilidades de mejora y el motor es perfecto ¿Por que existen los hints?&lt;br /&gt;
Bueno de hecho &lt;u&gt;&lt;b&gt;el motor sí se equivoca, poco, pero se equivoca&lt;/b&gt;&lt;/u&gt; con especial énfasis en las siguientes situaciones:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Datos correlacionados&lt;/li&gt;
&lt;li&gt;Poda por heuristica&lt;/li&gt;
&lt;li&gt;Bug optimizador&lt;/li&gt;
&lt;li&gt;Estadísticas no actualizadas&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;br /&gt;
¿Entonces modifico o no el plan de consulta?&lt;br /&gt;
&lt;br /&gt;
Entiendo que modificar el plan de consulta es la solución mas tentadora a un problema de rendimiento, generalmente parece ser también la solución menos probable hasta puede ofrecer mejoras marginales en muchos casos.&lt;br /&gt;
En posteriores entradas voy a intentar desgranar situaciones donde malos diseños, bugs del optimizador, datos correlacionados, podas o malas estadísticas puedan hacer que el sql se equivoque groseramente.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/1499187339557968070/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/09/sqlserver-plan-de-consulta-y.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/1499187339557968070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/1499187339557968070'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/09/sqlserver-plan-de-consulta-y.html' title='SqlServer, plan de consulta y optimización (Tuning) (1)'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-9112852067504911076</id><published>2012-09-25T14:48:00.001-03:00</published><updated>2012-09-25T23:42:15.445-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><title type='text'>Desarrollo WAP en Visual Web Developer 2010</title><content type='html'>&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Primero, si buscan los templates para
desarrollo wap en visual studio 2010 notaran que ya no existen. Los
componentes aun vienen pero la gente de microsoft argumenta que ya no
tiene sentido incorporar al IDE los mismos, o disponibilizar
templates dado que es un tipo de desarrollo obsoleto.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Cualquier dispositivo móvil moderno
soporta html básico, el soporte para desarrollo WAP no parece ser
una necesidad.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Esto es casi cierto, me ha tocado
desarrollar una pequeña aplicación para dispositivos móviles, y
los dispositivos móviles no soportaban html, solo WAP.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
¿Como podemos encarar este desarrollo?&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
¿Sera necesario instalar un viejo
Visual Studio 2003?&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
No necesariamente, veamos los pasos
para un efectivo desarrollo.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;h4&gt;
1.Descargar templates&lt;/h4&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Primero tenemos que descargar los
templates para forms WAP, estos template pueden ayudar, se pueden
descargar de aquí:&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;a href=&quot;http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-01-43-76-61/Mobile-Web-Form-Templates-for-WAP.zip&quot;&gt;http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-01-43-76-61/Mobile-Web-Form-Templates-for-WAP.zip&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Luego descomprimir y seguir las
instrucciones, las cuales básicamente dicen de colocar los templates
en la carpeta&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
[My Documents]\Visual Studio
2010\Templates\ItemTemplates\Visual C#&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
o si prefiere&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
C:\Users\FulanoDeTal\Documents\Visual
Studio 2010\Templates\ItemTemplates\Visual Web Developer&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;h4&gt;
2.Si todo fue bien cree una Aplicación
WEB ASP.NET vacía&lt;/h4&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgghA5nk_P7TZ5WvRzP8odcO6QugOnw-OQmlRXfxznVxMrPYq4IfpX8jJJg0K_Fqz0o5VLpGBVtYyyrzhQE7VtwceRdLSKcc75Sr4gIoEQBMvbypR7uFaNnvwSLqiVpHCw_z-cl9C51lXEB/s1600/AppASPNETVacia.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;441&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgghA5nk_P7TZ5WvRzP8odcO6QugOnw-OQmlRXfxznVxMrPYq4IfpX8jJJg0K_Fqz0o5VLpGBVtYyyrzhQE7VtwceRdLSKcc75Sr4gIoEQBMvbypR7uFaNnvwSLqiVpHCw_z-cl9C51lXEB/s640/AppASPNETVacia.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;h4&gt;
&amp;nbsp;3.Luego Agregar-&amp;gt;Nuevo elemento y
seleccione Mobile Web Form.&lt;/h4&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvPO6XTeovrDPIjclKu25KeGSfvSw-nNjHvdjy9LTU8mwSVM4xsBsVx9FqXCfEvyslSE51OiXJZnCRtqjRKbHubbeC11UQY_bP7vyDZuHlofPs47347ZsMQUdBitpBqQ8EuuZRE5nax8I_/s1600/NuevoWebForm.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;442&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvPO6XTeovrDPIjclKu25KeGSfvSw-nNjHvdjy9LTU8mwSVM4xsBsVx9FqXCfEvyslSE51OiXJZnCRtqjRKbHubbeC11UQY_bP7vyDZuHlofPs47347ZsMQUdBitpBqQ8EuuZRE5nax8I_/s640/NuevoWebForm.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Ahora tenemos nuestro mobile web form,
el cual vamos a editar y efectivamente puede ser accedido desde
equipos que solo manejan WAP.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;b&gt;La mala noticia:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
No estará disponible el diseño
visual.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTXsRoCCZLd7N9h3tQdADFhd7o7Sqxgkh-ZyL-CmTVbggnF5O1cvz_quMmo_jd3Wuv_bSm-TlBEyx2OU9q_bMbNRqIUvdVwIlZUQCyIESMhUBz3OmM5V0oHh2UD3GUvQBZR5ikQWiYeSLQ/s1600/SinDisenio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;282&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTXsRoCCZLd7N9h3tQdADFhd7o7Sqxgkh-ZyL-CmTVbggnF5O1cvz_quMmo_jd3Wuv_bSm-TlBEyx2OU9q_bMbNRqIUvdVwIlZUQCyIESMhUBz3OmM5V0oHh2UD3GUvQBZR5ikQWiYeSLQ/s640/SinDisenio.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;b&gt;La buena noticia:&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Tampoco es estrictamente necesario, la
interfaces WAP son tan pobres y la cantidad de componentes tan pocos
que no debería quitarnos el sueño no tener el tan cómodo diseñador
visual, especialmente para quienes no son totalmente del palo web.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4&gt;
4.Diseñar&lt;/h4&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Bien, como dijimos no tenemos diseñador
visual, ¿Como hacemos?&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Bueno ayudarse con el asistente de VS
para ir armando el formulario, es muy similar a un formulario html.
Colocar el carácter “&amp;lt;” escribir “mob” y alli aparecerán
las opciones de componente, como es de esperar muy pocos pero
suficientes para lo que tenemos que hacer, que también seguramente
sera muy simple (No se le puede pedir mucho a una aplicación WAP).  
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrMylrTlJWqICawRa89ZmrXx6GMvL49NR3YYHQOFOQTxb15kIiifsgykH4PNIguo2fX8xmQvNSwHcZjIW4pZk3C47-zcYPDhk8F4FekhVAv8RdVTc1qFHKmSA2WRee6BIYTFSj2Xn6nI4n/s1600/CodeIns.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;260&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrMylrTlJWqICawRa89ZmrXx6GMvL49NR3YYHQOFOQTxb15kIiifsgykH4PNIguo2fX8xmQvNSwHcZjIW4pZk3C47-zcYPDhk8F4FekhVAv8RdVTc1qFHKmSA2WRee6BIYTFSj2Xn6nI4n/s640/CodeIns.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Recordar agregar las referencias al
asembly con los componentes mobile...puedes usar con copia local si
te trae problemas&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXEUT36b0Be1XzcmxVxTqFGe5sHZWk86MrkHIk6ETURLmfP4qdpRLFw6My3GAT7FGBxQWbpOCTAVd9lsvGxBEX3N9fIe3nSStRXj-7UGwXcXIFUTLv_x0-GCAZYoCM6A7o_WatdKczd1_5/s1600/AddReference.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;384&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXEUT36b0Be1XzcmxVxTqFGe5sHZWk86MrkHIk6ETURLmfP4qdpRLFw6My3GAT7FGBxQWbpOCTAVd9lsvGxBEX3N9fIe3nSStRXj-7UGwXcXIFUTLv_x0-GCAZYoCM6A7o_WatdKczd1_5/s640/AddReference.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
El código abajo
muestra como quedaría el formulario. Observe que he creado dos
textbox, los he identificado como Runat=”Server”, les he puesto
un ID como corresponde y otras propiedades adicionales cuando fue
necesario.&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
También puse un
command, algo asi como el botón de asp.net en webforms, he declarado
también y codificado la función DoClick  y se la he asignado al
OnClick del comando. Si no me he equivocado con los nombre cuando se
haga click sobre el boton se deberia ejecutar mi evento DoClick. A no
tener miedo de usar los textbox del lado servidor, ya están
disponibles como indica el código.&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;%&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;@&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Page&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Language&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;C#&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;AutoEventWireup&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;true&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Inherits&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;WAPTEST.WAPLogin&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Codebehind&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;WAPLogin.aspx.cs&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;%&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;@&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Register&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;TagPrefix&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;mobile&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Namespace&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;System.Web.UI.MobileControls&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Assembly&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;System.Web.Mobile&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;html&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;xmlns&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;http://www.w3.org/1999/xhtml&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;body&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;mobile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Form&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;id&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;Form1&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;runat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;server&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;        &lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Usuario:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;mobile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;TextBox&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Runat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;server&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;ID&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;tbUsuario&quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;mobile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;TextBox&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;        &lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Password:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;mobile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;TextBox&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Runat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;server&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;ID&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;tbPassword&quot;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Password&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;True&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;mobile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;TextBox&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;       
&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;mobile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Command&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;ID&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;btnAceptar&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Runat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;Server&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: red;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;OnClick&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;=&quot;DoClick&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Aceptar&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;mobile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Command&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;   
&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;mobile&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Form&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;body&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: maroon;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;html&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&amp;nbsp;&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Collections;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.ComponentModel;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Data;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Drawing;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Web;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Web.Mobile;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Web.SessionState;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Web.UI;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Web.UI.MobileControls;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Web.UI.WebControls;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
System.Web.UI.HtmlControls;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;namespace&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
WAPTEST&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;public&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;partial&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;class&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #2b91af;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;WAPLogin&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
: System.Web.UI.MobileControls.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #2b91af;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;MobilePage&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;    &lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; protected&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;void&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
Page_Load(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;object&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
sender, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #2b91af;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;EventArgs&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
e)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; protected&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;void&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
DoClick(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;object&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
sender, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #2b91af;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;EventArgs&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;
e)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: green;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; //Codificar
aca....&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: green;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; //Se
tiene acceso a los controles sin problemas por ej. &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: green;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; //string s = tbUsuario.Text; es perfectamente posible.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;    &lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: Consolas, sans-serif;&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Aca el resultado en un navegador&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu3bOAbLq3jK2rq3Ra1hmcRHWhsoZMtlVvOIiBBsJCQ7Zf6QvZh_h0YdTI_C67gwUMa9OCASZk1fAuhfKO-NWQdgx1BTsH_8nIBCtVCFchm9e8nm7PccJ3fp92JHv_su0J3lHh7X8hIzuO/s1600/VistaWeb.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;218&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu3bOAbLq3jK2rq3Ra1hmcRHWhsoZMtlVvOIiBBsJCQ7Zf6QvZh_h0YdTI_C67gwUMa9OCASZk1fAuhfKO-NWQdgx1BTsH_8nIBCtVCFchm9e8nm7PccJ3fp92JHv_su0J3lHh7X8hIzuO/s640/VistaWeb.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
Aca en un navegador wap&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_e9VsfyW2vliZt-oUuSWAg-SErOkUwJSUmsrrPxDjOthhexPkbsTaHp80zS715oCTYPowmNfusMFUpMIlewbaKUq3o85AFAv9RnBqaZjqujaAGPDLn5_u0fc6feLIzUbbudt3uKEkNgMv/s1600/VistaWAP.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_e9VsfyW2vliZt-oUuSWAg-SErOkUwJSUmsrrPxDjOthhexPkbsTaHp80zS715oCTYPowmNfusMFUpMIlewbaKUq3o85AFAv9RnBqaZjqujaAGPDLn5_u0fc6feLIzUbbudt3uKEkNgMv/s320/VistaWAP.png&quot; width=&quot;135&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/9112852067504911076/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/09/desarrollo-wap-en-visual-web-developer.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/9112852067504911076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/9112852067504911076'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/09/desarrollo-wap-en-visual-web-developer.html' title='Desarrollo WAP en Visual Web Developer 2010'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgghA5nk_P7TZ5WvRzP8odcO6QugOnw-OQmlRXfxznVxMrPYq4IfpX8jJJg0K_Fqz0o5VLpGBVtYyyrzhQE7VtwceRdLSKcc75Sr4gIoEQBMvbypR7uFaNnvwSLqiVpHCw_z-cl9C51lXEB/s72-c/AppASPNETVacia.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-808292802056589939</id><published>2012-06-20T15:06:00.002-03:00</published><updated>2012-06-20T15:08:38.962-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi WebServices Certificados"/><title type='text'>WebServices y certificados vencidos</title><content type='html'>&lt;span style=&quot;background-color: white;&quot;&gt;Perdí&lt;/span&gt;&amp;nbsp;varias horas de pruebas y repruebas por un problema que ya&amp;nbsp;había&amp;nbsp;tenido pero que tarde&amp;nbsp;días&amp;nbsp;en recordar.&amp;nbsp;Según&amp;nbsp;algunos informes, internet paso a ser una&amp;nbsp;extensión&amp;nbsp;de nuestra memoria y en general muchas&amp;nbsp;situaciones se olvidan&amp;nbsp;rápidamente&amp;nbsp;para dejar lugar a cuestiones mas inmediatas.&lt;br /&gt;
El problema era la imposibilidad de consumir un servicio https y que tenia un certificado vencido. Tarde mucho tiempo en recordad la&amp;nbsp;solución&amp;nbsp;como para dejarla pasar y no registrarla en el blog.&lt;br /&gt;
La cuestion se resuelve seteando una simple opcion que no esta tan visible ni es tan accesible asi que aqui el codigo con la explicacion.&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
&amp;nbsp; r:Integer;&lt;br /&gt;
&amp;nbsp; msg:string;&lt;br /&gt;
&amp;nbsp; ss:ServiceSoap;&lt;br /&gt;
&amp;nbsp; RIO : THTTPRIO;&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; { Place thread code here }&lt;br /&gt;
&amp;nbsp; //Creo un componentes http RIO&lt;br /&gt;
&amp;nbsp; &lt;span style=&quot;color: red;&quot;&gt;RIO := THTTPRIO.Create(nil);&lt;/span&gt;&lt;br /&gt;
//Aca lo importante, colocar la opcion soIgnoreInvalidCerts para que haga caso omiso de certificados &amp;nbsp;//vencidos y que siga trabajando &lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;RIO.HTTPWebNode.InvokeOptions :=&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: red;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [soPickFirstClientCertificate ,soIgnoreInvalidCerts, soAutoCheckAccessPointViaUDDI];&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; //Pasar el componentes THTTPRIO como parametro, y listo funciona!!&lt;br /&gt;
&amp;nbsp; ss :=GetServiceSoap(false, defURL, &lt;span style=&quot;color: red;&quot;&gt;RIO&lt;/span&gt;);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; try&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; r := ss.MiMetodo(&#39;Hola mundo&#39;)&lt;br /&gt;
&lt;br /&gt;
...................&lt;br /&gt;
...................&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/808292802056589939/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/06/webservices-y-certificados-vencidos.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/808292802056589939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/808292802056589939'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/06/webservices-y-certificados-vencidos.html' title='WebServices y certificados vencidos'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-4523355892160548841</id><published>2012-04-29T18:24:00.002-03:00</published><updated>2012-04-29T18:24:55.739-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><category scheme="http://www.blogger.com/atom/ns#" term="Reflection"/><title type='text'>Carga dinámica de paquetes y reflexión (Una agradable sorpresa)</title><content type='html'>&lt;b&gt;&lt;u&gt;Introducción&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Hacia años que no tenia que meterme con las&amp;nbsp;características&amp;nbsp;de&amp;nbsp;reflexión&amp;nbsp;de delphi. Había&amp;nbsp;trabajado bastante en .Net pero en Delphi poco y nada. Sabia que en la version 2010 de delphi se&amp;nbsp;había&amp;nbsp;evolucionado mucho en este sentido pero no sabia cuanto y a&amp;nbsp;priori&amp;nbsp;imagina las restricciones obvias de un lenguaje compilado.&lt;br /&gt;
La&amp;nbsp;reflexión&amp;nbsp;seria como la capacidad que tiene nuestro compilador de analizar y accionar sus elementos en tiempo de&amp;nbsp;ejecución.&lt;br /&gt;
En lo que nos toca en esta entrada apuntamos a analizar una clase totalmente desconocida para investigar sus&amp;nbsp;método&amp;nbsp;y eventualmente ejecutarlos.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;¿Para que puede servir?&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Bueno, seguramente&amp;nbsp;habrá&amp;nbsp;mas casos el aqui expuesto, lo que&amp;nbsp;aquí&amp;nbsp;intentamos es simplemente cargar una serie de bpls, investigar sobre las clases y&amp;nbsp;métodos&amp;nbsp;que las mismas contienen y exponerlos. ¿Para que puede servir esto?, en mi caso particular lo que quiero es que se&amp;nbsp;carguen&amp;nbsp;las bpls a modo de funcionalidad agregada, luego quien configura el sistema determina que&amp;nbsp;método&amp;nbsp;se ejecuta&amp;nbsp;según&amp;nbsp;condiciones, pero los&amp;nbsp;métodos&amp;nbsp;disponibles se cargan dinamicamente de las bpls con las que se compra el sistema. Para mejor, se puede ir&amp;nbsp;agregando&amp;nbsp;bpls con mas funcionalidad sin afectar el core del producto.&lt;br /&gt;
Al decidir el configurador/analista que se ejecuta y cuando yo&amp;nbsp;tendré&amp;nbsp;que buscar y ejecutar un&amp;nbsp;método&amp;nbsp;mediante su nombre y para eso necesito las capacidades de&amp;nbsp;reflexión&amp;nbsp;que encuentro mas que aceptables en la&amp;nbsp;versión&amp;nbsp;actual de Delphi.&lt;br /&gt;
Los ejemplos de abajo han sido pelados de todas las cuestiones de bases de datos que tiene que ver con guardar los&amp;nbsp;métodos&amp;nbsp;disponibles y recuperar el&amp;nbsp;método&amp;nbsp;a ejecutar. Solo nos concentramos en lo importante: Como bucear en las bpls y como instanciar una clase y ejecutar un&amp;nbsp;método&amp;nbsp;por sus nombre.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;¿Como cargar las bpls?&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
El siguiente&amp;nbsp;código&amp;nbsp;revisa una carpeta determinada y bpl que encuentra bpl que carga por medio del LoadPackage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;DynamicPackageNames := &amp;nbsp;TStringList.Create;&lt;br /&gt;
&amp;nbsp;sda := TDirectory.GetFiles(ExtractFilePath( Application.ExeName)+&#39;PlugIns\&#39;, &#39;*.bpl&#39;);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; for s in sda do begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; hndl &amp;nbsp;:= LoadPackage(s);&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; DynamicPackageNames.Add(s);&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;br class=&quot;Apple-interchange-newline&quot; /&gt;&lt;br /&gt;
Ahora lo bueno, analizo las clases, pero solo lo hago para los librerias cargadas de las bpls.&lt;br /&gt;
&lt;br /&gt;
....&lt;br /&gt;
&lt;br /&gt;
c : TRttiContext;&lt;br /&gt;
m : TRttiMethod;&lt;br /&gt;
c : TRttiContext;&lt;br /&gt;
t : TRttiType;&lt;br /&gt;
p:TRttiPackage;&lt;br /&gt;
...&lt;br /&gt;
for p in c.GetPackages do begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; //Solo las cargadas de las bpls...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; if DynamicPackageNames.Find(p.Name, Index) then begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //Recorro las clases&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for t in p.GetTypes do begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//Recorro los metodos&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;for m in t.GetMethods do begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //Esto elimina metodos de clases anteriores, como por ejemplo de la&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //Classe TComponent&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if t.Name=m.Parent.ToString then begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //Recorro los parametros de los metodos&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for param in m.GetParameters do begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; end;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; end;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Con el&amp;nbsp;código&amp;nbsp;anterior, se puede bucear hasta el nivel deseado en las clases presentes en la bpls cargadas dinamicamente.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Cuando encuentro lo que busco, ¿Como lo ejecuto?&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;c := TRttiContext.Create;&lt;br /&gt;
&amp;nbsp;ty := c.FindType(&#39;MiClase&#39;) as TRttiInstanceType;&lt;br /&gt;
&amp;nbsp;if Assigned(ty) then begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp;//Encontro la clase que buscaba&lt;br /&gt;
&amp;nbsp; &amp;nbsp;m := ty.GetMethod(&#39;MiMetodo&#39;);&lt;br /&gt;
&amp;nbsp; &amp;nbsp;if Assigned(m) then begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; //Encontro el metodo que buscaba&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; //Construyo una instancia de la clase en cuestion&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; SL := ty.GetMethod(&#39;Create&#39;).Invoke(ty.MetaclassType,[Self]);&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; //Ejecuto el metodo&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; m.Invoke(SL, &amp;nbsp;[param1, param2, paramx]);&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; //Libero el objeto creado&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; SL.AsObject.Free;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;end;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Espero que el&amp;nbsp;código&amp;nbsp;aquí&amp;nbsp;expuesto sea de utilidad ya que no se encuentra con facilidad&amp;nbsp;documentación&amp;nbsp;sobre estos temas. Me parece mas importante el&amp;nbsp;código&amp;nbsp;expuesto que explicar todos los casos donde se puede utilizar la&amp;nbsp;reflexión.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/4523355892160548841/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/04/carga-dinamica-de-paquetes-y-reflexion.html#comment-form' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/4523355892160548841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/4523355892160548841'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/04/carga-dinamica-de-paquetes-y-reflexion.html' title='Carga dinámica de paquetes y reflexión (Una agradable sorpresa)'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-4044113349436194441</id><published>2012-03-06T17:10:00.000-03:00</published><updated>2012-03-06T17:10:48.307-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>IOUtils</title><content type='html'>&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Introducción&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Esta entrada va a ser sumamente corta, estoy preparando algunas cosas mas complejas como carga dinámica de paquetes o reflection pero eso me va a llevar algo mas de mi escaso tiempo.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Mirando el código de un amigo hace unos días, amigo que tiene varios años de experiencia en desarrollo Delphi note algo de desconocimiento sobre las capacidades incluidas dentro de la herramienta en las ultimas versiones.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Se veía mucha programación con le tema de codificación y decodificación de fechas y también mucho código a mano para lo que voy a mostrar ahora, y lo muestro porque justamente lo tuve que hacer para un proyecto en el trabajo y rápidamente me acorde de lo largo y complicado que lo había hecho mi amigo.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-size: large;&quot;&gt;El objetivo&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;El objetivo es sencillo, borrar, mover o lo que sea con algunos archivos que cumplen determinada característica. En este caso particular es simplemente borrar archivos viejos.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Las Herramientas&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Vieja forma, sacada de internet y que casi todos los desarrolladores Delphi hemos usado para encontrar archivos...&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp;procedure FileSearch(const PathName, FileName : string) ;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp;var&lt;br /&gt;
&amp;nbsp; &amp;nbsp;Rec : TSearchRec;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp;Path : string;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp;Path := IncludeTrailingPathDelimiter(PathName) ;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp;if FindFirst (Path + FileName, faAnyFile - faDirectory, Rec) = 0 then&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; try&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;repeat&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ListBox1.Items.Add(Path + Rec.Name) ;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;until FindNext(Rec) &amp;lt;&amp;gt; 0;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp;finally&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; FindClose(Rec) ;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp;end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp;end;&amp;nbsp;&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Nueva Forma....busco archivos, si son viejos los borro&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&amp;nbsp; cachePath := ExtractFilePath( Application.ExeName ) + &#39;AuxFiles\&#39;;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; for s in TDirectory.GetFiles(cachePath) do begin&amp;nbsp;&amp;nbsp;//&amp;lt;-Observar la forma de recorrer el array &quot;For in&quot;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; if TFile.GetCreationTime(s)&amp;lt;IncDay(now, -3) then begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; TFile.Delete(s);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; end;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;En las&amp;nbsp;próximas&amp;nbsp;entradas quiero mostrar como cargar packages de manera&amp;nbsp;dinámica&amp;nbsp;y lo que veo mas importante, poder crear clases y llamar a&amp;nbsp;métodos&amp;nbsp;sin siquiera conocerlos previamente.&lt;br /&gt;
Nos vamos a ayudar con el mejorado (En delphi 2010) RTTI para cumplir con el objetivo.&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/4044113349436194441/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2012/03/ioutils.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/4044113349436194441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/4044113349436194441'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2012/03/ioutils.html' title='IOUtils'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-7527955165207384313</id><published>2011-09-01T16:20:00.001-03:00</published><updated>2011-09-01T16:20:43.431-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Delphi"/><title type='text'>Mi aplicación en Internet</title><content type='html'>Con Delphi tenemos la posibilidad de meter casi todo los componentes y otros recursos dentro del ejecutable. Una aplicacion delphi tradicional no requiere de mucho mas que el ejecutable mismo. Esto&amp;nbsp;facilitaría&amp;nbsp;el deploy.&lt;br /&gt;
En el caso de trabajar con datasnap podriamos publicar nuestra aplicacion en una pequeña aplicacion web y podria ser ejecutada desde cualquier lugar siempre y cuando el servidor datasnap este publico.&lt;br /&gt;
Hasta aca todo parece ir sobre ruedas pero aparecen algunas cuestiones, que casi todo pueda embeberse en el ejecutable no significa que absolutamente todo este incluido, pueden quedarnos cosas afuera.&lt;br /&gt;
Podemos poner como ejemplo alguna DLL&amp;nbsp;imprescindible&amp;nbsp;con&amp;nbsp;algún&amp;nbsp;driver que no puede faltar, incluso&amp;nbsp;algún&amp;nbsp;archivo ini para guardar configuraciones&amp;nbsp;básicas, previas a todo, IP/Puerto etc y&amp;nbsp;&amp;nbsp;no puedo exigirle al usuario que descargue ademas de un ejecutable un archivo ini, un driver de base de datos etc, esto tiene que funcionar con un click&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Solución&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
Arrancamos con el ejemplo mas sencillo, supongamos un archivo ini, donde vamos a guardar&amp;nbsp;dirección&amp;nbsp;ip de mi servidor datasnap y alguna que otra cosa que necesite.&lt;br /&gt;
Cuando alguien descargue nuestra&amp;nbsp;aplicación&amp;nbsp;puede ponerla en alguna carpeta o ejecutarla directamente&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-_mkQlVwkTkg5P7dgxHeqCP_wIdcfAVxJEkFFtBPmaw56rWfNilQFiNlpR-auuRwU38mAVlyKtDC8-7l7Cb33qA8YRYOhGgVDQSnJkWGbWsHMj6dIzWwq55TGbJji8zBEHo9mS58XRZ8h/s1600/Blog1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;215&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-_mkQlVwkTkg5P7dgxHeqCP_wIdcfAVxJEkFFtBPmaw56rWfNilQFiNlpR-auuRwU38mAVlyKtDC8-7l7Cb33qA8YRYOhGgVDQSnJkWGbWsHMj6dIzWwq55TGbJji8zBEHo9mS58XRZ8h/s320/Blog1.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Si decide ejecutar la&amp;nbsp;aplicación&amp;nbsp;correrá&amp;nbsp;en&amp;nbsp;algún&amp;nbsp;directorio que el sistema operativo determine, si se selecciona guardar se&amp;nbsp;pedirá&amp;nbsp;donde colocar el ejecutable. Vamos a tomar como general el caso mas&amp;nbsp;problemático&amp;nbsp;que es cuando seleccionan directamente &quot;Ejecutar&quot;. La&amp;nbsp;solución&amp;nbsp;pensada es colocar un ini&amp;nbsp;inicial&amp;nbsp;en alguna carpeta propietaria del usuario o de la aplicación (Para evitar problemas de permisos entre otras cosas), pero hacerlo si y solo si este archivo aun no existe. Entonces primer problema preguntarle al sistema operativo por la carpeta del usuario,&amp;nbsp;aquí&amp;nbsp;el&amp;nbsp;código con algunos comentarios (Solo coloco la&amp;nbsp;implementación, son&amp;nbsp;métodos&amp;nbsp;de clase)&amp;nbsp;:&lt;br /&gt;
&lt;i&gt;&lt;b&gt;....uses SHFolder, windows, Classes, &amp;nbsp; SysUtils;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;{Opciones posibles&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_DESKTOP&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_INTERNET&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_PROGRAMS&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_CONTROLS&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_PRINTERS&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_PERSONAL&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_FAVORITES&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_STARTUP&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_RECENT&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_SENDTO&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_BITBUCKET&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_STARTMENU&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_DESKTOPDIRECTORY&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_DRIVES&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_NETWORK&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_NETHOOD&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_FONTS&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_TEMPLATES&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_COMMON_STARTMENU&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_COMMON_PROGRAMS&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_COMMON_STARTUP&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_COMMON_DESKTOPDIRECTORY&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_APPDATA&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_PRINTHOOD&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_ALTSTARTUP&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_COMMON_ALTSTARTUP&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_COMMON_FAVORITES&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_INTERNET_CACHE&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_COOKIES&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_HISTORY&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; CSIDL_SYSTEM&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;}&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;class function TGenericsUtils.GetUserIniFile(ApplicationExeName:String):String;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;begin&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; result := ChangeFileExt(IncludeTrailingBackslash( TGenericsUtils.GetSpecialFolderPath(CSIDL_APPDATA))+ExtractFileName(ApplicationExeName), &#39;.ini&#39;);&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;end;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;class function TGenericsUtils.GetSpecialFolderPath(folder : integer) : string;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;const&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp;SHGFP_TYPE_CURRENT = 0;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;var&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp;path: array [0..MAX_PATH] of char;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;begin&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//[Current User]\My Documents&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//CSIDL_PERSONAL;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//All Users\Application Data&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//CSIDL_COMMON_APPDATA;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//[User Specific]\Application Data&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//CSIDL_LOCAL_APPDATA;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//Program Files&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//CSIDL_PROGRAM_FILES;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//All Users\Documents&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;//CSIDL_COMMON_DOCUMENTS;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp;if SUCCEEDED(SHGetFolderPath(0,folder,0,SHGFP_TYPE_CURRENT,@path[0])) then&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;Result := path&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp;else&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;Result := &#39;&#39;;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;b&gt;end;&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
Aquí&amp;nbsp;el&amp;nbsp;método&amp;nbsp;GetUserIniFile me retornara el nombre del ini de mi&amp;nbsp;aplicación, ademas del nombre del archivo esta la ruta completa a el, ruta solicitada al sistema operativo por medio del&amp;nbsp;método GetSpecialFolderPath.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;fn := TGenericsUtils.GetUserIniFile(Application.ExeName);&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; if not FileExists(fn) then begin&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; //Si no existe genero un ini basico.....&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; TGenericsUtils.ExtractResource(&#39;ARCHIVOINI&#39;, fn);&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; end;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
El&amp;nbsp;código&amp;nbsp;anterior pregunta por la existencia del ini, en caso de no existir llama a una&amp;nbsp;método&amp;nbsp;&quot;ExtractResource&quot; que extrae un recurso del ejecutable, un recurso llamada &quot;ARCHIVOINI&quot; porque yo previamente&amp;nbsp;embebí&amp;nbsp;un ini de arranque en el ejecutable, tema que veremos mas adelante, para no tener que tomarme el trabajo de crear todas las secciones y claves que en un archivo ini grande puede exigir varias lineas de&amp;nbsp;código.&lt;br /&gt;
Aquí&amp;nbsp;el&amp;nbsp;código&amp;nbsp;de&amp;nbsp;&quot;ExtractResource&quot;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;i&gt;class procedure TGenericsUtils.ExtractResource(ResName: String; Filename: String);&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;var&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; ResStream: TResourceStream;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;begin&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; ResStream:= TResourceStream.Create(HInstance, ResName, RT_RCDATA);&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; try&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; ResStream.Position:= 0;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; ResStream.SaveToFile(Filename);&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; finally&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; ResStream.Free;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&amp;nbsp; end;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;end;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
Ademas esto me sirve para cuando tenga que embeber una dll y otro elemento que no puedo generar por&amp;nbsp;código.&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;&lt;u&gt;¿Como meto recursos en el ejecutable?&lt;/u&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
El delphi XE es muy sencillo, seleccione el item del menu como indica la figura&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigOT8bHqlEBHm1Yk6JHpUsebi9F9_AuGReqtF1mUrFMu3wBtQ_mT-uXyjzB1viAn-i2uDTu9aX52u5wzbeitjSyDjHK0hKrpO-aMee-ElK2KoLg7QNiswHvNevv6TdulWC29qHjjJvPY7Q/s1600/Blog2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigOT8bHqlEBHm1Yk6JHpUsebi9F9_AuGReqtF1mUrFMu3wBtQ_mT-uXyjzB1viAn-i2uDTu9aX52u5wzbeitjSyDjHK0hKrpO-aMee-ElK2KoLg7QNiswHvNevv6TdulWC29qHjjJvPY7Q/s400/Blog2.jpg&quot; width=&quot;221&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Luego añada los recursos colocando le tipo correspondiente y un nombre que luego sera usado para pedirle al&amp;nbsp;método&amp;nbsp;ExtractResource que realice la&amp;nbsp;extracción&amp;nbsp;deseada&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyefthXdIuh80i773qaWBY8kV3fT1z0E7qceIPdVkfcMpXcH0UaXX71Ybv27BiT33yWyWeZioLPVkyuUSvOKCtG1joxy-x4tPZDOTZLKhLeA0z04YdZrlAm8kPQV_gOzHGFU18vwL_Qj4h/s1600/Blog3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;230&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyefthXdIuh80i773qaWBY8kV3fT1z0E7qceIPdVkfcMpXcH0UaXX71Ybv27BiT33yWyWeZioLPVkyuUSvOKCtG1joxy-x4tPZDOTZLKhLeA0z04YdZrlAm8kPQV_gOzHGFU18vwL_Qj4h/s400/Blog3.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;En la&amp;nbsp;próxima&amp;nbsp;entrada extendemos la&amp;nbsp;solución&amp;nbsp;a modulos, dll, bpls etc&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/7527955165207384313/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2011/09/mi-aplicacion-en-internet.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/7527955165207384313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/7527955165207384313'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2011/09/mi-aplicacion-en-internet.html' title='Mi aplicación en Internet'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-_mkQlVwkTkg5P7dgxHeqCP_wIdcfAVxJEkFFtBPmaw56rWfNilQFiNlpR-auuRwU38mAVlyKtDC8-7l7Cb33qA8YRYOhGgVDQSnJkWGbWsHMj6dIzWwq55TGbJji8zBEHo9mS58XRZ8h/s72-c/Blog1.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-866661458107558063</id><published>2011-08-03T16:47:00.001-03:00</published><updated>2011-08-03T16:56:46.276-03:00</updated><title type='text'>DBExpress - Many to Many (Relaciones muchos a muchos) Parte 2</title><content type='html'>&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;En la ultima entrada vimos como trabajar relaciones muchos a muchos con dbexpress. Analizamos como relacionar los datasets y demás componentes de tal forma que casi sin escribir código logramos que moviéndome sobre un registro me muestre los elementos incluidos en el y los disponibles a ser incluidos. Hasta acá funciono todo sin problemas, ahora llega el momento de meter elementos dentro de los asignados, es decir, tomar elementos disponibles y meterlos en el lote de asignados para dejar luego que dbexpress se encargue de los inserts/deletes relacionados. Usamos un ejemplo de usuarios-permisos por ser sencillo y descriptivo y armamos un form con una grilla superior que muestra los usuarios y dos grillas inferiores mostrando permisos asignados y disponibles.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Pongamos ahora dos botones para que se puedan enviar los permisos de disponibles a asignados y viceversa.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIp3Xw8FxOK3ZtNyNjisIPaumM2230gSge_0lfQ3tL_jUNdvJDDBP3MAAhh_735eqnYjoePHZfADsFGMBMKL1Dq5RMKCTjaAImOMly9taQEoOI8MonI6-f4QQ6q8gKSIPH-mDa47n2OiUf/s1600/1.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;353&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIp3Xw8FxOK3ZtNyNjisIPaumM2230gSge_0lfQ3tL_jUNdvJDDBP3MAAhh_735eqnYjoePHZfADsFGMBMKL1Dq5RMKCTjaAImOMly9taQEoOI8MonI6-f4QQ6q8gKSIPH-mDa47n2OiUf/s640/1.JPG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Hagamos luego también una primera aproximación a la solución en términos de código&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;procedure TFrmUsuario.btnAsignarClick(Sender: TObject);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosAsignados.Insert;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosAsignadosIdPermiso.Value := cdsPermisosDisponiblesIdPermiso.Value;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosAsignados.Post;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosDisponibles.Delete;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;procedure TFrmUsuario.Button1Click(Sender: TObject);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsUsuario.ApplyUpdates(-1);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;procedure TFrmUsuario.Button2Click(Sender: TObject);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsUsuario.CancelUpdates;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Esto funciona y funciona bien si hablamos solo de&amp;nbsp;asignación&amp;nbsp;de permisos.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Asigna correctamente los permisos y se encarga de actualizar la nueva realidad en la tabla de&amp;nbsp;relación, pero solo funciona correcta y completamente hacia un lado, si intentara la inversa, quitar un permiso asignado&amp;nbsp;tendría&amp;nbsp;el problema de que no tengo el campo nombre para llenar el clientDataSet del los permisos disponibles. Algunas modificaciones en el dataset que provee los datos&amp;nbsp;podrían&amp;nbsp;ayudar.&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Lo que originalmente fue:&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;select *&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;from UsuarioPermiso&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Where Login=:Login&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Ahora es:&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;select UsuarioPermiso.*, Permiso.Nombre&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;from UsuarioPermiso inner join Permiso&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;On UsuarioPermiso.IdPermiso=Permiso.IdPermiso&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Where Login=:Login&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red;&quot;&gt;&lt;b&gt;Muy importante ver que el campo Nombre no pertenece a la tabla&amp;nbsp;relación&amp;nbsp;y por tanto no debe ser parte de los inserts y delete, mediante los providerflags de este campo desactivar su participacion en pfInUpdate y en pfInWhere, &amp;nbsp;(En ClientDataSet y DataSet), es un campo invitado en la consulta simplemente para mejorar aspectos de interfaz de usuario.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6sGYsY1ZPH786tdT9e7fYsJPYmnEOhnBkxFduH-RPt2KGzrDT5rRft4v3c5hxUTP-CzWaomSPU8IzBCXAlPjQ4a3own2lgqyflsvi4ZAy6eE4AJrYBw7YsAH-kQ5Gumh4aRs7pfhGmg57/s1600/3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;380&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6sGYsY1ZPH786tdT9e7fYsJPYmnEOhnBkxFduH-RPt2KGzrDT5rRft4v3c5hxUTP-CzWaomSPU8IzBCXAlPjQ4a3own2lgqyflsvi4ZAy6eE4AJrYBw7YsAH-kQ5Gumh4aRs7pfhGmg57/s640/3.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Ahora la interfaz muestra el nombre de los permisos&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4_xDlTFH5vEgLpNu7pA3wh8uuMmBAFS0WjoKTuW_mWtZoIXycTpHl9ucL_H2_2lCrnEHmAOAdlBJDHdO1e9_zVnkklMjZw80IwG7EbziOFNtZNgXQO2AzIfiCcFo7fuuntBsmYinNisVj/s1600/3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;353&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4_xDlTFH5vEgLpNu7pA3wh8uuMmBAFS0WjoKTuW_mWtZoIXycTpHl9ucL_H2_2lCrnEHmAOAdlBJDHdO1e9_zVnkklMjZw80IwG7EbziOFNtZNgXQO2AzIfiCcFo7fuuntBsmYinNisVj/s640/3.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: red;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Finalmente el&amp;nbsp;código&amp;nbsp;quedaría&amp;nbsp;así:&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;procedure TFrmUsuario.btnAsignarClick(Sender: TObject);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosAsignados.Insert;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosAsignadosIdPermiso.Value := cdsPermisosDisponiblesIdPermiso.Value;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosAsignadosNombre.Value := cdsPermisosDisponiblesNombre.Value;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosAsignados.Post;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosDisponibles.Delete;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;procedure TFrmUsuario.btnDesasignarClick(Sender: TObject);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosDisponibles.Insert;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosDisponiblesIdPermiso.Value := cdsPermisosAsignadosIdPermiso.Value;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosDisponiblesNombre.Value := cdsPermisosAsignadosNombre.Value;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosDisponibles.Post;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosAsignados.Delete;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;procedure TFrmUsuario.Button1Click(Sender: TObject);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsPermisosDisponibles.CancelUpdates;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsUsuario.ApplyUpdates(-1);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp;cdsUsuario.Refresh;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;procedure TFrmUsuario.Button2Click(Sender: TObject);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; cdsUsuario.CancelUpdates;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;procedure TFrmUsuario.cdsUsuarioBeforeScroll(DataSet: TDataSet);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; if cdsUsuario.ChangeCount&amp;gt;0 then begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; ShowMessage(&#39;Hay cambios pendientes en el registro actual, los perdera&#39;);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; cdsUsuario.CancelUpdates;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; &amp;nbsp; cdsUsuario.Refresh;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&amp;nbsp; end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Observe que antes de aplicar los cambios cancelo los cambios referentes los registros disponibles, los mismos son resultado del calculo de la consulta sobre lo que esta en la base y no deben tener injerencia sobre la misma. Observe&amp;nbsp;también&amp;nbsp;que esta consulta debe actualizarse constantemente, si aplique un cambio a la base necesito actualizar esto, si me intentan cambiar de registro en usuario y no guardaron los cambios debe preguntar que se debe hacer y guardo y refresco o cancelo todo.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;El objetivo de la entrada es entender la forma el concepto principal, el lector luego puede mejorarlo, incluso se pueden activar/desactivar los botones de&amp;nbsp;asignación&amp;nbsp;y desasignación&amp;nbsp;segun disponibilidad, ese tipo de detalles no&amp;nbsp;serán&amp;nbsp;contemplados&amp;nbsp;aquí.&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/866661458107558063/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2011/08/dbexpress-many-to-many-relaciones.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/866661458107558063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/866661458107558063'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2011/08/dbexpress-many-to-many-relaciones.html' title='DBExpress - Many to Many (Relaciones muchos a muchos) Parte 2'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIp3Xw8FxOK3ZtNyNjisIPaumM2230gSge_0lfQ3tL_jUNdvJDDBP3MAAhh_735eqnYjoePHZfADsFGMBMKL1Dq5RMKCTjaAImOMly9taQEoOI8MonI6-f4QQ6q8gKSIPH-mDa47n2OiUf/s72-c/1.JPG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-8011433424946039810</id><published>2011-07-20T10:31:00.000-03:00</published><updated>2011-07-20T10:31:54.704-03:00</updated><title type='text'>DBExpress - Many to Many (Relaciones muchos a muchos) Parte 1</title><content type='html'>Así&amp;nbsp;como en la entrada&amp;nbsp;&lt;a href=&quot;http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html&quot;&gt;http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html&lt;/a&gt;&amp;nbsp;se presento el tema de las relaciones master-details aparece ahora el interrogante de si podemos tambien manejar las relaciones muchos a muchos de una manera similar.&lt;br /&gt;
Yo digo que si, lo he probado, podemos manejar casi de manera completamente&amp;nbsp;automática&amp;nbsp;las relaciones muchos a muchos, lo&amp;nbsp;único&amp;nbsp;que haremos es ayudarnos con comandos sql para producir el resultado esperado.&lt;br /&gt;
Para empezar pensemos una&amp;nbsp;situación&amp;nbsp;de&amp;nbsp;relación&amp;nbsp;muchos a muchos, propongo la siguiente,&amp;nbsp;didáctica&amp;nbsp;y bien sencilla&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvo2KK3IlrRuvKZPhpIMKvpBitqF5d4edD9UrIv6AeFvQlj03qEiSvX_sHvJz27jFHK1pwJyDJTt96ZCGUDDq2P8K-AduNMp6dQWR9XIfyVKg0GljE_QwHh5kAJ_geWS8Vfko92lMCk7fG/s1600/BlogMuchosAMuchos.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;123&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvo2KK3IlrRuvKZPhpIMKvpBitqF5d4edD9UrIv6AeFvQlj03qEiSvX_sHvJz27jFHK1pwJyDJTt96ZCGUDDq2P8K-AduNMp6dQWR9XIfyVKg0GljE_QwHh5kAJ_geWS8Vfko92lMCk7fG/s640/BlogMuchosAMuchos.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Creo se sobreentiende un usuario tiene muchos permisos y un permiso puede estar en muchos usuarios.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Para plantear esto como un maestro detalle o mejor dicho como un maestro y doble detalle pongamos a cada elemento en su&amp;nbsp;posición&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Usuario-&amp;gt;Maestro&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Permisos asignados-&amp;gt;Detalle 1&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Permisos no asignados-&amp;gt;Detalle 2&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;¿Como quedan las consultas?&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;u&gt;&lt;b&gt;sqlUsuario&lt;/b&gt;&lt;/u&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;select *&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;from Usuario&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;u&gt;&lt;b&gt;sqlPermisosAsignados&lt;/b&gt;&lt;/u&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;select *&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;from UsuarioPermiso&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Where Login=:Login&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;u&gt;&lt;b&gt;sqlPermisosDisponibles&lt;/b&gt;&lt;/u&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;select *&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;from Permiso as p&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Where p.IdPermiso not in&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;(Select IdPermiso&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;from UsuarioPermiso as up&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Where up.Login=:Login)&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Bueno&amp;nbsp;ahí&amp;nbsp;esta la primera&amp;nbsp;aproximación, luego veremos si es suficiente o tenemos que mejorar&amp;nbsp;algún&amp;nbsp;aspecto,&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;sqlUsuario no merece&amp;nbsp;explicación, sqlPermisoAsignados casi que tampoco, son los permisos que le usuario ya tiene asignado y podemos considerarlo como un detalle del usuario, sqlPermisosDisponibles son todos los permisos que no tiene el usuario tema resuelto con un &quot;Not In&quot; el lector puede usar un Exists si prefiere y&amp;nbsp;también&amp;nbsp;lo podemos considerar un detalle del usuario, de hecho como esta planteado el&amp;nbsp;único&amp;nbsp;parámetros&amp;nbsp;de las consultas a las que consideramos detalle es el login del usuario, dato presente en el maestro,&amp;nbsp;condición&amp;nbsp;necesaria y suficiente para armar nuestros master-details en DBExpress&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Así&amp;nbsp;quedaría&amp;nbsp;la cosa, recordar enlazar los dataset detalle por su propiedad DataSource al DataSource llamado en este caso &quot;datUsuario&quot;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqfdI_3lMCi2MGF8Uszjw4YzVkkghmkJnV9qXxm3uPDmquntWRSOL9YhLMaBkNuXOcHqLH7Nn5f1b9pr21BTd6NG0XeXgT4dOEE_SwlNW95qO_rwb8JwnzceF6aqmLJkjyo-WgdIDPilzv/s1600/BlogTemp1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqfdI_3lMCi2MGF8Uszjw4YzVkkghmkJnV9qXxm3uPDmquntWRSOL9YhLMaBkNuXOcHqLH7Nn5f1b9pr21BTd6NG0XeXgT4dOEE_SwlNW95qO_rwb8JwnzceF6aqmLJkjyo-WgdIDPilzv/s400/BlogTemp1.jpg&quot; width=&quot;378&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Llegado este punto terminamos con el servidor, llega la hora del cliente.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Siguiente lo mostrado en la entrada&amp;nbsp;&lt;a href=&quot;http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html&quot;&gt;http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html&lt;/a&gt;&amp;nbsp;la cosa&amp;nbsp;quedaría&amp;nbsp;así, tanto los permisos disponibles como los permisos asignados son detalles del usuario&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-5R_BKy6IhiAlg5rBdKMZidi1nWH8TB6nDx24rU9KJGY84IzWGMNItubUMtD-sROJM1XJDtFqXN-cqOEI7OJ6YUPM1skK-WNyJ8ScSpEsuCEZSrBiUgqCQ1h4ogkv6sP7Zu2i3dAG351U/s1600/BlogTempClienteMuchosAMuchos.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;386&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-5R_BKy6IhiAlg5rBdKMZidi1nWH8TB6nDx24rU9KJGY84IzWGMNItubUMtD-sROJM1XJDtFqXN-cqOEI7OJ6YUPM1skK-WNyJ8ScSpEsuCEZSrBiUgqCQ1h4ogkv6sP7Zu2i3dAG351U/s640/BlogTempClienteMuchosAMuchos.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Relaciono las grillas los datasources etc, pongo algunos datos y abro solo el clientedataset maestro al abrir la ventana&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;procedure TFrmUsuario.FormCreate(Sender: TObject);&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;begin&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&amp;nbsp; cdsUsuario.Open;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;end;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;y lo pruebo a ver que tal funciona.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRkU5cDIIxP4z63CEyxLPL-e2yolF1Lm0FltnOynP8pkHiDliPu8RlddKPNII-ok_Q1xhAnmKTKfeEKONnsM0IOzRjErLtKAAvERonVJBrIscDsay4xNekY-VhCb_9VuXm1mwvDjGjoh-4/s1600/BlogTempForm.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;363&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRkU5cDIIxP4z63CEyxLPL-e2yolF1Lm0FltnOynP8pkHiDliPu8RlddKPNII-ok_Q1xhAnmKTKfeEKONnsM0IOzRjErLtKAAvERonVJBrIscDsay4xNekY-VhCb_9VuXm1mwvDjGjoh-4/s640/BlogTempForm.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Perfecto, me muevo entre usuarios y sus permisos disponibles y asignados se actualizan&amp;nbsp;automáticamente.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Claro, la critica&amp;nbsp;acá&amp;nbsp;puede ser de que debo mostrar las descripciones de los permisos en permisos asignados, es un tema que dejamos para mas adelante ya que no hace a la diferencia en cuanto a&amp;nbsp;programación, lo importante es entender la idea. Con esto tenemos el 70% del problema resuelto y solo escribimos una linea de&amp;nbsp;código.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;En la&amp;nbsp;próxima&amp;nbsp;entrada vemos la&amp;nbsp;actualización&amp;nbsp;de los permisos con este mismo esquema.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/8011433424946039810/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2011/07/dbexpress-many-to-many-relaciones.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/8011433424946039810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/8011433424946039810'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2011/07/dbexpress-many-to-many-relaciones.html' title='DBExpress - Many to Many (Relaciones muchos a muchos) Parte 1'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvo2KK3IlrRuvKZPhpIMKvpBitqF5d4edD9UrIv6AeFvQlj03qEiSvX_sHvJz27jFHK1pwJyDJTt96ZCGUDDq2P8K-AduNMp6dQWR9XIfyVKg0GljE_QwHh5kAJ_geWS8Vfko92lMCk7fG/s72-c/BlogMuchosAMuchos.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-3002475513540696326</id><published>2011-07-14T20:34:00.001-03:00</published><updated>2011-07-14T20:37:18.741-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DataSnap"/><category scheme="http://www.blogger.com/atom/ns#" term="DBExpress"/><title type='text'>Master-Details y Autoincrementales</title><content type='html'>Ahora si, este tema no puedo decir que no esta documentado, he encontrado tutoriales y papers que describen el problema, eso si, siempre en Ingles y tampoco son tantos los lugares donde uno pueda&amp;nbsp;encontrar&amp;nbsp;una&amp;nbsp;solución&amp;nbsp;a este asunto.&lt;br /&gt;
Como vimos en la entrada&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html&quot;&gt;http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: black;&quot;&gt;&lt;span style=&quot;font-family: &#39;Times New Roman&#39;;&quot;&gt;&lt;span style=&quot;font-style: normal;&quot;&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;DBExpress maneja&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; muy bien la idea de maestro detalle, lo maneja como un elemento único simplificando el desarrollo, es mas, solo se encarga de llenar el campo de relación en el detalle y lo llena correctamente con el identificado del maestro.&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;Rapidamente aparece un problema con los autoincrementales, el valor clave del maestro lo pone la base, cuando dbexpress intenta insertar los registros detalles no sabe la clave del maestro, de hecho el problema aparece antes ¿Que clave lleva el detalle en el ClientDataSet cuando siquiera se la clave que va a tener el maestro?&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;Primero ataquemos el problema que acabamos de mencionar, voy a cambiar la base de datos de ejemplo vista en las entradas anteriores para indicar que ahora el idPedido es autoincremental, en una oracle sera colocar un trigger, en Interbase un generator o como sea según motor, la idea es que el valor lo pone la base y no yo.&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_HYsjeJPFW0_STK64Taj3ipuFQuArhJgEhHf9yxVJwkaPcpdSM7gTb4sy8WiNR_1y1Y_2LWKmCU8-yu4UA7LDUhr5hkxfjIYU9WI_0yTAAyWbPm9CYnh2kXIjXvIN0aheJRqMnEWAvJZw/s1600/BlogOnNewRecordEvent.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;384&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_HYsjeJPFW0_STK64Taj3ipuFQuArhJgEhHf9yxVJwkaPcpdSM7gTb4sy8WiNR_1y1Y_2LWKmCU8-yu4UA7LDUhr5hkxfjIYU9WI_0yTAAyWbPm9CYnh2kXIjXvIN0aheJRqMnEWAvJZw/s640/BlogOnNewRecordEvent.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;Como ven, el clientDataSet(Maestro) tiene un evento que se ejecuta cuando hay un nuevo registro, tomemos esto para colocar un IdPedido temporal o comodín si así lo quieren llamar. Luego los detalles se generaran con este IdPedido comodín.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;procedure TFrmPedido.cdsPedidoNewRecord(DataSet: TDataSet);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&amp;nbsp; DataSet.FieldByName(&#39;IdPedido&#39;).Value := -1;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;end;&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLhULSm1-ZkoPt0wEAC6j_YCLoPrdALVwedy9tVLiM1cmqdoWT77D-hlKhvYgOlKT6BEFsbuwTfofMIWNk57-mXo8VeijuBcPWUVZKDgqYs6a10HNRmFqxl2xQRh4zjHbfMXNQ5hsLGtkZ/s1600/BlogOnNewRecordEvent.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;384&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLhULSm1-ZkoPt0wEAC6j_YCLoPrdALVwedy9tVLiM1cmqdoWT77D-hlKhvYgOlKT6BEFsbuwTfofMIWNk57-mXo8VeijuBcPWUVZKDgqYs6a10HNRmFqxl2xQRh4zjHbfMXNQ5hsLGtkZ/s640/BlogOnNewRecordEvent.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Esto es una&amp;nbsp;simplificación, si yo intentara ingresar mas registros maestros&amp;nbsp;fallaría&amp;nbsp;porque&amp;nbsp;crearía&amp;nbsp;dos registros con IdPedido=-1,&amp;nbsp;solución&amp;nbsp;y truco para esto.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
procedure TFrmPedido.cdsPedidoNewRecord(DataSet: TDataSet);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; DataSet.FieldByName(&#39;IdPedido&#39;).Value := DataSet.FieldByName(&#39;IdPedido&#39;).Tag - 1;&lt;br /&gt;
&amp;nbsp; DataSet.FieldByName(&#39;IdPedido&#39;).Tag := DataSet.FieldByName(&#39;IdPedido&#39;).Value;&lt;br /&gt;
end;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Ayudándonos&amp;nbsp;con la propiedad tag y sin declarar mas variables hacemos que nuestro IdPedido&amp;nbsp;comodín&amp;nbsp;se incremente hacia el negativo. Vamos a usar es breve este valor comodín.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;Ahora el siguiente problema, si el valor lo IdPedido lo pone la base, entonces no lo pongo yo.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;¿Como le digo a DBExpress insertame todos los campos menos este que lo hace la base de datos?&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;La respuesta es simple, del lado servidor (Suponiendo trabajo con DataSnap) buscamos el DataSet, seleccionamos en campo y en providerflags ponemos el pfInUpdate en false, con esto cuando se genere el insert DBExpress dejara fuera a este campo. La figura muestra como hacerlo.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgluywyhosUeEDxqmCtHerV7VEEdFiCoWdapMkPNwDZIwQPrW4fCBoRyqDx3JYW5jVp2rUnGWUL9HsSXnUSI_Wh4jz32FE2lDcgqdN4rqT0dE3oN6cbqqoUnxRxHa2PpfXTq37gcpSds0L-/s1600/blogpfUpdate.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;274&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgluywyhosUeEDxqmCtHerV7VEEdFiCoWdapMkPNwDZIwQPrW4fCBoRyqDx3JYW5jVp2rUnGWUL9HsSXnUSI_Wh4jz32FE2lDcgqdN4rqT0dE3oN6cbqqoUnxRxHa2PpfXTq37gcpSds0L-/s640/blogpfUpdate.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;En esta entrada&amp;nbsp;&lt;a href=&quot;http://pablosoligo.blogspot.com/2011/07/logica-del-negocio.html&quot;&gt;http://pablosoligo.blogspot.com/2011/07/logica-del-negocio.html&lt;/a&gt;&amp;nbsp;&amp;nbsp;se demuestra que puedo tener injerencia en los datos justo antes de ser insertados efectivamente, ¿Como usar esto a mi favor y poner en orden el tema de las claves en este maestro-detalle?&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;El SqlServer se encargara de poner el valor de IdPedido al maestro, es mi responsabilidad ponerlos en el detalle. Como vimos en la entrada anterior&amp;nbsp;puedo meterme justo antes de que se inserte el registro e interferir en la operación, veamos como:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;procedure TSMPedido.dspPedidoBeforeUpdateRecord(Sender: TObject;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; var Applied: Boolean);&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; inherited;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; if (UpdateKind=ukInsert) and (SourceDS=sqlPedido) then begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; &amp;nbsp; DeltaDs.FieldByName(&#39;FechaHora&#39;).NewValue := Now();&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; if (UpdateKind=ukInsert) and (SourceDS=sqlItemPedido) and (DeltaDS.FieldByName(&#39;IdPedido&#39;).NewValue&amp;lt;0) then begin&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; sqlTableIdentity.Close;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; sqlTableIdentity.ParamByName(&#39;TableName&#39;).Value := &#39;Pedido&#39;;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; sqlTableIdentity.Open;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; DeltaDS.FieldByName(&#39;IdPedido&#39;).NewValue &amp;nbsp;:= sqlTableIdentity.FieldByName(&#39;Identidad&#39;).Value;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&amp;nbsp; end;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;end;&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;sqlTablaIdenty es un TSqlDataSet con el siguiente CommandText&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
SELECT IDENT_CURRENT(:TableName) as Identidad&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; widows: 2;&quot;&gt;En sqlServer retorna la identidad para una tabla en una conexión determinada, el lector sabrá como hacerlo en su motor de base de datos favorito, si utilizo un esquema de herencia para la creacion de servermodules mucho mejor porque puede poner este sqldataset en el servermodule padre y tenerlo listo en cualquier server module donde lo necesite usar.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; widows: 2;&quot;&gt;Por lo demas lo que se hace es preguntar si es una inserción, si el dataset origen es el del detalle y si el valor de idPedido del detalle es negativo, pensemos que me puede estar insertando un detalle mas en un pedido previamente creado que ya tiene su IdPedido correctamente generado, ahí no necesito preguntar a la base y asignarlo por la fuerza.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0cm; orphans: 2; widows: 2;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/3002475513540696326/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2011/07/master-details-y-autoincrementales.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/3002475513540696326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/3002475513540696326'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2011/07/master-details-y-autoincrementales.html' title='Master-Details y Autoincrementales'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_HYsjeJPFW0_STK64Taj3ipuFQuArhJgEhHf9yxVJwkaPcpdSM7gTb4sy8WiNR_1y1Y_2LWKmCU8-yu4UA7LDUhr5hkxfjIYU9WI_0yTAAyWbPm9CYnh2kXIjXvIN0aheJRqMnEWAvJZw/s72-c/BlogOnNewRecordEvent.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-1374705601164476237</id><published>2011-07-10T16:44:00.003-03:00</published><updated>2011-07-14T16:52:11.671-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DataSnap"/><title type='text'>Lógica del negocio</title><content type='html'>Es sabido, y existen tutoriales y&amp;nbsp;vídeos&amp;nbsp;que explican como crear&amp;nbsp;métodos&amp;nbsp;en datasnap y consumirlos desde una&amp;nbsp;aplicación&amp;nbsp;cliente, ya sea Delphi, ASP.NET, PHP etc. Existe&amp;nbsp;también&amp;nbsp;muchos tutoriales y&amp;nbsp;vídeos&amp;nbsp;que explican como utilizar la interfaz IAppServer.&lt;br /&gt;
Muchos nos sentimos muy tentados a utilizar intensivamente la interfaz IAppServer, principalmente por su facilidad y rapidez. En entradas anteriores dejamos pendiente el tema de los autoincrementales en relaciones maestro-detalle con DataSnap&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html&quot;&gt;http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
lo que voy a mostrar es por un lado la puerta de entrada es a resolver el problema&amp;nbsp;mencionado, pero es mucho mas que eso.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;¿Si utilizo la&amp;nbsp;interfaz&amp;nbsp;IAppServer como y donde genero mi&amp;nbsp;lógica&amp;nbsp;del negocio?&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
La&amp;nbsp;tentación&amp;nbsp;de usar esta interfaz es muy grande, pero si los componentes generar&amp;nbsp;automáticamente&amp;nbsp;todo, ¿Como puedo yo meter mi&amp;nbsp;lógica&amp;nbsp;en todo este automatismo?&lt;br /&gt;
Existen varios lugares pero quiero proponer el que viene acompañado de mas&amp;nbsp;información&amp;nbsp;para la&amp;nbsp;aplicación&amp;nbsp;efectiva&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmN6akvp4l-D5_KnflCNe8rXZVugGjeM0TDeRBKSghRqKBI02qGfohSnWK18pOCRdj8H25NNYkyQsEYz4bf4UvD9RQz3zVuimhq-63xDIYBAd4ctVEovpIZr0EfS4ENJlU_W7y9lA3GT6x/s1600/tempBlog1.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;257&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmN6akvp4l-D5_KnflCNe8rXZVugGjeM0TDeRBKSghRqKBI02qGfohSnWK18pOCRdj8H25NNYkyQsEYz4bf4UvD9RQz3zVuimhq-63xDIYBAd4ctVEovpIZr0EfS4ENJlU_W7y9lA3GT6x/s640/tempBlog1.JPG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Como muestra la figura el TDataSetProvider tiene dos eventos que nos&amp;nbsp;serán&amp;nbsp;muy&amp;nbsp;útiles, BeforeUpdateRecord y AfterUpdateRecord. Tomemos el primero, generemos el&amp;nbsp;código&amp;nbsp;del evento y veamos que podemos hacer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
procedure TSMPedido.dspPedidoBeforeUpdateRecord(Sender: TObject;&lt;br /&gt;
&amp;nbsp; SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind;&lt;br /&gt;
&amp;nbsp; var Applied: Boolean);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; inherited;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; if (UpdateKind=ukInsert) and (SourceDS=sqlPedido) then begin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; DeltaDs.FieldByName(&#39;FechaHora&#39;).NewValue := Now();&lt;br /&gt;
&amp;nbsp; end;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aunque muy simple el&amp;nbsp;código&amp;nbsp;de arriba nos presenta una idea de lo que podemos hacer. El evento como su nombre lo indica se ejecuta justo antes de insertar/modifica/borrar el registro.&lt;br /&gt;
En el ejemplo, muy simple, lo&amp;nbsp;único&amp;nbsp;que hacemos es preguntar si es una&amp;nbsp;inserción, de ser&amp;nbsp;así&amp;nbsp;ponemos la fecha hora que nos de el sistema. DeltaDS contiene los registros que cambiaron, la diferencia entre los datos que salieron del servidor y los que volvieron del cliente.&lt;br /&gt;
Parándonos sobre un registro y un campo con OldValue, NewValue podemos acceder a esa diferencias, incluso en este caso pisamos la fecha con el valor que nos retorne el sistema. Podemos incluso liberar a la&amp;nbsp;aplicación&amp;nbsp;cliente de esta responsabilidad y dejar que el servidor de&amp;nbsp;aplicación&amp;nbsp;lo haga.&lt;br /&gt;
&lt;br /&gt;
Esto que ponemos&amp;nbsp;aquí&amp;nbsp;es&amp;nbsp;didáctico, pero ya nos da la pauta de que es posible justo antes o justo&amp;nbsp;después&amp;nbsp;de actualizar un registro poner nuestra&amp;nbsp;lógica, modificar valores, remplazar, e incluso tocar otras tablas que&amp;nbsp;estén&amp;nbsp;relacionadas. A modo de ejemplo luego de insertar/modificar/borrar un&amp;nbsp;ítem&amp;nbsp;de un pedido debo actualizar los stocks, luego de actualizar la temperatura de&amp;nbsp;algún&amp;nbsp;sensor puedo generar alguna alarma etc.&lt;br /&gt;
Para mejor, los&amp;nbsp;parámetros&amp;nbsp;me dan acceso a los elementos involucrados en la&amp;nbsp;operación&amp;nbsp;e incluso me dejan ver si es un insert, un update o un delete.</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/1374705601164476237/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2011/07/logica-del-negocio.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/1374705601164476237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/1374705601164476237'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2011/07/logica-del-negocio.html' title='Lógica del negocio'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmN6akvp4l-D5_KnflCNe8rXZVugGjeM0TDeRBKSghRqKBI02qGfohSnWK18pOCRdj8H25NNYkyQsEYz4bf4UvD9RQz3zVuimhq-63xDIYBAd4ctVEovpIZr0EfS4ENJlU_W7y9lA3GT6x/s72-c/tempBlog1.JPG" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-5117330174823076359</id><published>2011-07-04T17:00:00.001-03:00</published><updated>2011-07-04T17:01:09.546-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DBExpress"/><title type='text'>DBExpress - Master-Detail</title><content type='html'>&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Es posible anidar dataset en dbexpress, utilidad muy interesante para casos de tablas relacionadas tipo master-detail. Existe buena documentación sobre esto en internet y quiero usar esta entrada como introducción a las próximas donde se ve un tema menos documentado que es el de los autoincrementales en casos de maestro-detalle.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;DBExpress permite anidar DataSet para tablas de tipo maestro-detalle hasta un limite cercano a los 15 o 16 dataset, quien escribe nunca supero los 5 o 6 y en este sentido nunca tuve mayores problemas.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;u&gt;&lt;b&gt;¿Por que yo querría trabajar con dataset anidados?&lt;/b&gt;&lt;/u&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Bueno las ventajas son varias, en principio manejar todos los elementos de manera única, cosa que es una realidad, si el maestro fuera una tabla de pedidos y me paro sobre un pedido particular quiero ver, borrar, editar y añadir items de ese pedido y no de otros.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Para mejor cuando actualizo quiero una actualización en un bloque transaccional, para todo lo relacionado, maestro y detalle.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;b&gt;&lt;u&gt;¿Como genero un conjunto de dataset maestro-detalle en delphi?&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Es fácil, con un poco de practica sale como pan caliente, pero obviamente hay que relacionar varias cosas de manera ordenada así que naturalmente puede aparecer alguna complicación las primeras veces.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Una imagen, mil palabras.  &lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXj2vr3QFX1mHn0MWI5278tcUUrBKokGfODb_UXvs1wVzmulR6PDGbp9Fxa4FtDaJYqWDGQA19T9O4_SXvdMoRWOLdOzqy-bepsLXJFe2j14IpdNIdLFGiGARL7ZfdQ4VvGBLjMyg7BTZO/s1600/MasterDetailconnection.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXj2vr3QFX1mHn0MWI5278tcUUrBKokGfODb_UXvs1wVzmulR6PDGbp9Fxa4FtDaJYqWDGQA19T9O4_SXvdMoRWOLdOzqy-bepsLXJFe2j14IpdNIdLFGiGARL7ZfdQ4VvGBLjMyg7BTZO/s1600/MasterDetailconnection.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;La imagen anterior muestra los diferentes componentes y sus conexiones, figura en el texto de la propiedad a conectar y la flecha la dirección de conexión. Las consultas en cada uno de los datasets serian las siguientes.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;u&gt;SqlPedido:&lt;/u&gt;&lt;span style=&quot;text-decoration: none;&quot;&gt; &lt;/span&gt;Select * from Pedido&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;u&gt;SqlItemPedido:&lt;/u&gt;&lt;span style=&quot;text-decoration: none;&quot;&gt; Select&lt;/span&gt; * from ItemPedido Where IdPedido=:IdPedido&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Se observa en la consulta de SqlItemPedido un parametro, IdPedido, el parametro debe tener el mismo nombre que la columna de la tabla maestra.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Añadiendo un y solo un datasetProvider conectado al dataset maestro (En este caso sqlPedido) tenemos solucionada “la parte servidora” independientemente de si es una aplicación multicapa o no. Si fuera una simple aplicación cliente/servidor entendamos que la parte servidora son las conexiones a la base de datos, los datasets y los providers, la parte cliente son los clientsdataset involucrados.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;La &quot;Parte servidora&quot;&amp;nbsp;quedaría&amp;nbsp;entonces&amp;nbsp;así&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizsiA4MpTw8XqF5Nx8GoBqGtbokBmf_Pp-vxj39phZdyYfKGE0sxXHZlXBsah3yAg3ZiKIr7YctBQjrzrAKea3IyiTWz0qV-hT8xgQWyyZJRsGkmQGQC1vvZbun49JOaxOOXJ73n-uPF3r/s1600/MasterDetail2.JPG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;283&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizsiA4MpTw8XqF5Nx8GoBqGtbokBmf_Pp-vxj39phZdyYfKGE0sxXHZlXBsah3yAg3ZiKIr7YctBQjrzrAKea3IyiTWz0qV-hT8xgQWyyZJRsGkmQGQC1vvZbun49JOaxOOXJ73n-uPF3r/s400/MasterDetail2.JPG&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0cm;&quot;&gt;Ahora llega el momento de configurar la parte cliente, aca la cosa puede ser muy simple o se puede complicar un poco depende del diseño de base de datos.&lt;br /&gt;
Esta seria la forma del lado cliente, dos clientdatasets uno para la tabla maestra y otro para la tabla detalle, dos datasources enlazados y dos grillas, completando dos navigators por si son necesarios y un boton para efectuar el applyUpdate que llevara los cambios a la base de datos.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjfOOMwI87T9CzpzBpGmqRwGIlnYdCxWV0I5a6VnLlPjXbwy9u1qniKNFO0aZcZojHHtP8BikjZTXJlAYW45Z_X7bCKssD62N_7rFYajV2hmC2Cax23Svl2VGhJwCHnFSy6g8WjtUWiM0y/s1600/MasterDetail.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;241&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjfOOMwI87T9CzpzBpGmqRwGIlnYdCxWV0I5a6VnLlPjXbwy9u1qniKNFO0aZcZojHHtP8BikjZTXJlAYW45Z_X7bCKssD62N_7rFYajV2hmC2Cax23Svl2VGhJwCHnFSy6g8WjtUWiM0y/s400/MasterDetail.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Muy importante, el ApplyUpdate solo debe ejecutarse sobre el clientdataset maestro, DBExpress se encargara del detalla en el orden correspondiente&amp;nbsp;según&amp;nbsp;sea&amp;nbsp;inserción,&amp;nbsp;edición&amp;nbsp;o borrado.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
procedure TFrmPedido.btnApplyUpdateClick(Sender: TObject);&lt;br /&gt;
begin&lt;br /&gt;
&amp;nbsp; cdsPedido.ApplyUpdates(-1);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
Para saber si todo va bien basta con generar los campos en el clientdataset maestro como se indica abajo.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7Vtx2lR_Fu4DklPTLdfyW4RpDleGF0-L3YiwQ3I5_SUezj4Ryj_pSzDS8oRHG_mWP3uelb_hUypfFlBagVZzFvBHcGHkBulW85HQ0_1Yui2KHF49YROOEIAd9R8nAQ3CzidVr991X1hti/s1600/TempMasterDetails4.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;392&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7Vtx2lR_Fu4DklPTLdfyW4RpDleGF0-L3YiwQ3I5_SUezj4Ryj_pSzDS8oRHG_mWP3uelb_hUypfFlBagVZzFvBHcGHkBulW85HQ0_1Yui2KHF49YROOEIAd9R8nAQ3CzidVr991X1hti/s640/TempMasterDetails4.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFFEtjoBHRAp2T4G8kjL1uuImF18M_XCt0OU_XC9Ue5g-oF3OwmPZoDYsDbWAPaAAy28JyJursIxrcwRNS-MGsOUqOBLsvgain0hciWNI3SVmgwWhCZjC-sFDkvYRM6NyVkZy8Dpg0ZoPY/s1600/TempMasterDetails5.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;384&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFFEtjoBHRAp2T4G8kjL1uuImF18M_XCt0OU_XC9Ue5g-oF3OwmPZoDYsDbWAPaAAy28JyJursIxrcwRNS-MGsOUqOBLsvgain0hciWNI3SVmgwWhCZjC-sFDkvYRM6NyVkZy8Dpg0ZoPY/s640/TempMasterDetails5.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Si se observa un campo mas con el nombre del dataset detalle del lado servidor nos quedamos tranquilos, conectamos todo bien y estamos listos para dar el toque final.&lt;br /&gt;
Lo que nos queda por hacer ahora es hacer apuntar en el clientDataSet detalle el DataSetField al campo sqlItemPedido del clientDataSet maestro.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_H9VjYpR7K-R6MelEiOvsOJ75eOxM1WcX0W7srktvR0ewVm8oye1GRbmWnbNCbe8dJ6zlCKvS73DBejiAiRflxRyLVL6zT89VU5nWuko8vocCd9qYcFV2tkKlOnko-q9HD0QxMX1diqQF/s1600/TempMasterDetails.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;411&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_H9VjYpR7K-R6MelEiOvsOJ75eOxM1WcX0W7srktvR0ewVm8oye1GRbmWnbNCbe8dJ6zlCKvS73DBejiAiRflxRyLVL6zT89VU5nWuko8vocCd9qYcFV2tkKlOnko-q9HD0QxMX1diqQF/s640/TempMasterDetails.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Con esto es suficiente para el clientDataSet detalle, todo lo va a manejar el maestro y en el detalle solo veremos los registros correspondiente al registro maestro actual. Incluso podemos ver que dbexpress genera&amp;nbsp;automáticamente&amp;nbsp;en el detalle el id del maestro correspondiente.&lt;br /&gt;
Podemos añadir, borrar, editar y el applyUpdate que usaremos es el del clientDataSet maestro que se encargara de todo.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrp4pWtE1EoCWhcukOy4qgWbWwf63_DtWJPrpBCoSHxNRuUiNWqGNP1kH6sOxaBfTdv9E_l9ZNDUFxG7plRlfy_dBY9RnCCgZ0CWUajRWppvfjjGa8lpsiTEDNIWVJ3oBkr8rB1lKAzOHV/s1600/TempMasterDetails2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;385&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrp4pWtE1EoCWhcukOy4qgWbWwf63_DtWJPrpBCoSHxNRuUiNWqGNP1kH6sOxaBfTdv9E_l9ZNDUFxG7plRlfy_dBY9RnCCgZ0CWUajRWppvfjjGa8lpsiTEDNIWVJ3oBkr8rB1lKAzOHV/s640/TempMasterDetails2.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;b&gt;Hilando un poco mas fino&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
En aplicaciones reales algunos cosas que no debemos dejar pasar.&lt;br /&gt;
&lt;br /&gt;
¿Traemos todos los detalles juntos o los traemos a medida que nos vamos desplazando por el maestro?&lt;br /&gt;
&lt;br /&gt;
Esto en realidad depende de la cantidad de datos, del tamaño etc, lo importante es saber donde determinar esto y yo he encontrado sumamente&amp;nbsp;útil&amp;nbsp;en variedad de casos&amp;nbsp;retrasar&amp;nbsp;el&amp;nbsp;envío&amp;nbsp;del detalle en el momento que se necesite&lt;br /&gt;
Como muestra la figura una de las opciones del datasetProvider es poFetchDetailsOnDemand, esta propiedad determina si los detalle se&amp;nbsp;envían&amp;nbsp;sobre demanda o todos al mismo tiempo.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibEAKJzoAcHlgZ1bXKL3rny5QzGPC2CazqCZ71u77X0vlge6bQ3W_YmprigcLbi37-CCSW0Q6dFkacOun5C1jEpjXj_FY_Vd5zsbKdFMBWzTtfdTJx9pRBDN9aA3NeDh_UcDEsGG9T0Z1p/s1600/TempMasterDetails3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;346&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibEAKJzoAcHlgZ1bXKL3rny5QzGPC2CazqCZ71u77X0vlge6bQ3W_YmprigcLbi37-CCSW0Q6dFkacOun5C1jEpjXj_FY_Vd5zsbKdFMBWzTtfdTJx9pRBDN9aA3NeDh_UcDEsGG9T0Z1p/s640/TempMasterDetails3.jpg&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Ahora sabemos crear master-detail&amp;nbsp;condición&amp;nbsp;necesaria para encarar un problema un poco mas dificil y menos documentado de como combinar esto con los autoincrementales que tanto nos gustan, incluso si no fueran autoincrementales es muy probable que el IdPedido sea responsabilidad de la base de datos y no nuestra.&lt;br /&gt;
La manera de resolver esto y otros temas quedan para próximas entradas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/5117330174823076359/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/5117330174823076359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/5117330174823076359'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2011/07/dbexpressmaster-detail.html' title='DBExpress - Master-Detail'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXj2vr3QFX1mHn0MWI5278tcUUrBKokGfODb_UXvs1wVzmulR6PDGbp9Fxa4FtDaJYqWDGQA19T9O4_SXvdMoRWOLdOzqy-bepsLXJFe2j14IpdNIdLFGiGARL7ZfdQ4VvGBLjMyg7BTZO/s72-c/MasterDetailconnection.jpg" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1079486184614702376.post-3374546166735598830</id><published>2011-06-20T12:26:00.004-03:00</published><updated>2011-06-21T11:05:19.084-03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DBExpress"/><title type='text'>¿Y cuanto duran tus transacciones?</title><content type='html'>Mientras miraba de reojo un servidor de&amp;nbsp;aplicación&amp;nbsp;funcionando observo el mensaje &quot;Begin transaction module bla bla..&quot;, le presto un poco de&amp;nbsp;atención&amp;nbsp;y me pongo en espera &amp;nbsp;del &quot;Commit transaction.....&quot;. (Este servidor de&amp;nbsp;aplicación&amp;nbsp;va logueando en pantalla algunas de las tareas que va realizando).&lt;br /&gt;
Sucede entonces que los segundos pasan y nada....y pasan y nada, y de repente &quot;Commit transaction&quot;. ¿Que paso&amp;nbsp;acá? La base de datos no esta sobrecargada, yo la monitoreo, ¿Como puede tardar tanto una&amp;nbsp;transacción&amp;nbsp;? Nos han enseñado una y otra vez que las transacciones deben ser cortas, tan cortas como sea posible. Cuando profundizo en el tema veo con horror los siguiente, esta&amp;nbsp;transacción&amp;nbsp;abarca entre 6 y 10 tablas y ante una&amp;nbsp;situación&amp;nbsp;anormal (Bastante improbable por suerte) la&amp;nbsp;aplicación&amp;nbsp;comienza a preguntar al usuario si quiere resolverlo de tal o cual manera, y mientras tanto la&amp;nbsp;transacción&amp;nbsp;abierta. Problema encontrado, problema solucionado y ahora&amp;nbsp;acá&amp;nbsp;viene el tema ¿Esta esto pasando en varios lugares o fue esta la&amp;nbsp;única&amp;nbsp;&quot;patinada&quot; de toda la&amp;nbsp;aplicación? ¿Como saberlo?&lt;br /&gt;
&lt;br /&gt;
En la entrada&lt;br /&gt;
&lt;a href=&quot;http://pablosoligo.blogspot.com/2011/06/dbexpress-trace.html&quot;&gt;http://pablosoligo.blogspot.com/2011/06/dbexpress-trace.html&lt;/a&gt;&lt;br /&gt;
se explico como llevar a una tabla de log las operaciones que realiza DBExpress con la base de datos, entre esas operaciones&amp;nbsp;están&amp;nbsp;los begin transaction/commit/rollback entre otras muchas cosas. ¿Y si sacamos la diferencia de tiempo entre un begin transaction y su&amp;nbsp;correspondiente&amp;nbsp;commit/rollback? podriamos ver si hay irregularidades, incluso podemos ordenar la cosa y saber cuales son las que mas demoran.&lt;br /&gt;
Desgraciadamente quien les escribe no sabe ni investigo como pedirle al DBExpress o al sqlserver el numero de transaction si es que existiera, tampoco tenemos en la tabla un campo que una un begin transaction con su commit/rollback, por tanto tendremos que usar las neuronas un poco mas.&lt;br /&gt;
La siguiente consulta es la base sql que&amp;nbsp;podría&amp;nbsp;resolver el misterio,&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
select DateDiff(millisecond, s1.FechaHora, s2.FechaHora) as &#39;Demora&#39;, *&lt;br /&gt;
from SqlLog as s1 inner join SqlLog as s2&lt;br /&gt;
On s1.Module=s2.Module and s1.Login=s2.Login&lt;br /&gt;
Where (s1.Message like &#39;OLEDB - StartTransaction&#39;) and&lt;br /&gt;
&amp;nbsp; (s2.Message like &#39;OLEDB - Abort&#39; or s2.Message like &#39;OLEDB - Commit&#39;)and&lt;br /&gt;
&amp;nbsp; (s2.IdSqlLog&amp;gt;s1.IdSqlLog) and&lt;br /&gt;
&amp;nbsp; (s2.IdSqlLog&amp;lt;(&lt;br /&gt;
&amp;nbsp; &amp;nbsp;Select top 1 IdSqlLog&lt;br /&gt;
&amp;nbsp; &amp;nbsp;from SqlLog as i&lt;br /&gt;
&amp;nbsp; &amp;nbsp;Where i.Login=s1.Login and&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;i.Module=s1.Module and&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;i.IdSqlLog&amp;gt;s1.IdSqlLog and&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;i.Message like &#39;OLEDB - StartTransaction&#39;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;Order by i.IdSqlLog))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Traducido lo que hace es un join de la tabla de log con sigo misma juntando por Module y login, esto es porque es una&amp;nbsp;aplicación&amp;nbsp;multicapa, &lt;u&gt;&lt;b&gt;en una&amp;nbsp;aplicación&amp;nbsp;Cliente/Servidor una campo hostname en la tabla de log soluciona el problema del join.&lt;/b&gt;&lt;/u&gt;&lt;br /&gt;
Hecho el join busca un begin transaction y para ese busca o un commit o un rollback cuidando de que el idLog sea mayor y que no exista&amp;nbsp;ningún&amp;nbsp;otro begin transaction en el medio (Begin transaction del mismo Login/Module o hostname&amp;nbsp;según&amp;nbsp;corresponda).&lt;br /&gt;
Mañana&amp;nbsp;estaré&amp;nbsp;probando esto en un entorno de&amp;nbsp;producción, con datos reales&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: red; font-size: large;&quot;&gt;WARNING&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white;&quot;&gt;No hace falta pedir el plan de consulta para ver que esta consulta es explosiva&amp;nbsp;especialmente&amp;nbsp;en una tabla que crece sin&amp;nbsp;descanso&amp;nbsp;y que se puede volver gigante en un par de&amp;nbsp;&lt;/span&gt;días&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQuVyS1GqY98kHVh5-NxAILzNlKvox7iKUWlT67a9LQFFDlmQHIZ7GV7nYqV5vqBUNxRTNp3ecNM-JwXSzUxuW5isQm_DpPs9xFeCgTneXScVMgCAElMdk6ZaWlI6iwdbMeF7q5_Ih1Ufa/s1600/planConsulta.JPG&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;147&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQuVyS1GqY98kHVh5-NxAILzNlKvox7iKUWlT67a9LQFFDlmQHIZ7GV7nYqV5vqBUNxRTNp3ecNM-JwXSzUxuW5isQm_DpPs9xFeCgTneXScVMgCAElMdk6ZaWlI6iwdbMeF7q5_Ih1Ufa/s640/planConsulta.JPG&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: white; color: red; font-size: large;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Así&amp;nbsp;que mucho cuidado, ejecutarla sobre un set de datos pequeño o en un servidor de testing.</content><link rel='replies' type='application/atom+xml' href='http://pablosoligo.blogspot.com/feeds/3374546166735598830/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://pablosoligo.blogspot.com/2011/06/y-cuanto-duran-tus-transacciones.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/3374546166735598830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1079486184614702376/posts/default/3374546166735598830'/><link rel='alternate' type='text/html' href='http://pablosoligo.blogspot.com/2011/06/y-cuanto-duran-tus-transacciones.html' title='¿Y cuanto duran tus transacciones?'/><author><name>Pablo Soligo</name><uri>http://www.blogger.com/profile/01506697778667989450</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_XWbRr4oPsRokdorzqedw5WOWJNxqx69ItBk0KUhsKk81Rf-fUK3fB6t-YIPHA2RTVirh7wdde3YmR5hRtdTOU4HcY1h3FJ4c6rGv-vlY-SEAHvtFwOxOLJCzGgnCVAc/s220/4x4_2-crop.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQuVyS1GqY98kHVh5-NxAILzNlKvox7iKUWlT67a9LQFFDlmQHIZ7GV7nYqV5vqBUNxRTNp3ecNM-JwXSzUxuW5isQm_DpPs9xFeCgTneXScVMgCAElMdk6ZaWlI6iwdbMeF7q5_Ih1Ufa/s72-c/planConsulta.JPG" height="72" width="72"/><thr:total>0</thr:total></entry></feed>